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.
- 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
|