sitehub 0.5.0.alpha5 → 0.5.0.alpha6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|