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