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
@@ -1,156 +0,0 @@
|
|
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
|
-
# Module Registration provides registration of stubbed endpoints and services
|
12
|
-
#
|
13
|
-
# @author Mikael Henriksson <mikael@zoolutions.se>
|
14
|
-
# @since 0.1.3
|
15
|
-
#
|
16
|
-
module Registration
|
17
|
-
#
|
18
|
-
# Class Endpoints manages a collection of endpoints
|
19
|
-
#
|
20
|
-
# @author Mikael Henriksson <mikael@zoolutions.se>
|
21
|
-
#
|
22
|
-
class Endpoints
|
23
|
-
include Enumerable
|
24
|
-
|
25
|
-
#
|
26
|
-
# @!attribute [rw] endpoints
|
27
|
-
# @return [Concurrent::Map<Symbol, Endpoint>] a map with endpoints
|
28
|
-
attr_reader :endpoints
|
29
|
-
|
30
|
-
def initialize
|
31
|
-
@endpoints = Concurrent::Map.new
|
32
|
-
end
|
33
|
-
|
34
|
-
#
|
35
|
-
# Required by Enumerable
|
36
|
-
#
|
37
|
-
# @return [Concurrent::Map<Symbol, Service>] a map with endpoints
|
38
|
-
#
|
39
|
-
# @yield used by Enumerable
|
40
|
-
#
|
41
|
-
def each(&block)
|
42
|
-
endpoints.each(&block)
|
43
|
-
end
|
44
|
-
|
45
|
-
#
|
46
|
-
# Registers an endpoint in the collection
|
47
|
-
#
|
48
|
-
# @param [Symbol] endpoint_id the id of this Endpoint
|
49
|
-
# @param [Symbol] verb a HTTP verb
|
50
|
-
# @param [String] uri_template the URI to reach the endpoint
|
51
|
-
# @param [optional, Hash<Symbol>] options default options
|
52
|
-
#
|
53
|
-
# @return [Endpoint]
|
54
|
-
#
|
55
|
-
# :reek:LongParameterList { max_params: 4 }
|
56
|
-
def register(endpoint_id, verb, uri_template, options = {})
|
57
|
-
endpoint =
|
58
|
-
if (endpoint = find(endpoint_id))
|
59
|
-
StubRequests.logger.warn("Endpoint already registered: #{endpoint}")
|
60
|
-
endpoint.update(verb, uri_template, options)
|
61
|
-
else
|
62
|
-
Endpoint.new(endpoint_id, verb, uri_template, options)
|
63
|
-
end
|
64
|
-
|
65
|
-
endpoints[endpoint.id] = endpoint
|
66
|
-
endpoint
|
67
|
-
end
|
68
|
-
|
69
|
-
#
|
70
|
-
# Updates an endpoint
|
71
|
-
#
|
72
|
-
# @param [Symbol] endpoint_id the id of the endpoint
|
73
|
-
# @param [Symbol] verb a HTTP verb
|
74
|
-
# @param [String] uri_template how to reach the endpoint
|
75
|
-
# @param [optional, Hash<Symbol>] options
|
76
|
-
# @option options [optional, Hash<Symbol>] :request request options
|
77
|
-
# @option options [optional, Hash<Symbol>] :response options
|
78
|
-
# @option options [optional, Array, Exception, StandardError, String] :error to raise
|
79
|
-
# @option options [optional, TrueClass] :timeout raise a timeout error?
|
80
|
-
#
|
81
|
-
# @raise [EndpointNotFound] when the endpoint couldn't be found
|
82
|
-
#
|
83
|
-
# @return [Endpoint] returns the updated endpoint
|
84
|
-
#
|
85
|
-
# :reek:LongParameterList { max_params: 4 }
|
86
|
-
def update(endpoint_id, verb, uri_template, options)
|
87
|
-
endpoint = find!(endpoint_id)
|
88
|
-
endpoint.update(verb, uri_template, options)
|
89
|
-
end
|
90
|
-
|
91
|
-
#
|
92
|
-
# Removes an endpoint from the collection
|
93
|
-
#
|
94
|
-
# @param [Symbol] endpoint_id the id of the endpoint, `:file_service`
|
95
|
-
#
|
96
|
-
# @return [Endpoint] the endpoint that was removed
|
97
|
-
#
|
98
|
-
def remove(endpoint_id)
|
99
|
-
endpoints.delete(endpoint_id)
|
100
|
-
end
|
101
|
-
|
102
|
-
#
|
103
|
-
# Fetches an endpoint from the collection
|
104
|
-
#
|
105
|
-
# @param [<type>] endpoint_id <description>
|
106
|
-
#
|
107
|
-
# @return [Endpoint]
|
108
|
-
#
|
109
|
-
def find(endpoint_id)
|
110
|
-
endpoints[endpoint_id]
|
111
|
-
end
|
112
|
-
|
113
|
-
#
|
114
|
-
# Fetches an endpoint from the collection or raises an error
|
115
|
-
#
|
116
|
-
# @param [Symbol] endpoint_id the id of the endpoint
|
117
|
-
#
|
118
|
-
# @raise [EndpointNotFound] when an endpoint couldn't be found
|
119
|
-
#
|
120
|
-
# @return [Endpoint, nil]
|
121
|
-
#
|
122
|
-
def find!(endpoint_id)
|
123
|
-
find(endpoint_id) || raise(EndpointNotFound, "Couldn't find an endpoint with id=:#{endpoint_id}")
|
124
|
-
end
|
125
|
-
|
126
|
-
#
|
127
|
-
# Returns a descriptive string with all endpoints in the collection
|
128
|
-
#
|
129
|
-
# @return [String]
|
130
|
-
#
|
131
|
-
def to_s
|
132
|
-
[
|
133
|
-
+"#<#{self.class} endpoints=",
|
134
|
-
+endpoints_string,
|
135
|
-
+">",
|
136
|
-
].join("")
|
137
|
-
end
|
138
|
-
|
139
|
-
#
|
140
|
-
# Returns a nicely formatted string with an array of endpoints
|
141
|
-
#
|
142
|
-
#
|
143
|
-
# @return [<type>] <description>
|
144
|
-
#
|
145
|
-
def endpoints_string
|
146
|
-
"[#{endpoints_as_string}]"
|
147
|
-
end
|
148
|
-
|
149
|
-
private
|
150
|
-
|
151
|
-
def endpoints_as_string
|
152
|
-
endpoints.values.map(&:to_s).join(",") if endpoints.size.positive?
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
@@ -1,112 +0,0 @@
|
|
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
|
-
# Module Registration provides registration of stubbed endpoints and services
|
12
|
-
#
|
13
|
-
# @author Mikael Henriksson <mikael@zoolutions.se>
|
14
|
-
# @since 0.1.3
|
15
|
-
#
|
16
|
-
module Registration
|
17
|
-
#
|
18
|
-
# Class Registry provides registration of services
|
19
|
-
#
|
20
|
-
# @author Mikael Henriksson <mikael@zoolutions.se>
|
21
|
-
#
|
22
|
-
class Registry
|
23
|
-
include Singleton
|
24
|
-
include Enumerable
|
25
|
-
|
26
|
-
#
|
27
|
-
# @!attribute [rw] services
|
28
|
-
# @return [Concurrent::Map<Symbol, Service>] a map with services
|
29
|
-
attr_reader :services
|
30
|
-
|
31
|
-
def initialize
|
32
|
-
@services = Concurrent::Map.new
|
33
|
-
end
|
34
|
-
|
35
|
-
#
|
36
|
-
# Resets the map with registered services
|
37
|
-
#
|
38
|
-
#
|
39
|
-
# @api private
|
40
|
-
def reset
|
41
|
-
services.clear
|
42
|
-
end
|
43
|
-
|
44
|
-
#
|
45
|
-
# Required by Enumerable
|
46
|
-
#
|
47
|
-
#
|
48
|
-
# @return [Concurrent::Map<Symbol, Service>] an map with services
|
49
|
-
#
|
50
|
-
# @yield used by Enumerable
|
51
|
-
#
|
52
|
-
def each(&block)
|
53
|
-
services.each(&block)
|
54
|
-
end
|
55
|
-
|
56
|
-
#
|
57
|
-
# Registers a service in the registry
|
58
|
-
#
|
59
|
-
#
|
60
|
-
# @param [Symbol] service_id a symbolic id of the service
|
61
|
-
# @param [String] service_uri a string with a base_uri to the service
|
62
|
-
#
|
63
|
-
# @return [Registration::Service] the service that was just registered
|
64
|
-
#
|
65
|
-
def register(service_id, service_uri)
|
66
|
-
if (service = find(service_id))
|
67
|
-
StubRequests.logger.warn("Service already registered #{service}")
|
68
|
-
raise ServiceHaveEndpoints, service if service.endpoints?
|
69
|
-
end
|
70
|
-
services[service_id] = Service.new(service_id, service_uri)
|
71
|
-
end
|
72
|
-
|
73
|
-
#
|
74
|
-
# Removes a service from the registry
|
75
|
-
#
|
76
|
-
#
|
77
|
-
# @param [Symbol] service_id the service_id to remove
|
78
|
-
#
|
79
|
-
# @raise [ServiceNotFound] when the service was not removed
|
80
|
-
#
|
81
|
-
def remove(service_id)
|
82
|
-
services.delete(service_id) || raise(ServiceNotFound, service_id)
|
83
|
-
end
|
84
|
-
|
85
|
-
#
|
86
|
-
# Fetches a service from the registry
|
87
|
-
#
|
88
|
-
#
|
89
|
-
# @param [Symbol] service_id id of the service to remove
|
90
|
-
#
|
91
|
-
# @return [Registration::Service] the found service
|
92
|
-
#
|
93
|
-
def find(service_id)
|
94
|
-
services[service_id]
|
95
|
-
end
|
96
|
-
|
97
|
-
#
|
98
|
-
# Fetches a service from the registry or raises {ServiceNotFound}
|
99
|
-
#
|
100
|
-
#
|
101
|
-
# @param [Symbol] service_id the id of a service
|
102
|
-
#
|
103
|
-
# @raise [ServiceNotFound] when an endpoint couldn't be found
|
104
|
-
#
|
105
|
-
# @return [Registration::Service]
|
106
|
-
#
|
107
|
-
def find!(service_id)
|
108
|
-
find(service_id) || raise(ServiceNotFound, service_id)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
@@ -1,85 +0,0 @@
|
|
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
|
-
# Module Registration provides registration of stubbed endpoints and services
|
12
|
-
#
|
13
|
-
# @author Mikael Henriksson <mikael@zoolutions.se>
|
14
|
-
# @since 0.1.3
|
15
|
-
#
|
16
|
-
module Registration
|
17
|
-
#
|
18
|
-
# Class Service provides details for a registered service
|
19
|
-
#
|
20
|
-
# @author Mikael Henriksson <mikael@zoolutions.se>
|
21
|
-
#
|
22
|
-
class Service
|
23
|
-
include Comparable
|
24
|
-
include Property
|
25
|
-
|
26
|
-
# @!attribute [rw] id
|
27
|
-
# @return [Symbol] the id of the service
|
28
|
-
property :id, type: Symbol
|
29
|
-
|
30
|
-
# @!attribute [rw] uri
|
31
|
-
# @return [String] the base uri to the service
|
32
|
-
property :uri, type: String
|
33
|
-
|
34
|
-
# @!attribute [rw] endpoints
|
35
|
-
# @return [Endpoints] a list with defined endpoints
|
36
|
-
attr_reader :endpoints
|
37
|
-
|
38
|
-
#
|
39
|
-
# Initializes a new instance of a Service
|
40
|
-
#
|
41
|
-
# @param [Symbol] service_id the id of this service
|
42
|
-
# @param [String] service_uri the base uri to reach the service
|
43
|
-
#
|
44
|
-
def initialize(service_id, service_uri)
|
45
|
-
self.id = service_id
|
46
|
-
self.uri = service_uri
|
47
|
-
@endpoints = Endpoints.new
|
48
|
-
end
|
49
|
-
|
50
|
-
#
|
51
|
-
# Check if the endpoint registry has endpoints
|
52
|
-
#
|
53
|
-
# @return [true,false]
|
54
|
-
#
|
55
|
-
def endpoints?
|
56
|
-
endpoints.any?
|
57
|
-
end
|
58
|
-
|
59
|
-
#
|
60
|
-
# Returns a nicely formatted string with this service
|
61
|
-
#
|
62
|
-
# @return [String]
|
63
|
-
#
|
64
|
-
def to_s
|
65
|
-
[
|
66
|
-
+"#<#{self.class}",
|
67
|
-
+" id=#{id}",
|
68
|
-
+" uri=#{uri}",
|
69
|
-
+" endpoints=#{endpoints.endpoints_string}",
|
70
|
-
+">",
|
71
|
-
].join("")
|
72
|
-
end
|
73
|
-
|
74
|
-
def <=>(other)
|
75
|
-
id <=> other.id
|
76
|
-
end
|
77
|
-
|
78
|
-
def hash
|
79
|
-
[id, self.class].hash
|
80
|
-
end
|
81
|
-
|
82
|
-
alias eql? ==
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
@@ -1,87 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module StubRequests
|
4
|
-
#
|
5
|
-
# Module Registration handles registration of stubbed endpoints and services
|
6
|
-
#
|
7
|
-
# @author Mikael Henriksson <mikael@zoolutions.se>
|
8
|
-
# @since 0.1.3
|
9
|
-
#
|
10
|
-
module Registration
|
11
|
-
# Register a service in the service registry
|
12
|
-
#
|
13
|
-
#
|
14
|
-
# @param [Symbol] service_id a descriptive id for the service
|
15
|
-
# @param [Symbol] service_uri the uri used to call the service
|
16
|
-
#
|
17
|
-
# @example Register a service with endpoints
|
18
|
-
# register_service(:documents, "https://company.com/api/v1") do
|
19
|
-
# register(:show, :get, "documents/:id")
|
20
|
-
# register(:index, :get, "documents")
|
21
|
-
# register(:create, :post, "documents")
|
22
|
-
# register(:update, :patch, "documents/:id")
|
23
|
-
# register(:destroy, :delete, "documents/:id")
|
24
|
-
# end
|
25
|
-
#
|
26
|
-
# @return [Service] a new service or a previously registered service
|
27
|
-
#
|
28
|
-
def self.register_service(service_id, service_uri, &block)
|
29
|
-
service = Registry.instance.register(service_id, service_uri)
|
30
|
-
Docile.dsl_eval(service.endpoints, &block) if block.present?
|
31
|
-
service
|
32
|
-
end
|
33
|
-
|
34
|
-
#
|
35
|
-
# Stub a request to a registered service endpoint
|
36
|
-
#
|
37
|
-
#
|
38
|
-
# @param [Symbol] service_id the id of a registered service
|
39
|
-
# @param [Symbol] endpoint_id the id of a registered endpoint
|
40
|
-
# @param [Hash<Symbol>] uri_replacements a list of URI replacements
|
41
|
-
# @param [Hash<Symbol>] options
|
42
|
-
# @option options [optional, Hash<Symbol>] :request webmock request options
|
43
|
-
# @option options [optional, Hash<Symbol>] :response webmock response options
|
44
|
-
# @option options [optional, Array, Exception, StandardError, String] :error webmock error to raise
|
45
|
-
# @option options [optional, TrueClass] :timeout set to true to raise some kind of timeout error
|
46
|
-
#
|
47
|
-
# @note the kind of timeout error raised by webmock is depending on the HTTP client used
|
48
|
-
#
|
49
|
-
# @example Stub a request to a registered service endpoint
|
50
|
-
# register_stub(
|
51
|
-
# :google_api,
|
52
|
-
# :get_map_location,
|
53
|
-
# {}, # No URI replacements needed for this endpoint
|
54
|
-
# { request: { headers: { "Accept" => "application/json" }}},
|
55
|
-
# { response: { body: { id: "abyasdjasd", status: "successful" }}}
|
56
|
-
# )
|
57
|
-
#
|
58
|
-
# @example Stub a request to a registered service endpoint using block version
|
59
|
-
# register_stub(:documents, :index) do
|
60
|
-
# with(headers: { "Accept" => "application/json" }}})
|
61
|
-
# to_return(body: "No content", status: 204)
|
62
|
-
# end
|
63
|
-
#
|
64
|
-
# @see #stub_http_request
|
65
|
-
# @return [WebMock::RequestStub] a mocked request
|
66
|
-
#
|
67
|
-
# :reek:UtilityFunction
|
68
|
-
# :reek:LongParameterList { max_params: 5 }
|
69
|
-
def self.stub_endpoint(service_id, endpoint_id, uri_replacements = {}, options = {}, &callback)
|
70
|
-
service, endpoint, uri = StubRequests::URI.for_service_endpoint(service_id, endpoint_id, uri_replacements)
|
71
|
-
endpoint_stub = WebMock::Builder.build(endpoint.verb, uri, options, &callback)
|
72
|
-
|
73
|
-
Metrics.record(service, endpoint, endpoint_stub)
|
74
|
-
::WebMock::StubRegistry.instance.register_request_stub(endpoint_stub)
|
75
|
-
end
|
76
|
-
|
77
|
-
# @api private
|
78
|
-
# Used only for testing purposes
|
79
|
-
# :reek:LongParameterList { max_params: 4 }
|
80
|
-
def self.__stub_endpoint(service_id, endpoint_id, uri_replacements = {}, options = {})
|
81
|
-
_service, endpoint, uri = StubRequests::URI.for_service_endpoint(service_id, endpoint_id, uri_replacements)
|
82
|
-
endpoint_stub = WebMock::Builder.build(endpoint.verb, uri, options)
|
83
|
-
|
84
|
-
::WebMock::StubRegistry.instance.register_request_stub(endpoint_stub)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|