stub_requests 0.1.0
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 +7 -0
- data/.codeclimate.yml +23 -0
- data/.editorconfig +13 -0
- data/.gitignore +10 -0
- data/.mdlrc +1 -0
- data/.reek.yml +12 -0
- data/.rspec +3 -0
- data/.rubocop.yml +112 -0
- data/.ruby-version +1 -0
- data/.simplecov +23 -0
- data/.travis.yml +37 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +0 -0
- data/CODE_OF_CONDUCT.md +64 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +138 -0
- data/Rakefile +8 -0
- data/_config.yml +1 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/index.md +37 -0
- data/lib/stub_requests/api.rb +73 -0
- data/lib/stub_requests/argument_validation.rb +39 -0
- data/lib/stub_requests/core_ext/all.rb +3 -0
- data/lib/stub_requests/core_ext/object/blank.rb +171 -0
- data/lib/stub_requests/core_ext.rb +3 -0
- data/lib/stub_requests/endpoint.rb +100 -0
- data/lib/stub_requests/endpoint_registry.rb +157 -0
- data/lib/stub_requests/hash_util.rb +30 -0
- data/lib/stub_requests/service.rb +118 -0
- data/lib/stub_requests/service_registry.rb +105 -0
- data/lib/stub_requests/stub_requests.rb +90 -0
- data/lib/stub_requests/uri/builder.rb +226 -0
- data/lib/stub_requests/uri/scheme.rb +34 -0
- data/lib/stub_requests/uri/suffix.rb +31 -0
- data/lib/stub_requests/uri/validator.rb +69 -0
- data/lib/stub_requests/version.rb +13 -0
- data/lib/stub_requests/webmock_builder.rb +108 -0
- data/lib/stub_requests.rb +25 -0
- data/stub_requests.gemspec +56 -0
- metadata +363 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "addressable/uri"
|
4
|
+
require "public_suffix"
|
5
|
+
|
6
|
+
#
|
7
|
+
# Abstraction over WebMock to reduce duplication
|
8
|
+
#
|
9
|
+
# @author Mikael Henriksson <mikael@zoolutions.se>
|
10
|
+
# @since 0.1.0
|
11
|
+
#
|
12
|
+
module StubRequests
|
13
|
+
#
|
14
|
+
# Module ArgumentValidation provides validation of method arguments
|
15
|
+
#
|
16
|
+
module ArgumentValidation
|
17
|
+
extend self
|
18
|
+
|
19
|
+
#
|
20
|
+
# Require the value to be any of the types past in
|
21
|
+
#
|
22
|
+
#
|
23
|
+
# @param [Object] value the value to validate
|
24
|
+
# @param [Array<Class>, Array<Module>, Class, Module] is_a
|
25
|
+
#
|
26
|
+
# @raise [InvalidType] when the value is disallowed
|
27
|
+
#
|
28
|
+
# @return [true] when the value is allowed
|
29
|
+
#
|
30
|
+
def validate!(value, is_a:)
|
31
|
+
expected_types = Array(is_a)
|
32
|
+
return true if expected_types.any? { |type| value.is_a?(type) }
|
33
|
+
|
34
|
+
raise StubRequests::InvalidType,
|
35
|
+
actual: value.class,
|
36
|
+
expected: expected_types.join(", ")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "concurrent/map"
|
4
|
+
|
5
|
+
# Copied from https://raw.githubusercontent.com/rails/rails/d66e7835bea9505f7003e5038aa19b6ea95ceea1/activesupport/lib/active_support/core_ext/object/blank.rb
|
6
|
+
|
7
|
+
# :nodoc:
|
8
|
+
# :nocov:
|
9
|
+
|
10
|
+
# @see Object
|
11
|
+
class Object # :nodoc: # :nocov:
|
12
|
+
# An object is blank if it's false, empty, or a whitespace string.
|
13
|
+
# For example, +nil+, '', ' ', [], {}, and +false+ are all blank.
|
14
|
+
#
|
15
|
+
# This simplifies
|
16
|
+
#
|
17
|
+
# !address || address.empty?
|
18
|
+
#
|
19
|
+
# to
|
20
|
+
#
|
21
|
+
# address.blank?
|
22
|
+
#
|
23
|
+
# @return [true, false]
|
24
|
+
def blank?
|
25
|
+
respond_to?(:empty?) ? !!empty? : !self # rubocop:disable Style/DoubleNegation
|
26
|
+
end unless respond_to?(:blank?)
|
27
|
+
|
28
|
+
# An object is present if it's not blank.
|
29
|
+
#
|
30
|
+
# @return [true, false]
|
31
|
+
def present?
|
32
|
+
!blank?
|
33
|
+
end unless respond_to?(:present?)
|
34
|
+
|
35
|
+
# Returns the receiver if it's present otherwise returns +nil+.
|
36
|
+
# <tt>object.presence</tt> is equivalent to
|
37
|
+
#
|
38
|
+
# object.present? ? object : nil
|
39
|
+
#
|
40
|
+
# For example, something like
|
41
|
+
#
|
42
|
+
# state = params[:state] if params[:state].present?
|
43
|
+
# country = params[:country] if params[:country].present?
|
44
|
+
# region = state || country || 'US'
|
45
|
+
#
|
46
|
+
# becomes
|
47
|
+
#
|
48
|
+
# region = params[:state].presence || params[:country].presence || 'US'
|
49
|
+
#
|
50
|
+
# @return [Object]
|
51
|
+
def presence
|
52
|
+
self if present?
|
53
|
+
end unless respond_to?(:presence)
|
54
|
+
end
|
55
|
+
|
56
|
+
# @see NilClass
|
57
|
+
class NilClass
|
58
|
+
# +nil+ is blank:
|
59
|
+
#
|
60
|
+
# nil.blank? # => true
|
61
|
+
#
|
62
|
+
# @return [true]
|
63
|
+
def blank?
|
64
|
+
true
|
65
|
+
end unless respond_to?(:blank?)
|
66
|
+
end
|
67
|
+
|
68
|
+
# @see FalseClass
|
69
|
+
class FalseClass
|
70
|
+
# +false+ is blank:
|
71
|
+
#
|
72
|
+
# false.blank? # => true
|
73
|
+
#
|
74
|
+
# @return [true]
|
75
|
+
def blank?
|
76
|
+
true
|
77
|
+
end unless respond_to?(:blank?)
|
78
|
+
end
|
79
|
+
|
80
|
+
# @see TrueClass
|
81
|
+
class TrueClass
|
82
|
+
# +true+ is not blank:
|
83
|
+
#
|
84
|
+
# true.blank? # => false
|
85
|
+
#
|
86
|
+
# @return [false]
|
87
|
+
def blank?
|
88
|
+
false
|
89
|
+
end unless respond_to?(:blank?)
|
90
|
+
end
|
91
|
+
|
92
|
+
# @see Array
|
93
|
+
class Array
|
94
|
+
# An array is blank if it's empty:
|
95
|
+
#
|
96
|
+
# [].blank? # => true
|
97
|
+
# [1,2,3].blank? # => false
|
98
|
+
#
|
99
|
+
# @return [true, false]
|
100
|
+
alias blank? empty?
|
101
|
+
end
|
102
|
+
|
103
|
+
# @see Hash
|
104
|
+
class Hash
|
105
|
+
# A hash is blank if it's empty:
|
106
|
+
#
|
107
|
+
# {}.blank? # => true
|
108
|
+
# { key: 'value' }.blank? # => false
|
109
|
+
#
|
110
|
+
# @return [true, false]
|
111
|
+
alias blank? empty?
|
112
|
+
end
|
113
|
+
|
114
|
+
# @see String
|
115
|
+
class String
|
116
|
+
# :nodoc:
|
117
|
+
BLANK_RE = /\A[[:space:]]*\z/.freeze
|
118
|
+
# :nodoc:
|
119
|
+
ENCODED_BLANKS = Concurrent::Map.new do |map, enc|
|
120
|
+
map[enc] = Regexp.new(BLANK_RE.source.encode(enc), BLANK_RE.options | Regexp::FIXEDENCODING)
|
121
|
+
end
|
122
|
+
|
123
|
+
# A string is blank if it's empty or contains whitespaces only:
|
124
|
+
#
|
125
|
+
# ''.blank? # => true
|
126
|
+
# ' '.blank? # => true
|
127
|
+
# "\t\n\r".blank? # => true
|
128
|
+
# ' blah '.blank? # => false
|
129
|
+
#
|
130
|
+
# Unicode whitespace is supported:
|
131
|
+
#
|
132
|
+
# "\u00a0".blank? # => true
|
133
|
+
#
|
134
|
+
# @return [true, false]
|
135
|
+
def blank?
|
136
|
+
# The regexp that matches blank strings is expensive. For the case of empty
|
137
|
+
# strings we can speed up this method (~3.5x) with an empty? call. The
|
138
|
+
# penalty for the rest of strings is marginal.
|
139
|
+
empty? ||
|
140
|
+
begin
|
141
|
+
BLANK_RE.match?(self)
|
142
|
+
rescue Encoding::CompatibilityError
|
143
|
+
ENCODED_BLANKS[encoding].match?(self)
|
144
|
+
end
|
145
|
+
end unless respond_to?(:blank?)
|
146
|
+
end
|
147
|
+
|
148
|
+
# @see Numeric
|
149
|
+
class Numeric
|
150
|
+
# No number is blank:
|
151
|
+
#
|
152
|
+
# 1.blank? # => false
|
153
|
+
# 0.blank? # => false
|
154
|
+
#
|
155
|
+
# @return [false]
|
156
|
+
def blank?
|
157
|
+
false
|
158
|
+
end unless respond_to?(:blank?)
|
159
|
+
end
|
160
|
+
|
161
|
+
# @see Time
|
162
|
+
class Time
|
163
|
+
# No Time is blank:
|
164
|
+
#
|
165
|
+
# Time.now.blank? # => false
|
166
|
+
#
|
167
|
+
# @return [false]
|
168
|
+
def blank?
|
169
|
+
false
|
170
|
+
end unless respond_to?(:blank?)
|
171
|
+
end
|
@@ -0,0 +1,100 @@
|
|
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 registration of stubbed endpoints
|
12
|
+
#
|
13
|
+
class Endpoint
|
14
|
+
include ArgumentValidation
|
15
|
+
include Comparable
|
16
|
+
|
17
|
+
#
|
18
|
+
# @!attribute [rw] id
|
19
|
+
# @return [Symbol] the id of the endpoint
|
20
|
+
attr_reader :id
|
21
|
+
|
22
|
+
#
|
23
|
+
# @!attribute [rw] verb
|
24
|
+
# @return [Symbol] a HTTP verb
|
25
|
+
attr_reader :verb
|
26
|
+
|
27
|
+
#
|
28
|
+
# @!attribute [rw] uri_template
|
29
|
+
# @return [String] a string template for the endpoint
|
30
|
+
attr_reader :uri_template
|
31
|
+
|
32
|
+
#
|
33
|
+
# @!attribute [rw] default_options
|
34
|
+
# @see
|
35
|
+
# @return [Hash<Symbol>] a string template for the endpoint
|
36
|
+
attr_reader :default_options
|
37
|
+
|
38
|
+
#
|
39
|
+
# An endpoint for a specific {Service}
|
40
|
+
#
|
41
|
+
# @param [Symbol] endpoint_id a descriptive id for the endpoint
|
42
|
+
# @param [Symbol] verb a HTTP verb
|
43
|
+
# @param [String] uri_template how to reach the endpoint
|
44
|
+
# @param [optional, Hash<Symbol>] default_options
|
45
|
+
# @option default_options [optional, Hash<Symbol>] :request for request_stub.with
|
46
|
+
# @option default_options [optional, Hash<Symbol>] :response for request_stub.to_return
|
47
|
+
# @option default_options [optional, Array, Exception, StandardError, String] :error for request_stub.to_raise
|
48
|
+
# @option default_options [optional, TrueClass] :timeout for request_stub.to_timeout
|
49
|
+
#
|
50
|
+
def initialize(endpoint_id, verb, uri_template, default_options = {})
|
51
|
+
validate! endpoint_id, is_a: Symbol
|
52
|
+
validate! verb, is_a: Symbol
|
53
|
+
validate! uri_template, is_a: String
|
54
|
+
|
55
|
+
@id = endpoint_id
|
56
|
+
@verb = verb
|
57
|
+
@uri_template = uri_template
|
58
|
+
@default_options = default_options
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Updates this endpoint
|
63
|
+
#
|
64
|
+
# @param [Symbol] verb a HTTP verb
|
65
|
+
# @param [String] uri_template how to reach the endpoint
|
66
|
+
# @param [optional, Hash<Symbol>] default_options
|
67
|
+
# @option default_options [optional, Hash<Symbol>] :request for request_stub.with
|
68
|
+
# @option default_options [optional, Hash<Symbol>] :response for request_stub.to_return
|
69
|
+
# @option default_options [optional, Array, Exception, StandardError, String] :error for request_stub.to_raise
|
70
|
+
# @option default_options [optional, TrueClass] :timeout for request_stub.to_timeout
|
71
|
+
#
|
72
|
+
# @return [Endpoint] returns the updated endpoint
|
73
|
+
#
|
74
|
+
def update(verb, uri_template, default_options)
|
75
|
+
@verb = verb
|
76
|
+
@uri_template = uri_template
|
77
|
+
@default_options = default_options
|
78
|
+
self
|
79
|
+
end
|
80
|
+
|
81
|
+
def <=>(other)
|
82
|
+
id <=> other.id
|
83
|
+
end
|
84
|
+
|
85
|
+
def hash
|
86
|
+
[id, self.class].hash
|
87
|
+
end
|
88
|
+
|
89
|
+
alias eql? ==
|
90
|
+
|
91
|
+
#
|
92
|
+
# Returns a descriptive string of this endpoint
|
93
|
+
#
|
94
|
+
# @return [String]
|
95
|
+
#
|
96
|
+
def to_s
|
97
|
+
"#<#{self.class} id=:#{id} verb=:#{verb} uri_template='#{uri_template}'>"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,157 @@
|
|
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 EndpointRegistry holds a collection of {Endpoint}
|
12
|
+
#
|
13
|
+
class EndpointRegistry
|
14
|
+
include Enumerable
|
15
|
+
|
16
|
+
#
|
17
|
+
# @!attribute [rw] endpoints
|
18
|
+
# @return [Concurrent::Map<Symbol, Endpoint>] a map with endpoints
|
19
|
+
attr_reader :endpoints
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@endpoints = Concurrent::Map.new
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# Required by Enumerable
|
27
|
+
#
|
28
|
+
# @return [Concurrent::Map<Symbol, Service>] a map with endpoints
|
29
|
+
#
|
30
|
+
# @yield used by Enumerable
|
31
|
+
#
|
32
|
+
def each(&block)
|
33
|
+
endpoints.each(&block)
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Registers an endpoint in the collection
|
38
|
+
#
|
39
|
+
# @param [Symbol] endpoint_id the id of this Endpoint
|
40
|
+
# @param [Symbol] verb a HTTP verb
|
41
|
+
# @param [String] uri_template the URI to reach the endpoint
|
42
|
+
# @param [optional, Hash<Symbol>] default_options default options
|
43
|
+
#
|
44
|
+
# @return [Endpoint]
|
45
|
+
#
|
46
|
+
# :reek:LongParameterList { max_params: 4 }
|
47
|
+
def register(endpoint_id, verb, uri_template, default_options = {})
|
48
|
+
endpoint =
|
49
|
+
if (endpoint = get(endpoint_id))
|
50
|
+
StubRequests.logger.warn("Endpoint already registered: #{endpoint}")
|
51
|
+
endpoint.update(verb, uri_template, default_options)
|
52
|
+
else
|
53
|
+
Endpoint.new(endpoint_id, verb, uri_template, default_options)
|
54
|
+
end
|
55
|
+
|
56
|
+
endpoints[endpoint.id] = endpoint
|
57
|
+
endpoint
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Check if an endpoint is registered
|
62
|
+
#
|
63
|
+
# @param [Symbol] endpoint_id the id of the endpoint
|
64
|
+
#
|
65
|
+
# @return [true, false]
|
66
|
+
#
|
67
|
+
def registered?(endpoint_id)
|
68
|
+
endpoints[endpoint_id].present?
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# Updates an endpoint
|
73
|
+
#
|
74
|
+
# @param [Symbol] endpoint_id the id of the endpoint
|
75
|
+
# @param [Symbol] verb a HTTP verb
|
76
|
+
# @param [String] uri_template how to reach the endpoint
|
77
|
+
# @param [optional, Hash<Symbol>] default_options
|
78
|
+
# @option default_options [optional, Hash<Symbol>] :request request options
|
79
|
+
# @option default_options [optional, Hash<Symbol>] :response options
|
80
|
+
# @option default_options [optional, Array, Exception, StandardError, String] :error to raise
|
81
|
+
# @option default_options [optional, TrueClass] :timeout raise a timeout error?
|
82
|
+
#
|
83
|
+
# @raise [EndpointNotFound] when the endpoint couldn't be found
|
84
|
+
#
|
85
|
+
# @return [Endpoint] returns the updated endpoint
|
86
|
+
#
|
87
|
+
# :reek:LongParameterList { max_params: 4 }
|
88
|
+
def update(endpoint_id, verb, uri_template, default_options)
|
89
|
+
endpoint = get!(endpoint_id)
|
90
|
+
endpoint.update(verb, uri_template, default_options)
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# Removes an endpoint from the collection
|
95
|
+
#
|
96
|
+
# @param [Symbol] endpoint_id the id of the endpoint, `:file_service`
|
97
|
+
#
|
98
|
+
# @return [Endpoint] the endpoint that was removed
|
99
|
+
#
|
100
|
+
def remove(endpoint_id)
|
101
|
+
endpoints.delete(endpoint_id)
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# Fetches an endpoint from the collection
|
106
|
+
#
|
107
|
+
# @param [<type>] endpoint_id <description>
|
108
|
+
#
|
109
|
+
# @return [Endpoint]
|
110
|
+
#
|
111
|
+
def get(endpoint_id)
|
112
|
+
endpoints[endpoint_id]
|
113
|
+
end
|
114
|
+
|
115
|
+
#
|
116
|
+
# Fetches an endpoint from the collection or raises an error
|
117
|
+
#
|
118
|
+
# @param [Symbol] endpoint_id the id of the endpoint
|
119
|
+
#
|
120
|
+
# @raise [EndpointNotFound] when an endpoint couldn't be found
|
121
|
+
#
|
122
|
+
# @return [Endpoint, nil]
|
123
|
+
#
|
124
|
+
def get!(endpoint_id)
|
125
|
+
get(endpoint_id) || raise(EndpointNotFound, "Couldn't find an endpoint with id=:#{endpoint_id}")
|
126
|
+
end
|
127
|
+
|
128
|
+
#
|
129
|
+
# Returns a descriptive string with all endpoints in the collection
|
130
|
+
#
|
131
|
+
# @return [String]
|
132
|
+
#
|
133
|
+
def to_s
|
134
|
+
[
|
135
|
+
+"#<#{self.class} endpoints=",
|
136
|
+
+endpoints_string,
|
137
|
+
+">",
|
138
|
+
].join("")
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# Returns a nicely formatted string with an array of endpoints
|
143
|
+
#
|
144
|
+
#
|
145
|
+
# @return [<type>] <description>
|
146
|
+
#
|
147
|
+
def endpoints_string
|
148
|
+
"[#{endpoints_as_string}]"
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
def endpoints_as_string
|
154
|
+
endpoints.values.map(&:to_s).join(",") if endpoints.size.positive?
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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
|
+
# Provides convenience methods for hashes
|
12
|
+
#
|
13
|
+
module HashUtil
|
14
|
+
#
|
15
|
+
# Removes all entries with nil values (first level only)
|
16
|
+
#
|
17
|
+
# @param [Hash] options the hash to compact
|
18
|
+
#
|
19
|
+
# @return [Hash, nil] Returns
|
20
|
+
#
|
21
|
+
# @yieldparam [Hash] compacted the hash without nils
|
22
|
+
# @yieldreturn [void]
|
23
|
+
def self.compact(options)
|
24
|
+
return if options.blank?
|
25
|
+
|
26
|
+
compacted = options.delete_if { |_, val| val.blank? }
|
27
|
+
yield compacted if compacted.present?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,118 @@
|
|
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 Service provides details for a registered service
|
12
|
+
#
|
13
|
+
class Service
|
14
|
+
include ArgumentValidation
|
15
|
+
include Comparable
|
16
|
+
|
17
|
+
# @!attribute [rw] id
|
18
|
+
# @return [EndpointRegistry] the id of the service
|
19
|
+
attr_reader :id
|
20
|
+
|
21
|
+
# @!attribute [rw] uri
|
22
|
+
# @return [EndpointRegistry] the base uri to the service
|
23
|
+
attr_reader :uri
|
24
|
+
|
25
|
+
# @!attribute [rw] endpoint_registry
|
26
|
+
# @return [EndpointRegistry] a list with defined endpoints
|
27
|
+
attr_reader :endpoint_registry
|
28
|
+
|
29
|
+
#
|
30
|
+
# Initializes a new instance of a Service
|
31
|
+
#
|
32
|
+
# @param [Symbol] service_id the id of this service
|
33
|
+
# @param [String] service_uri the base uri to reach the service
|
34
|
+
#
|
35
|
+
def initialize(service_id, service_uri)
|
36
|
+
validate! service_id, is_a: Symbol
|
37
|
+
validate! service_uri, is_a: String
|
38
|
+
|
39
|
+
@id = service_id
|
40
|
+
@uri = service_uri
|
41
|
+
@endpoint_registry = EndpointRegistry.new
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Registers a new endpoint or updates an existing one
|
46
|
+
#
|
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>] default_options default options
|
52
|
+
#
|
53
|
+
# @return [Endpoint] either the new endpoint or the updated one
|
54
|
+
#
|
55
|
+
# :reek:LongParameterList { max_params: 5 }
|
56
|
+
def register_endpoint(endpoint_id, verb, uri_template, default_options = {})
|
57
|
+
endpoint_registry.register(endpoint_id, verb, uri_template, default_options)
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Check if the endpoint registry has endpoints
|
62
|
+
#
|
63
|
+
# @return [true,false]
|
64
|
+
#
|
65
|
+
def endpoints?
|
66
|
+
endpoint_registry.any?
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# Gets an endpoint from the {#endpoint_registry} collection
|
71
|
+
#
|
72
|
+
# @param [Symbol] endpoint_id the id of the endpoint
|
73
|
+
#
|
74
|
+
# @raise [EndpointNotFound] when the endpoint couldn't be found
|
75
|
+
#
|
76
|
+
# @return [Endpoint]
|
77
|
+
#
|
78
|
+
def get_endpoint!(endpoint_id)
|
79
|
+
endpoint_registry.get!(endpoint_id)
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# Gets an endpoint from the {#endpoint_registry} collection
|
84
|
+
#
|
85
|
+
# @param [Symbol] endpoint_id the id of the endpoint
|
86
|
+
#
|
87
|
+
# @return [Endpoint, nil]
|
88
|
+
#
|
89
|
+
def get_endpoint(endpoint_id)
|
90
|
+
endpoint_registry.get(endpoint_id)
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# Returns a nicely formatted string with this service
|
95
|
+
#
|
96
|
+
# @return [String]
|
97
|
+
#
|
98
|
+
def to_s
|
99
|
+
[
|
100
|
+
+"#<#{self.class}",
|
101
|
+
+" id=#{id}",
|
102
|
+
+" uri=#{uri}",
|
103
|
+
+" endpoints=#{endpoint_registry.endpoints_string}",
|
104
|
+
+">",
|
105
|
+
].join("")
|
106
|
+
end
|
107
|
+
|
108
|
+
def <=>(other)
|
109
|
+
id <=> other.id
|
110
|
+
end
|
111
|
+
|
112
|
+
def hash
|
113
|
+
[id, self.class].hash
|
114
|
+
end
|
115
|
+
|
116
|
+
alias eql? ==
|
117
|
+
end
|
118
|
+
end
|