sitehub 0.5.0.alpha5 → 0.5.0.alpha6
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/Gemfile.lock +2 -2
- data/lib/sitehub/candidate_routes/class_methods.rb +42 -0
- data/lib/sitehub/{route_builder.rb → candidate_routes.rb} +76 -69
- data/lib/sitehub/collection_methods.rb +12 -0
- data/lib/sitehub/cookie/rewriting.rb +42 -0
- data/lib/sitehub/core.rb +10 -20
- data/lib/sitehub/identifier.rb +2 -2
- data/lib/sitehub/middleware/{routes.rb → candidate_route_mappings.rb} +4 -4
- data/lib/sitehub/middleware/config_loader.rb +1 -0
- data/lib/sitehub/middleware/reverse_proxy.rb +2 -2
- data/lib/sitehub/middleware.rb +1 -1
- data/lib/sitehub/request.rb +1 -1
- data/lib/sitehub/version.rb +1 -1
- data/spec/integration/access_logs_spec.rb +75 -0
- data/spec/integration/middleware_spec.rb +129 -0
- data/spec/integration/version_affinity_spec.rb +55 -0
- data/spec/sitehub/builder_spec.rb +3 -3
- data/spec/sitehub/{route_builder_spec.rb → candidate_routes_spec.rb} +193 -52
- data/spec/sitehub/cookie/rewriting_spec.rb +68 -0
- data/spec/sitehub/core_spec.rb +7 -7
- data/spec/sitehub/middleware/{routes_spec.rb → candidate_route_mappings_spec.rb} +4 -4
- data/spec/spec_helper.rb +1 -0
- data/spec/support/shared_examples/sitehub_json_context.rb +42 -6
- metadata +13 -9
- data/lib/sitehub/cookie_rewriting.rb +0 -40
- data/spec/sitehub/cookie_rewriting_spec.rb +0 -66
- data/spec/sitehub/integration_spec.rb +0 -197
@@ -0,0 +1,129 @@
|
|
1
|
+
describe 'middleware' do
|
2
|
+
include_context :middleware_test
|
3
|
+
|
4
|
+
let(:downstream_url) { 'http://localhost:12345' }
|
5
|
+
let(:experiment1_url) { "#{downstream_url}/experiment1" }
|
6
|
+
let(:experiment2_url) { "#{downstream_url}/experiment2" }
|
7
|
+
|
8
|
+
def middleware(name)
|
9
|
+
create_middleware.tap do |clazz|
|
10
|
+
clazz.class_eval do
|
11
|
+
define_method :call do |env|
|
12
|
+
callback = env['async.callback'] || env['async.orig_callback']
|
13
|
+
env['async.orig_callback'] = env['async.callback'] = proc do |status, headers, body|
|
14
|
+
body = body.body.join if body.is_a?(Rack::BodyProxy)
|
15
|
+
|
16
|
+
callback.call(status, headers, "#{name}, #{body}")
|
17
|
+
end
|
18
|
+
@app.call(env)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:app) { Async::Middleware.new(builder) }
|
25
|
+
|
26
|
+
before do
|
27
|
+
WebMock.enable!
|
28
|
+
stub_request(:get, downstream_url).to_return(body: 'hello')
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'middleware added to top level' do
|
32
|
+
let(:builder) do
|
33
|
+
middleware = middleware(:middleware1)
|
34
|
+
downstream_url = downstream_url()
|
35
|
+
|
36
|
+
SiteHub.build do
|
37
|
+
access_logger StringIO.new
|
38
|
+
use middleware
|
39
|
+
proxy '/1' => downstream_url
|
40
|
+
proxy '/2' => downstream_url
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'adds it to each route' do
|
45
|
+
get('/1')
|
46
|
+
expect(app.last_response.body.join).to eq('middleware1, hello')
|
47
|
+
get('/2')
|
48
|
+
expect(app.last_response.body.join).to eq('middleware1, hello')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'middleware added to specific route' do
|
53
|
+
let(:builder) do
|
54
|
+
middleware = middleware(:middleware1)
|
55
|
+
downstream_url = downstream_url()
|
56
|
+
|
57
|
+
SiteHub.build do
|
58
|
+
access_logger StringIO.new
|
59
|
+
proxy '/1' do
|
60
|
+
use middleware
|
61
|
+
route label: :with_middleware, url: downstream_url
|
62
|
+
end
|
63
|
+
proxy '/2' => downstream_url
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'adds it to that route only' do
|
68
|
+
get('/1')
|
69
|
+
expect(app.last_response.body.join).to eq('middleware1, hello')
|
70
|
+
get('/2')
|
71
|
+
expect(app.last_response.body.join).to eq('hello')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'base inherited middleware' do
|
76
|
+
let(:builder) do
|
77
|
+
middleware1 = middleware(:middleware1)
|
78
|
+
middleware2 = middleware(:middleware2)
|
79
|
+
downstream_url = downstream_url()
|
80
|
+
|
81
|
+
SiteHub.build do
|
82
|
+
access_logger StringIO.new
|
83
|
+
use middleware1
|
84
|
+
proxy '/1' do
|
85
|
+
use middleware2
|
86
|
+
route label: :with_middleware, url: downstream_url
|
87
|
+
end
|
88
|
+
proxy '/2' => downstream_url
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'adds it to that route only' do
|
93
|
+
get('/1')
|
94
|
+
expect(app.last_response.body.join).to eq('middleware1, middleware2, hello')
|
95
|
+
get('/2')
|
96
|
+
expect(app.last_response.body.join).to eq('middleware1, hello')
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'nested inherited middleware' do
|
101
|
+
let(:builder) do
|
102
|
+
middleware1 = middleware(:middleware1)
|
103
|
+
middleware2 = middleware(:middleware2)
|
104
|
+
downstream_url = downstream_url()
|
105
|
+
|
106
|
+
SiteHub.build do
|
107
|
+
access_logger StringIO.new
|
108
|
+
|
109
|
+
proxy '/1' do
|
110
|
+
split percentage: 100, label: :experiment1 do
|
111
|
+
use middleware1
|
112
|
+
split percentage: 100, label: :with_middleware do
|
113
|
+
use middleware2
|
114
|
+
split percentage: 100, label: :with_nested_middleware, url: downstream_url
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
proxy '/2' => downstream_url
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'adds it to that route only' do
|
123
|
+
get('/1')
|
124
|
+
expect(app.last_response.body.join).to eq('middleware1, middleware2, hello')
|
125
|
+
get('/2')
|
126
|
+
expect(app.last_response.body.join).to eq('hello')
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
3
|
+
describe 'route affinity' do
|
4
|
+
let(:downstream_url) { 'http://localhost:12345' }
|
5
|
+
let(:experiment1_url) { "#{downstream_url}/experiment1" }
|
6
|
+
let(:experiment2_url) { "#{downstream_url}/experiment2" }
|
7
|
+
|
8
|
+
let(:experiment_body_1) { 'experiment1_body' }
|
9
|
+
let(:experiment_body_2) { 'experiment2_body' }
|
10
|
+
|
11
|
+
before do
|
12
|
+
WebMock.enable!
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:app) do
|
16
|
+
experiment1_url = experiment1_url()
|
17
|
+
experiment2_url = experiment2_url()
|
18
|
+
|
19
|
+
sitehub = SiteHub.build do
|
20
|
+
access_logger StringIO.new
|
21
|
+
error_logger StringIO.new
|
22
|
+
|
23
|
+
proxy '/endpoint' do
|
24
|
+
split(label: :experiment1, percentage: 100) do
|
25
|
+
split percentage: 100, label: 'variant1', url: experiment1_url
|
26
|
+
end
|
27
|
+
|
28
|
+
split(label: :experiment2, percentage: 0) do
|
29
|
+
split percentage: 0, label: 'variant1', url: experiment2_url
|
30
|
+
split percentage: 100, label: 'variant2', url: :should_not_be_called
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
Async::Middleware.new(sitehub)
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'requested route cookie not present' do
|
38
|
+
it 'drops a cookie to keep you on the same path' do
|
39
|
+
stub_request(:get, experiment1_url).to_return(body: experiment_body_1)
|
40
|
+
get('/endpoint')
|
41
|
+
expect(app.last_response.body).to eq([experiment_body_1])
|
42
|
+
expect(app.last_response.cookies[SiteHub::RECORDED_ROUTES_COOKIE][:value]).to eq('experiment1|variant1')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'requested route cookie present' do
|
47
|
+
it 'proxies to the preselected route' do
|
48
|
+
stub_request(:get, experiment2_url).to_return(body: experiment_body_2)
|
49
|
+
|
50
|
+
get('/endpoint', {}, 'HTTP_COOKIE' => "#{SiteHub::RECORDED_ROUTES_COOKIE}=experiment2|variant1")
|
51
|
+
expect(app.last_response.body).to eq([experiment_body_2])
|
52
|
+
expect(app.last_response.cookies[SiteHub::RECORDED_ROUTES_COOKIE][:value]).to eq('experiment2|variant1')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -123,11 +123,11 @@ class SiteHub
|
|
123
123
|
end
|
124
124
|
|
125
125
|
it 'adds a forward proxies' do
|
126
|
-
expect(subject.build).to be_using(Middleware::
|
126
|
+
expect(subject.build).to be_using(Middleware::CandidateRouteMappings)
|
127
127
|
end
|
128
128
|
|
129
129
|
it 'configures it with the sitehub_cookie_name' do
|
130
|
-
forward_proxies = find_middleware(subject.build, Middleware::
|
130
|
+
forward_proxies = find_middleware(subject.build, Middleware::CandidateRouteMappings)
|
131
131
|
expect(forward_proxies.sitehub_cookie_name).to eq(:custom_cookie_name)
|
132
132
|
end
|
133
133
|
end
|
@@ -173,7 +173,7 @@ class SiteHub
|
|
173
173
|
Middleware::ErrorHandling,
|
174
174
|
Middleware::TransactionId,
|
175
175
|
Middleware::ReverseProxy,
|
176
|
-
Middleware::
|
176
|
+
Middleware::CandidateRouteMappings]
|
177
177
|
|
178
178
|
expect(middleware_stack).to eq(expected_middleware)
|
179
179
|
end
|
@@ -1,18 +1,17 @@
|
|
1
1
|
# rubocop:disable Metrics/ClassLength
|
2
|
-
require 'sitehub/
|
2
|
+
require 'sitehub/candidate_routes'
|
3
3
|
|
4
4
|
class SiteHub
|
5
|
-
describe
|
5
|
+
describe CandidateRoutes do
|
6
6
|
include_context :middleware_test
|
7
7
|
|
8
8
|
describe '::from_hash' do
|
9
9
|
include_context :sitehub_json
|
10
10
|
|
11
|
-
subject do
|
12
|
-
described_class.from_hash(proxy_1, :expected).routes[Identifier.new(route_1[:label])]
|
13
|
-
end
|
14
|
-
|
15
11
|
context 'splits' do
|
12
|
+
subject do
|
13
|
+
described_class.from_hash(split_proxy, :expected)
|
14
|
+
end
|
16
15
|
context 'sitehub_cookie_name' do
|
17
16
|
it 'sets it' do
|
18
17
|
expect(subject.sitehub_cookie_name).to eq(:expected)
|
@@ -21,26 +20,110 @@ class SiteHub
|
|
21
20
|
|
22
21
|
context 'sitehub_cookie_path' do
|
23
22
|
it 'sets it' do
|
24
|
-
expect(subject.sitehub_cookie_path).to eq(
|
23
|
+
expect(subject.sitehub_cookie_path).to eq(split_proxy[:sitehub_cookie_path])
|
25
24
|
end
|
26
25
|
end
|
27
26
|
|
28
|
-
|
27
|
+
it 'returns core with splits' do
|
28
|
+
split_1 = split_1()
|
29
|
+
split_2 = split_2()
|
30
|
+
expected = described_class.new(sitehub_cookie_name: :expected,
|
31
|
+
sitehub_cookie_path: subject.sitehub_cookie_path,
|
32
|
+
mapped_path: subject.mapped_path) do
|
33
|
+
split percentage: split_1[:percentage], label: split_1[:label], url: split_1[:url]
|
34
|
+
split percentage: split_2[:percentage], label: split_2[:label], url: split_2[:url]
|
35
|
+
end
|
36
|
+
expect(subject.candidates).to eq(expected.candidates)
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'default' do
|
40
|
+
it 'sets it' do
|
41
|
+
expect(subject.default_route.app.mapped_url).to eq(split_proxy[:default])
|
42
|
+
end
|
43
|
+
end
|
29
44
|
end
|
30
45
|
|
31
46
|
context 'routes' do
|
47
|
+
subject do
|
48
|
+
described_class.from_hash(routes_proxy, :expected)
|
49
|
+
end
|
50
|
+
|
32
51
|
context 'sitehub_cookie_name' do
|
33
|
-
|
52
|
+
it 'sets it' do
|
53
|
+
expect(subject.sitehub_cookie_name).to eq(:expected)
|
54
|
+
end
|
34
55
|
end
|
35
56
|
|
36
57
|
context 'sitehub_cookie_path' do
|
37
|
-
|
58
|
+
it 'sets it' do
|
59
|
+
expect(subject.sitehub_cookie_path).to eq(routes_proxy[:sitehub_cookie_path])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'returns core with routes' do
|
64
|
+
route_1 = route_1()
|
65
|
+
expected = described_class.new(sitehub_cookie_name: :expected,
|
66
|
+
sitehub_cookie_path: subject.sitehub_cookie_path,
|
67
|
+
mapped_path: subject.mapped_path) do
|
68
|
+
route label: route_1[:label], url: route_1[:url]
|
69
|
+
end
|
70
|
+
expect(subject.candidates).to eq(expected.candidates)
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'default' do
|
74
|
+
it 'sets it' do
|
75
|
+
expect(subject.default_route.app.mapped_url).to eq(routes_proxy[:default])
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'nested routes' do
|
81
|
+
context 'routes inside a split' do
|
82
|
+
subject do
|
83
|
+
described_class.from_hash(nested_route_proxy, :expected)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'creates them' do
|
87
|
+
route_1 = route_1()
|
88
|
+
nested_route = nested_route()
|
89
|
+
|
90
|
+
expected = described_class.new(sitehub_cookie_name: :expected,
|
91
|
+
sitehub_cookie_path: subject.sitehub_cookie_path,
|
92
|
+
mapped_path: subject.mapped_path) do
|
93
|
+
split(percentage: nested_route[:percentage], label: nested_route[:label]) do
|
94
|
+
route label: route_1[:label], url: route_1[:url]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
expect(subject).to eq(expected)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'splits in a split' do
|
102
|
+
subject do
|
103
|
+
described_class.from_hash(nested_split_proxy, :expected)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'creates them' do
|
107
|
+
split_1 = split_1()
|
108
|
+
split_2 = split_2()
|
109
|
+
nested_split = nested_split()
|
110
|
+
|
111
|
+
expected = described_class.new(sitehub_cookie_name: :expected,
|
112
|
+
sitehub_cookie_path: subject.sitehub_cookie_path,
|
113
|
+
mapped_path: subject.mapped_path) do
|
114
|
+
split(percentage: nested_split[:percentage], label: nested_split[:label]) do
|
115
|
+
split percentage: split_1[:percentage], label: split_1[:label], url: split_1[:url]
|
116
|
+
split percentage: split_2[:percentage], label: split_2[:label], url: split_2[:url]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
expect(subject).to eq(expected)
|
120
|
+
end
|
38
121
|
end
|
39
|
-
pending 'returns core with routes'
|
40
122
|
end
|
41
123
|
|
42
124
|
context 'default' do
|
43
|
-
it 'sets the default'
|
125
|
+
it 'sets the default' do
|
126
|
+
end
|
44
127
|
end
|
45
128
|
end
|
46
129
|
|
@@ -51,26 +134,35 @@ class SiteHub
|
|
51
134
|
|
52
135
|
describe '#routes' do
|
53
136
|
it 'returns RouteCollection by default' do
|
54
|
-
expect(subject.
|
137
|
+
expect(subject.candidates).to be_a(Collection::RouteCollection)
|
55
138
|
end
|
56
139
|
|
57
140
|
it 'returns the same intance everytime' do
|
58
141
|
collection = Collection::SplitRouteCollection.new
|
59
|
-
subject.
|
60
|
-
expect(subject.
|
142
|
+
subject.candidates(collection)
|
143
|
+
expect(subject.candidates).to be(collection)
|
61
144
|
end
|
62
145
|
|
63
146
|
context 'endpoints already set' do
|
64
147
|
context 'different object supplied' do
|
65
148
|
it 'raises an error' do
|
66
|
-
subject.
|
67
|
-
expect { subject.
|
68
|
-
.to raise_error(
|
149
|
+
subject.candidates(Collection::SplitRouteCollection.new)
|
150
|
+
expect { subject.candidates(Collection::RouteCollection.new) }
|
151
|
+
.to raise_error(CandidateRoutes::InvalidDefinitionException)
|
69
152
|
end
|
70
153
|
end
|
71
154
|
end
|
72
155
|
end
|
73
156
|
|
157
|
+
describe '#[]' do
|
158
|
+
context 'id of existing route passed in' do
|
159
|
+
it 'returns it' do
|
160
|
+
subject.split(label: :current, percentage: 100, url: :url)
|
161
|
+
expect(subject[:current]).to eq(subject[:current])
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
74
166
|
it 'supports middleware' do
|
75
167
|
expect(described_class).to include(Middleware)
|
76
168
|
end
|
@@ -141,20 +233,20 @@ class SiteHub
|
|
141
233
|
describe '#split' do
|
142
234
|
it 'setups up a splits collection' do
|
143
235
|
subject.split percentage: 10, url: :url, label: :label
|
144
|
-
expect(subject.
|
236
|
+
expect(subject.candidates).to be_a(Collection::SplitRouteCollection)
|
145
237
|
end
|
146
238
|
end
|
147
239
|
|
148
240
|
describe '#route' do
|
149
241
|
it 'sets up the routes collection' do
|
150
242
|
subject.route url: :url, label: :current
|
151
|
-
expect(subject.
|
243
|
+
expect(subject.candidates).to be_a(Collection::RouteCollection)
|
152
244
|
end
|
153
245
|
end
|
154
246
|
|
155
|
-
describe '#
|
247
|
+
describe '#add' do
|
156
248
|
it 'stores the route against the given label' do
|
157
|
-
subject.
|
249
|
+
subject.add url: :url, label: :current
|
158
250
|
|
159
251
|
proxy = ForwardProxy.new(mapped_url: :url,
|
160
252
|
mapped_path: subject.mapped_path)
|
@@ -164,17 +256,17 @@ class SiteHub
|
|
164
256
|
sitehub_cookie_name: :cookie_name,
|
165
257
|
sitehub_cookie_path: nil)
|
166
258
|
|
167
|
-
expect(subject
|
259
|
+
expect(subject[:current]).to eq(expected_route)
|
168
260
|
end
|
169
261
|
|
170
262
|
it 'accepts a rule' do
|
171
|
-
endpoint = subject.
|
263
|
+
endpoint = subject.add url: :url, label: :current, rule: :rule
|
172
264
|
expect(endpoint.rule).to eq(:rule)
|
173
265
|
end
|
174
266
|
|
175
267
|
it 'accepts a percentage' do
|
176
|
-
subject.
|
177
|
-
endpoint = subject.
|
268
|
+
subject.candidates(Collection::SplitRouteCollection.new)
|
269
|
+
endpoint = subject.add url: :url, label: :current, percentage: 50
|
178
270
|
expect(endpoint.upper).to eq(50)
|
179
271
|
end
|
180
272
|
|
@@ -189,53 +281,65 @@ class SiteHub
|
|
189
281
|
|
190
282
|
it 'stores the nested route_builder against the label' do
|
191
283
|
rule = proc { true }
|
192
|
-
subject.
|
284
|
+
subject.add(rule: rule, label: :label1, &block)
|
193
285
|
subject.use middleware
|
194
286
|
|
195
|
-
expected_endpoints =
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
287
|
+
expected_endpoints = CandidateRoutes.new(rule: rule,
|
288
|
+
id: :label1,
|
289
|
+
sitehub_cookie_name: :cookie_name,
|
290
|
+
mapped_path: '/path',
|
291
|
+
&block).build
|
200
292
|
|
201
|
-
expect(subject
|
293
|
+
expect(subject[:label1]).to eq(expected_endpoints)
|
202
294
|
subject.build
|
203
295
|
end
|
204
296
|
|
205
297
|
describe '#errors and warnings' do
|
206
298
|
context 'precentage and rule not supplied' do
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
299
|
+
context 'split required' do
|
300
|
+
it 'raise an error' do
|
301
|
+
subject.candidates(Collection::SplitRouteCollection.new)
|
302
|
+
expected_message = described_class::PERCENTAGE_NOT_SPECIFIED_MSG
|
303
|
+
expect { subject.add(label: :label) {} }
|
304
|
+
.to raise_exception described_class::InvalidDefinitionException, expected_message
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
context 'route required' do
|
309
|
+
it 'raise an error' do
|
310
|
+
subject.candidates(Collection::RouteCollection.new)
|
311
|
+
expected_message = described_class::RULE_NOT_SPECIFIED_MSG
|
312
|
+
expect { subject.add(label: :label) {} }
|
313
|
+
.to raise_exception described_class::InvalidDefinitionException, expected_message
|
314
|
+
end
|
211
315
|
end
|
212
316
|
end
|
213
317
|
|
214
318
|
context 'url' do
|
215
319
|
it 'gives a warning to say that the url will not be used' do
|
216
320
|
expect(subject).to receive(:warn).with(described_class::IGNORING_URL_MSG)
|
217
|
-
subject.
|
321
|
+
subject.add(rule: :rule, url: :url, label: :label, &block)
|
218
322
|
end
|
219
323
|
end
|
220
324
|
end
|
221
325
|
|
222
326
|
it 'stores a proxy builder' do
|
223
327
|
rule = proc { true }
|
224
|
-
subject.
|
328
|
+
subject.add(rule: rule, label: :label, &block)
|
225
329
|
|
226
330
|
expected_endpoints = described_class.new(id: :label, sitehub_cookie_name: :cookie_name,
|
227
331
|
rule: rule, mapped_path: subject.mapped_path, &block).tap do |builder|
|
228
332
|
builder.sitehub_cookie_name subject.sitehub_cookie_name
|
229
333
|
end.build
|
230
334
|
|
231
|
-
expect(subject.
|
335
|
+
expect(subject.candidates.values).to eq([expected_endpoints])
|
232
336
|
end
|
233
337
|
|
234
338
|
context 'invalid definitions inside block' do
|
235
339
|
it 'raises an error' do
|
236
340
|
rule = proc { true }
|
237
341
|
expect do
|
238
|
-
subject.
|
342
|
+
subject.add rule: rule, label: :label do
|
239
343
|
split percentage: 20, url: :url, label: :label1
|
240
344
|
end
|
241
345
|
end.to raise_exception described_class::InvalidDefinitionException
|
@@ -250,9 +354,9 @@ class SiteHub
|
|
250
354
|
context 'middleware not specified' do
|
251
355
|
it 'leaves it the proxies alone' do
|
252
356
|
subject.route url: :url, label: :current
|
253
|
-
expect(subject
|
357
|
+
expect(subject[:current]).to be_using_rack_stack(ForwardProxy)
|
254
358
|
subject.build
|
255
|
-
expect(subject
|
359
|
+
expect(subject[:current]).to be_using_rack_stack(ForwardProxy)
|
256
360
|
end
|
257
361
|
end
|
258
362
|
|
@@ -264,7 +368,7 @@ class SiteHub
|
|
264
368
|
it 'wraps the forward proxies in the middleware' do
|
265
369
|
subject.route url: :url, label: :current
|
266
370
|
subject.build
|
267
|
-
expect(subject
|
371
|
+
expect(subject[:current]).to be_using_rack_stack(middleware, ForwardProxy)
|
268
372
|
end
|
269
373
|
|
270
374
|
it 'wraps the default in the middleware' do
|
@@ -272,9 +376,18 @@ class SiteHub
|
|
272
376
|
subject.build
|
273
377
|
expect(subject.default_route).to be_using_rack_stack(middleware, ForwardProxy)
|
274
378
|
end
|
379
|
+
end
|
275
380
|
|
276
|
-
|
277
|
-
|
381
|
+
context 'middleware present on the parent route' do
|
382
|
+
it 'adds it to the list middleware to be added' do
|
383
|
+
middleware = middleware()
|
384
|
+
subject.split(percentage: 100, label: :parent) do
|
385
|
+
use middleware
|
386
|
+
split(percentage: 100, label: :child) do
|
387
|
+
default url: :url
|
388
|
+
end
|
389
|
+
end
|
390
|
+
expect(subject[:parent][:child].default_route).to be_using(middleware)
|
278
391
|
end
|
279
392
|
end
|
280
393
|
end
|
@@ -284,11 +397,11 @@ class SiteHub
|
|
284
397
|
context 'routes defined' do
|
285
398
|
it 'returns that route' do
|
286
399
|
subject.route url: :url, label: :current
|
287
|
-
expect(subject.resolve(env: {})).to eq(subject.
|
400
|
+
expect(subject.resolve(env: {})).to eq(subject.candidates.values.first)
|
288
401
|
end
|
289
402
|
|
290
403
|
it 'passes the env to the when resolving the correct route' do
|
291
|
-
expect_any_instance_of(subject.
|
404
|
+
expect_any_instance_of(subject.candidates.class).to receive(:resolve).with(env: :env).and_call_original
|
292
405
|
subject.resolve(env: :env)
|
293
406
|
end
|
294
407
|
end
|
@@ -343,15 +456,15 @@ class SiteHub
|
|
343
456
|
context '#endpoints' do
|
344
457
|
context 'called with a collection' do
|
345
458
|
it 'sets endpoints to be that collection' do
|
346
|
-
subject.
|
347
|
-
expect(subject.
|
459
|
+
subject.candidates(:collection)
|
460
|
+
expect(subject.candidates).to eq(:collection)
|
348
461
|
end
|
349
462
|
end
|
350
463
|
|
351
464
|
context 'already set with a different collection' do
|
352
465
|
it 'raise an error' do
|
353
|
-
subject.
|
354
|
-
expect { subject.
|
466
|
+
subject.candidates(:collection1)
|
467
|
+
expect { subject.candidates(:collection2) }.to raise_exception described_class::InvalidDefinitionException
|
355
468
|
end
|
356
469
|
end
|
357
470
|
end
|
@@ -374,5 +487,33 @@ class SiteHub
|
|
374
487
|
expect(proxy.sitehub_cookie_name).to eq(:expected_cookie_name)
|
375
488
|
end
|
376
489
|
end
|
490
|
+
|
491
|
+
describe '#method_missing' do
|
492
|
+
context 'calling scope set' do
|
493
|
+
subject do
|
494
|
+
calling_scope = double(:calling_scope, parent_method: :called)
|
495
|
+
described_class.new(sitehub_cookie_name: :cookie_name,
|
496
|
+
mapped_path: '/path',
|
497
|
+
calling_scope: calling_scope)
|
498
|
+
end
|
499
|
+
context 'method on calling_context' do
|
500
|
+
it 'delegates to it' do
|
501
|
+
expect(subject.parent_method).to eq(:called)
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
context 'method on calling_context' do
|
506
|
+
it 'delegates to it' do
|
507
|
+
expect(subject.parent_method).to eq(:called)
|
508
|
+
end
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
context 'calling scope not set' do
|
513
|
+
it 'raises an error' do
|
514
|
+
expect { subject.parent_method }.to raise_error(NoMethodError)
|
515
|
+
end
|
516
|
+
end
|
517
|
+
end
|
377
518
|
end
|
378
519
|
end
|