stub_requests 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.reek.yml +1 -0
- data/CHANGELOG.md +2 -0
- data/README.md +2 -2
- data/lib/stub_requests/api.rb +8 -22
- data/lib/stub_requests/callback.rb +58 -0
- data/lib/stub_requests/callback_registry.rb +188 -0
- data/lib/stub_requests/core_ext/all.rb +1 -0
- data/lib/stub_requests/core_ext/array/extract_options.rb +4 -6
- data/lib/stub_requests/core_ext/class/attribute.rb +2 -3
- data/lib/stub_requests/core_ext/kernel/singleton_class.rb +2 -3
- data/lib/stub_requests/core_ext/module/redefine_method.rb +6 -0
- data/lib/stub_requests/core_ext/object/blank.rb +21 -22
- data/lib/stub_requests/core_ext/string/to_route_param.rb +35 -0
- data/lib/stub_requests/dsl/define_method.rb +49 -0
- data/lib/stub_requests/dsl/method_definition.rb +72 -0
- data/lib/stub_requests/dsl.rb +94 -0
- data/lib/stub_requests/endpoint.rb +48 -36
- data/lib/stub_requests/endpoint_stub.rb +89 -0
- data/lib/stub_requests/endpoints.rb +147 -0
- data/lib/stub_requests/observable.rb +0 -44
- data/lib/stub_requests/request_stub.rb +80 -0
- data/lib/stub_requests/service.rb +77 -0
- data/lib/stub_requests/service_registry.rb +174 -0
- data/lib/stub_requests/stub_registry.rb +159 -0
- data/lib/stub_requests/uri/builder.rb +27 -34
- data/lib/stub_requests/uri.rb +31 -4
- data/lib/stub_requests/version.rb +1 -1
- data/lib/stub_requests/webmock/stub_registry_extension.rb +1 -1
- data/lib/stub_requests.rb +12 -12
- data/lib/tasks/changelog.rake +2 -1
- metadata +14 -16
- data/gemfiles/webmock_2.3.gemfile.lock +0 -206
- data/gemfiles/webmock_3.5.gemfile.lock +0 -206
- data/gemfiles/webmock_develop.gemfile.lock +0 -211
- data/lib/stub_requests/metrics/endpoint.rb +0 -98
- data/lib/stub_requests/metrics/registry.rb +0 -132
- data/lib/stub_requests/metrics/request.rb +0 -89
- data/lib/stub_requests/metrics.rb +0 -33
- data/lib/stub_requests/observable/registry.rb +0 -152
- data/lib/stub_requests/observable/subscription.rb +0 -58
- data/lib/stub_requests/registration/endpoint.rb +0 -107
- data/lib/stub_requests/registration/endpoints.rb +0 -156
- data/lib/stub_requests/registration/registry.rb +0 -112
- data/lib/stub_requests/registration/service.rb +0 -85
- 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]
|
29
|
+
# @!attribute [rw] path
|
33
30
|
# @return [String] a string template for the endpoint
|
34
|
-
property :
|
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 [
|
39
|
-
|
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::
|
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]
|
47
|
-
#
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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]
|
66
|
-
#
|
67
|
-
# @
|
68
|
-
#
|
69
|
-
|
70
|
-
|
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
|
-
|
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}
|
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
|