stub_requests 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.reek.yml +1 -0
  3. data/CHANGELOG.md +2 -0
  4. data/README.md +2 -2
  5. data/lib/stub_requests/api.rb +8 -22
  6. data/lib/stub_requests/callback.rb +58 -0
  7. data/lib/stub_requests/callback_registry.rb +188 -0
  8. data/lib/stub_requests/core_ext/all.rb +1 -0
  9. data/lib/stub_requests/core_ext/array/extract_options.rb +4 -6
  10. data/lib/stub_requests/core_ext/class/attribute.rb +2 -3
  11. data/lib/stub_requests/core_ext/kernel/singleton_class.rb +2 -3
  12. data/lib/stub_requests/core_ext/module/redefine_method.rb +6 -0
  13. data/lib/stub_requests/core_ext/object/blank.rb +21 -22
  14. data/lib/stub_requests/core_ext/string/to_route_param.rb +35 -0
  15. data/lib/stub_requests/dsl/define_method.rb +49 -0
  16. data/lib/stub_requests/dsl/method_definition.rb +72 -0
  17. data/lib/stub_requests/dsl.rb +94 -0
  18. data/lib/stub_requests/endpoint.rb +48 -36
  19. data/lib/stub_requests/endpoint_stub.rb +89 -0
  20. data/lib/stub_requests/endpoints.rb +147 -0
  21. data/lib/stub_requests/observable.rb +0 -44
  22. data/lib/stub_requests/request_stub.rb +80 -0
  23. data/lib/stub_requests/service.rb +77 -0
  24. data/lib/stub_requests/service_registry.rb +174 -0
  25. data/lib/stub_requests/stub_registry.rb +159 -0
  26. data/lib/stub_requests/uri/builder.rb +27 -34
  27. data/lib/stub_requests/uri.rb +31 -4
  28. data/lib/stub_requests/version.rb +1 -1
  29. data/lib/stub_requests/webmock/stub_registry_extension.rb +1 -1
  30. data/lib/stub_requests.rb +12 -12
  31. data/lib/tasks/changelog.rake +2 -1
  32. metadata +14 -16
  33. data/gemfiles/webmock_2.3.gemfile.lock +0 -206
  34. data/gemfiles/webmock_3.5.gemfile.lock +0 -206
  35. data/gemfiles/webmock_develop.gemfile.lock +0 -211
  36. data/lib/stub_requests/metrics/endpoint.rb +0 -98
  37. data/lib/stub_requests/metrics/registry.rb +0 -132
  38. data/lib/stub_requests/metrics/request.rb +0 -89
  39. data/lib/stub_requests/metrics.rb +0 -33
  40. data/lib/stub_requests/observable/registry.rb +0 -152
  41. data/lib/stub_requests/observable/subscription.rb +0 -58
  42. data/lib/stub_requests/registration/endpoint.rb +0 -107
  43. data/lib/stub_requests/registration/endpoints.rb +0 -156
  44. data/lib/stub_requests/registration/registry.rb +0 -112
  45. data/lib/stub_requests/registration/service.rb +0 -85
  46. data/lib/stub_requests/registration.rb +0 -87
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StubRequests
4
+ class DSL
5
+ #
6
+ # Class DefineMethod generates method definition for a stubbed endpoint
7
+ #
8
+ # @author Mikael Henriksson <mikael@zoolutions.se>
9
+ # @since 0.1.4
10
+ #
11
+ class MethodDefinition
12
+ #
13
+ # @return [String]
14
+ BLOCK_ARG = "&block"
15
+
16
+ #
17
+ # @!attribute [r] service_id
18
+ # @return [Symbol] the id of a registered service
19
+ attr_reader :service_id
20
+ #
21
+ # @!attribute [r] endpoint_id
22
+ # @return [Symbol] the id of a registered endpoint
23
+ attr_reader :endpoint_id
24
+ #
25
+ # @!attribute [r] route_params
26
+ # @return [Array<Symbol>] the URI parameters for the endpoint
27
+ attr_reader :route_params
28
+
29
+ #
30
+ # Initialize a new endpoint of {MethodDefinition}
31
+ #
32
+ # @param [Symbol] service_id the id of a registered service
33
+ # @param [Symbol] endpoint_id the id of a registered endpoint
34
+ # @param [Array<Symbol>] route_params the route parameter keys
35
+ #
36
+ def initialize(service_id, endpoint_id, route_params)
37
+ @service_id = service_id
38
+ @endpoint_id = endpoint_id
39
+ @route_params = route_params
40
+ end
41
+
42
+ #
43
+ # The name of this method
44
+ #
45
+ #
46
+ # @return [String] a string prefixed with stub_, `"stub_documents_show"`
47
+ #
48
+ def name
49
+ @name ||= "stub_#{endpoint_id}"
50
+ end
51
+
52
+ def to_s
53
+ <<~METHOD
54
+ def #{name}(#{keywords})
55
+ stub_endpoint(:#{service_id}, :#{endpoint_id}, #{arguments})
56
+ end
57
+ METHOD
58
+ end
59
+ alias to_str to_s
60
+
61
+ private
62
+
63
+ def keywords
64
+ @keywords ||= route_params.map { |param| "#{param}:" }.concat([+BLOCK_ARG]).join(", ")
65
+ end
66
+
67
+ def arguments
68
+ @arguments ||= route_params.map { |param| "#{param}: #{param}" }.concat([+BLOCK_ARG]).join(", ")
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StubRequests
4
+ #
5
+ # Module DSL takes the id of a registered service
6
+ #
7
+ # @author Mikael Henriksson <mikael@zoolutions.se>
8
+ # @since 0.1.4
9
+ #
10
+ # @example **Register service with endpoints**
11
+ # StubRequests.register_service(:documents, "https://company.com/api/v1") do
12
+ # register_endpoints do
13
+ # register(:show, :get, "documents/:id")
14
+ # register(:index, :get, "documents")
15
+ # register(:create, :post, "documents")
16
+ # end
17
+ # end
18
+ # @example **Create a receiver module for the stub methods**
19
+ # module Stubs; end
20
+ #
21
+ # Stubs.instance_methods #=> []
22
+ # @example **Define the endpoint methods using the DSL**
23
+ # StubRequests::DSL.define_endpoint_methods(
24
+ # :documents, receiver: Stubs
25
+ # )
26
+ #
27
+ # # This turns the module Stubs into the following:
28
+ #
29
+ # Stubs.instance_methods #=> [:stub_documents_show, :stub_documents_index, :stub_documents_create]
30
+ # module Stubs
31
+ # def stub_documents_show(id:, &block)
32
+ # stub_endpoint(:documents, :show, id: id, &block)
33
+ # end
34
+ #
35
+ # def stub_documents_index(&block)
36
+ # stub_endpoint(:documents, :index, &block)
37
+ # end
38
+ #
39
+ # def stub_documents_create(&block)
40
+ # stub_endpoint(:documents, :create, &block)
41
+ # end
42
+ # end
43
+ #
44
+ # @example **Use the helper methods in your tests**
45
+ # include Stubs
46
+ #
47
+ # let(:document_id) { 1234 }
48
+ # let(:request_body) { { key: "value" }.to_json }
49
+ # let(:response_body) { { id: document_id, key: "value" }.to_json }
50
+ #
51
+ # before do
52
+ # stub_documents_create do
53
+ # with(body: request_body)
54
+ # to_return(body: response_body)
55
+ # end
56
+ #
57
+ # stub_documents_show(id: document_id) do
58
+ # with(body: request_body)
59
+ # to_return(body: response_body)
60
+ # end
61
+ # end
62
+ #
63
+ # it "stubs the requests nicely" do
64
+ # create_uri = URI("https://company.com/api/v1/documents")
65
+ # response = Net::HTTP.post(create_uri)
66
+ # expect(response).to be_json_eql(response_body.to_json)
67
+ #
68
+ # show_uri = URI("https://company.com/api/v1/documents/#{document_id}")
69
+ # response = Net::HTTP.post(create_uri)
70
+ # expect(response).to be_json_eql(response_body.to_json)
71
+ # end
72
+ class DSL
73
+ def self.define_endpoint_methods(service_id, receiver:)
74
+ new(service_id, receiver: receiver).define_endpoint_methods
75
+ end
76
+
77
+ attr_reader :service, :receiver, :endpoints
78
+
79
+ def initialize(service_id, receiver:)
80
+ @service = StubRequests::ServiceRegistry.instance.find(service_id)
81
+ @receiver = receiver
82
+ @endpoints = service.endpoints.endpoints.values
83
+ end
84
+
85
+ def define_endpoint_methods
86
+ receiver.send(:include, StubRequests::API)
87
+
88
+ endpoints.each do |endpoint|
89
+ definition = MethodDefinition.new(service.id, endpoint.id, endpoint.route_params)
90
+ DefineMethod.new(definition, receiver).define
91
+ end
92
+ end
93
+ end
94
+ end
@@ -17,9 +17,6 @@ module StubRequests
17
17
 
18
18
  include Comparable
19
19
  include Property
20
-
21
- # Delegate id, uri and endpoints to service
22
- delegate [:id, :uri, :endpoints] => :service
23
20
  #
24
21
  # @!attribute [rw] id
25
22
  # @return [Symbol] the id of the endpoint
@@ -29,57 +26,72 @@ module StubRequests
29
26
  # @return [Symbol] a HTTP verb
30
27
  property :verb, type: Symbol
31
28
  #
32
- # @!attribute [rw] uri_template
29
+ # @!attribute [rw] path
33
30
  # @return [String] a string template for the endpoint
34
- property :uri_template, type: String
31
+ property :path, type: String
32
+
33
+ #
34
+ # @!attribute [rw] service
35
+ # @see
36
+ # @return [Service] a service
37
+ attr_reader :service
38
+
39
+ #
40
+ # @!attribute [rw] service_id
41
+ # @see
42
+ # @return [Symbol] the id of the service
43
+ attr_reader :service_id
44
+
45
+ #
46
+ # @!attribute [rw] service_uri
47
+ # @see
48
+ # @return [String] a service's base URI
49
+ attr_reader :service_uri
50
+
35
51
  #
36
52
  # @!attribute [rw] options
37
53
  # @see
38
- # @return [Hash<Symbol>] a Hash with default request/response options
39
- property :options, type: Hash, default: {}
54
+ # @return [Array<Symbol>] an array with required route params
55
+ attr_reader :route_params
40
56
 
41
57
  #
42
- # An endpoint for a specific {StubRequests::Registration::Service}
58
+ # An endpoint for a specific {StubRequests::Service}
43
59
  #
60
+ #
61
+ # @param [Service] service a registered service
44
62
  # @param [Symbol] endpoint_id a descriptive id for the endpoint
45
63
  # @param [Symbol] verb a HTTP verb
46
- # @param [String] uri_template how to reach the endpoint
47
- # @param [optional, Hash<Symbol>] options
48
- # @option options [optional, Hash<Symbol>] :request for request_stub.with
49
- # @option options [optional, Hash<Symbol>] :response for request_stub.to_return
50
- # @option options [optional, Array, Exception, StandardError, String] :error for request_stub.to_raise
51
- # @option options [optional, TrueClass] :timeout for request_stub.to_timeout
52
- #
53
- def initialize(service, endpoint_id, verb, uri_template, options = {})
54
- self.service = service
55
- self.id = endpoint_id
56
- self.verb = verb
57
- self.uri_template = uri_template
58
- self.options = options
64
+ # @param [String] path how to reach the endpoint
65
+ #
66
+ def initialize(service, endpoint_id, verb, path)
67
+ self.id = endpoint_id
68
+ self.verb = verb
69
+ self.path = path
70
+
71
+ @service = service
72
+ @service_id = service.id
73
+ @service_uri = service.uri
74
+ @route_params = URI.route_params(path)
59
75
  end
60
76
 
61
77
  #
62
78
  # Updates this endpoint
63
79
  #
80
+ #
64
81
  # @param [Symbol] verb a HTTP verb
65
- # @param [String] uri_template how to reach the endpoint
66
- # @param [optional, Hash<Symbol>] options
67
- # @option options [optional, Hash<Symbol>] :request for request_stub.with
68
- # @option options [optional, Hash<Symbol>] :response for request_stub.to_return
69
- # @option options [optional, Array, Exception, StandardError, String] :error for request_stub.to_raise
70
- # @option options [optional, TrueClass] :timeout for request_stub.to_timeout
71
- #
72
- # @return [Registration::Endpoint] returns the updated endpoint
73
- #
74
- def update(verb, uri_template, options)
75
- self.verb = verb
76
- self.uri_template = uri_template
77
- self.options = options
82
+ # @param [String] path how to reach the endpoint
83
+ #
84
+ # @return [Endpoint] returns the updated endpoint
85
+ #
86
+ def update(verb, path)
87
+ self.verb = verb
88
+ self.path = path
78
89
  self
79
90
  end
80
91
 
81
92
  def <=>(other)
82
- id <=> other.id
93
+ service_id <=> other.service_id &&
94
+ id <=> other.id
83
95
  end
84
96
 
85
97
  def hash
@@ -94,7 +106,7 @@ module StubRequests
94
106
  # @return [String]
95
107
  #
96
108
  def to_s
97
- "#<#{self.class} id=:#{id} verb=:#{verb} uri_template='#{uri_template}'>"
109
+ "#<#{self.class} id=:#{id} verb=:#{verb} path='#{path}'>"
98
110
  end
99
111
  end
100
112
  end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Abstraction over WebMock to reduce duplication
5
+ #
6
+ # @author Mikael Henriksson <mikael@zoolutions.se>
7
+ # @since 0.1.0
8
+ #
9
+ module StubRequests
10
+ #
11
+ # Class Endpoint provides metrics for stubbed endpoints
12
+ #
13
+ # @author Mikael Henriksson <mikael@zoolutions.se>
14
+ # @since 0.1.2
15
+ #
16
+ class EndpointStub
17
+ # includes "Enumerable"
18
+ # @!parse include Enumerable
19
+ include Enumerable
20
+ # @api private
21
+ include Property
22
+ # @api private
23
+
24
+ #
25
+ # @!attribute [r] service_id
26
+ # @return [Symbol] the id of a {StubRequests::Service}
27
+ property :service_id, type: Symbol
28
+ #
29
+ # @!attribute [r] endpoint_id
30
+ # @return [Symbol] the id of an endpoint
31
+ property :endpoint_id, type: Symbol
32
+ #
33
+ # @!attribute [r] verb
34
+ # @return [String] the HTTP verb/method for this endpoint
35
+ property :verb, type: Symbol
36
+ #
37
+ # @!attribute [r] path
38
+ # @return [String] the full URI template for the endpoint
39
+ property :path, type: String
40
+ #
41
+ # @!attribute [r] stubs
42
+ # @return [Array] an array with recorded stubs
43
+ attr_reader :stubs
44
+
45
+ #
46
+ # Initializes a new Endpoint
47
+ #
48
+ # @param [Service] service a service
49
+ # @param [Endpoint] endpoint an endpoint
50
+ #
51
+ def initialize(service, endpoint)
52
+ self.service_id = service.id
53
+ self.endpoint_id = endpoint.id
54
+ self.verb = endpoint.verb
55
+ self.path = [service.uri, endpoint.path].join("/")
56
+
57
+ @stubs = Concurrent::Array.new
58
+ end
59
+
60
+ def find_by(attribute:, value:)
61
+ find { |request| request.send(attribute) == value }
62
+ end
63
+
64
+ #
65
+ # Required by Enumerable
66
+ #
67
+ #
68
+ # @return [Concurrent::Map<Symbol, Service>] an map with services
69
+ #
70
+ # @yield used by Enumerable
71
+ #
72
+ def each(&block)
73
+ stubs.each(&block)
74
+ end
75
+
76
+ #
77
+ # Records a WebMock::RequestStub as stubbed
78
+ #
79
+ # @param [WebMock::RequestStub] webmock_stub <description>
80
+ #
81
+ # @return [RequestStub]
82
+ #
83
+ def record(webmock_stub)
84
+ request_stub = RequestStub.new(self, webmock_stub)
85
+ stubs.push(request_stub)
86
+ request_stub
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Abstraction over WebMock to reduce duplication
5
+ #
6
+ # @author Mikael Henriksson <mikael@zoolutions.se>
7
+ # @since 0.1.0
8
+ #
9
+ module StubRequests
10
+ #
11
+ # Class Endpoints manages a collection of endpoints
12
+ #
13
+ # @author Mikael Henriksson <mikael@zoolutions.se>
14
+ #
15
+ class Endpoints
16
+ include Enumerable
17
+
18
+ #
19
+ # @!attribute [rw] service
20
+ # @return [Service] the service the collection belongs to
21
+ attr_reader :service
22
+ #
23
+ # @!attribute [rw] endpoints
24
+ # @return [Concurrent::Map<Symbol, Endpoint>] a map with endpoints
25
+ attr_reader :endpoints
26
+
27
+ def initialize(service)
28
+ @service = service
29
+ @endpoints = Concurrent::Map.new
30
+ end
31
+
32
+ #
33
+ # Required by Enumerable
34
+ #
35
+ # @return [Concurrent::Map<Symbol, Service>] a map with endpoints
36
+ #
37
+ # @yield used by Enumerable
38
+ #
39
+ def each(&block)
40
+ endpoints.each(&block)
41
+ end
42
+
43
+ #
44
+ # Registers an endpoint in the collection
45
+ #
46
+ # @param [Symbol] endpoint_id the id of this Endpoint
47
+ # @param [Symbol] verb a HTTP verb
48
+ # @param [String] path the URI to reach the endpoint
49
+ #
50
+ # @return [Endpoint]
51
+ #
52
+ # :reek:LongParameterList { max_params: 4 }
53
+ def register(endpoint_id, verb, path)
54
+ endpoint =
55
+ if (endpoint = find(endpoint_id))
56
+ StubRequests.logger.warn("Endpoint already registered: #{endpoint}")
57
+ endpoint.update(verb, path)
58
+ else
59
+ Endpoint.new(service, endpoint_id, verb, path)
60
+ end
61
+
62
+ endpoints[endpoint.id] = endpoint
63
+ endpoint
64
+ end
65
+
66
+ #
67
+ # Updates an endpoint
68
+ #
69
+ # @param [Symbol] endpoint_id the id of the endpoint
70
+ # @param [Symbol] verb a HTTP verb
71
+ # @param [String] path the path to the endpoint
72
+ #
73
+ # @raise [EndpointNotFound] when the endpoint couldn't be found
74
+ #
75
+ # @return [Endpoint] returns the updated endpoint
76
+ #
77
+ # :reek:LongParameterList { max_params: 4 }
78
+ def update(endpoint_id, verb, path)
79
+ endpoint = find!(endpoint_id)
80
+ endpoint.update(verb, path)
81
+ end
82
+
83
+ #
84
+ # Removes an endpoint from the collection
85
+ #
86
+ # @param [Symbol] endpoint_id the id of the endpoint, `:file_service`
87
+ #
88
+ # @return [Endpoint] the endpoint that was removed
89
+ #
90
+ def remove(endpoint_id)
91
+ endpoints.delete(endpoint_id)
92
+ end
93
+
94
+ #
95
+ # Fetches an endpoint from the collection
96
+ #
97
+ # @param [<type>] endpoint_id <description>
98
+ #
99
+ # @return [Endpoint]
100
+ #
101
+ def find(endpoint_id)
102
+ endpoints[endpoint_id]
103
+ end
104
+
105
+ #
106
+ # Fetches an endpoint from the collection or raises an error
107
+ #
108
+ # @param [Symbol] endpoint_id the id of the endpoint
109
+ #
110
+ # @raise [EndpointNotFound] when an endpoint couldn't be found
111
+ #
112
+ # @return [Endpoint, nil]
113
+ #
114
+ def find!(endpoint_id)
115
+ find(endpoint_id) || raise(EndpointNotFound, "Couldn't find an endpoint with id=:#{endpoint_id}")
116
+ end
117
+
118
+ #
119
+ # Returns a descriptive string with all endpoints in the collection
120
+ #
121
+ # @return [String]
122
+ #
123
+ def to_s
124
+ [
125
+ +"#<#{self.class} endpoints=",
126
+ +endpoints_string,
127
+ +">",
128
+ ].join("")
129
+ end
130
+
131
+ #
132
+ # Returns a nicely formatted string with an array of endpoints
133
+ #
134
+ #
135
+ # @return [<type>] <description>
136
+ #
137
+ def endpoints_string
138
+ "[#{endpoints_as_string}]"
139
+ end
140
+
141
+ private
142
+
143
+ def endpoints_as_string
144
+ endpoints.values.map(&:to_s).join(",") if endpoints.size.positive?
145
+ end
146
+ end
147
+ end
@@ -14,49 +14,5 @@ module StubRequests
14
14
  # @since 0.1.3
15
15
  #
16
16
  module Observable
17
- #
18
- # Subscribe to a service endpoint call
19
- # @see Observable::Registry#subscribe
20
- #
21
- #
22
- # @param [Symbol] service_id the id of a service
23
- # @param [Symbol] endpoint_id the id of an endpoint
24
- # @param [Symbol] verb the HTTP verb to subscribe to
25
- # @param [Proc] callback the callback to use for when.a request was made
26
- #
27
- # @return [Subscription]
28
- #
29
- # :reek:LongParameterList
30
- def self.subscribe_to(service_id, endpoint_id, verb, callback)
31
- Registry.instance.subscribe(service_id, endpoint_id, verb, callback)
32
- end
33
-
34
- #
35
- # Unsubscribe from a service endpoint call
36
- # @see Observable::Registry#unsubscribe
37
- #
38
- #
39
- # @param [Symbol] service_id the id of a service
40
- # @param [Symbol] endpoint_id the id of an endpoint
41
- # @param [Symbol] verb the HTTP verb to subscribe to
42
- #
43
- # @return [Subscription]
44
- #
45
- def self.unsubscribe_from(service_id, endpoint_id, verb)
46
- Registry.instance.unsubscribe(service_id, endpoint_id, verb)
47
- end
48
-
49
- #
50
- # Notifies subscribers that a request was made
51
- # @see Observable::Registry#notify_subscribers
52
- #
53
- #
54
- # @param [Metrics::Request] request the stubbed request
55
- #
56
- # @return [Request]
57
- #
58
- def self.notify_subscribers(request)
59
- Registry.instance.notify_subscribers(request)
60
- end
61
17
  end
62
18
  end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Abstraction over WebMock to reduce duplication
5
+ #
6
+ # @author Mikael Henriksson <mikael@zoolutions.se>
7
+ # @since 0.1.0
8
+ #
9
+ module StubRequests
10
+ #
11
+ # Class Stub tracks the WebMock::RequestStub life cycle
12
+ #
13
+ # @author Mikael Henriksson <mikael@zoolutions.se>
14
+ # @since 0.1.2
15
+ #
16
+ # :reek:TooManyInstanceVariables
17
+ class RequestStub
18
+ include Property
19
+ extend Forwardable
20
+
21
+ # Delegate service_id, endpoint_id, verb and path to endpoint
22
+ delegate [:service_id, :endpoint_id, :verb, :path] => :endpoint
23
+ #
24
+ # @!attribute [r] endpoint
25
+ # @return [StubRequests::EndpointStub] a stubbed endpoint
26
+ property :endpoint, type: StubRequests::EndpointStub
27
+ #
28
+ # @!attribute [r] verb
29
+ # @return [Symbol] a HTTP verb/method
30
+ property :verb, type: Symbol
31
+ #
32
+ # @!attribute [r] uri
33
+ # @return [String] the full URI for this endpoint
34
+ property :uri, type: String
35
+ #
36
+ # @!attribute [r] request_stub
37
+ # @return [WebMock::RequestStub] a webmock stubbed request
38
+ property :request_stub, type: WebMock::RequestStub
39
+ #
40
+ # @!attribute [r] recorded_at
41
+ # @return [Time] the time this record was recorded
42
+ property :recorded_at, type: Time
43
+ #
44
+ # @!attribute [r] recorded_from
45
+ # @return [String] the relative path to the spec that recorded it
46
+ property :recorded_from, type: String
47
+ #
48
+ # @!attribute [r] responded_at
49
+ # @return [Time] the time this stubs response was used
50
+ property :responded_at, type: Time
51
+
52
+ #
53
+ # Initialize a new Record
54
+ #
55
+ #
56
+ # @param [Endpoint] endpoint a stubbed endpoint
57
+ # @param [WebMock::RequestStub] request_stub the stubbed webmock request
58
+ #
59
+ def initialize(endpoint, request_stub)
60
+ request_pattern = request_stub.request_pattern
61
+ self.endpoint = endpoint
62
+ self.verb = request_pattern.method_pattern.to_s.to_sym
63
+ self.uri = request_pattern.uri_pattern.to_s
64
+ self.request_stub = request_stub
65
+ self.recorded_at = Time.now
66
+ self.recorded_from = RSpec.current_example.metadata[:location]
67
+ @responded_at = nil # ByPass the validation for the initializer
68
+ end
69
+
70
+ #
71
+ # Marks this record as having responded
72
+ #
73
+ #
74
+ # @return [Time] the time it was marked responded
75
+ #
76
+ def mark_as_responded
77
+ self.responded_at = Time.now
78
+ end
79
+ end
80
+ end