sitehub 0.5.0.alpha3 → 0.5.0.alpha4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,20 +1,198 @@
1
1
  require 'async/middleware'
2
- describe 'proxying calls' do
3
- include_context :site_hub
2
+ require 'stringio'
3
+ shared_context :site_hub do
4
+ let(:downstream_url) { 'http://localhost:12345' }
5
+ let(:experiment1_url) { "#{downstream_url}/experiment1" }
6
+ let(:experiment2_url) { "#{downstream_url}/experiment2" }
4
7
 
5
- describe 'supported HTTP verbs' do
6
- before do
7
- WebMock.enable!
8
+ before do
9
+ WebMock.enable!
10
+ stub_request(:get, experiment1_url).to_return(body: 'hello')
11
+ stub_request(:get, experiment2_url).to_return(body: 'experiment1_body')
12
+ end
13
+
14
+ let(:builder) do
15
+ SiteHub::Builder.new.tap do |builder|
16
+ builder.access_logger StringIO.new
17
+ builder.error_logger StringIO.new
18
+ experiment1_url = experiment1_url()
19
+ experiment2_url = experiment2_url()
20
+
21
+ builder.proxy '/endpoint' do
22
+ split(label: :experiment1, percentage: 100) do
23
+ split percentage: 100, label: 'variant1', url: experiment1_url
24
+ end
25
+
26
+ split(label: :experiment2, percentage: 0) do
27
+ split percentage: 100, label: 'variant1', url: experiment2_url
28
+ end
29
+ end
8
30
  end
31
+ end
32
+
33
+ let(:rack_application) do
34
+ builder.build
35
+ end
36
+ end
9
37
 
10
- let(:app) { Async::Middleware.new(rack_application) }
38
+ describe 'proxying calls' do
39
+ include_context :site_hub
11
40
 
41
+ let(:app) { Async::Middleware.new(rack_application) }
42
+ describe 'supported HTTP verbs' do
12
43
  %i(get post put delete).each do |verb|
13
44
  it 'forwards the downstream' do
14
- stub_request(verb, downstream_url).to_return(body: 'hello')
45
+ stub_request(verb, experiment1_url).to_return(body: 'hello')
15
46
  send(verb, '/endpoint')
16
47
  expect(app.last_response.body).to eq(['hello'])
17
48
  end
18
49
  end
19
50
  end
51
+
52
+ describe 'route affinity' do
53
+ context 'requested route cookie not present' do
54
+ it 'drops a cookie to keep you on the same path' do
55
+ stub_request(:get, downstream_url).to_return(body: 'hello')
56
+ get('/endpoint')
57
+ expect(app.last_response.cookies[SiteHub::RECORDED_ROUTES_COOKIE][:value]).to eq('experiment1|variant1')
58
+ end
59
+ end
60
+
61
+ context 'requested route cookie present' do
62
+ it 'proxies to the preselected route' do
63
+ get('/endpoint', {}, 'HTTP_COOKIE' => "#{SiteHub::RECORDED_ROUTES_COOKIE}=experiment2|variant1")
64
+ expect(app.last_response.body).to eq(['experiment1_body'])
65
+
66
+ expect(app.last_response.cookies[SiteHub::RECORDED_ROUTES_COOKIE][:value]).to eq('experiment2|variant1')
67
+ end
68
+ end
69
+ end
70
+
71
+ # describe 'middleware' do
72
+ #
73
+ # include_context :middleware_test
74
+ #
75
+ # let(:app) { Async::Middleware.new(rack_application) }
76
+ #
77
+ # def middleware name
78
+ # create_middleware.tap do |clazz|
79
+ # clazz.class_eval do
80
+ # define_method :call do |env|
81
+ # callback = env['async.callback'] || env['async.orig_callback']
82
+ # env['async.orig_callback'] = env['async.callback'] = proc do |status, headers, body|
83
+ # if body.is_a?(Rack::BodyProxy)
84
+ # body = "#{name}, #{body.body.join}"
85
+ # end
86
+ #
87
+ # callback.call(status, headers, body)
88
+ # end
89
+ # @app.call(env)
90
+ # end
91
+ # end
92
+ # end
93
+ # end
94
+ #
95
+ # before do
96
+ # stub_request(:get, downstream_url).to_return(body: 'hello')
97
+ # end
98
+ #
99
+ # context 'middleware added to top level' do
100
+ # let(:builder) do
101
+ # middleware = middleware(:middleware1)
102
+ # downstream_url = downstream_url()
103
+ #
104
+ # SiteHub::Builder.new do
105
+ # access_logger StringIO.new
106
+ # use middleware
107
+ # proxy '/1' => downstream_url
108
+ # proxy '/2' => downstream_url
109
+ # end
110
+ # end
111
+ #
112
+ # it 'adds it to each route' do
113
+ # get('/1')
114
+ # expect(app.last_response.body.join).to eq('middleware1, hello')
115
+ # get('/2')
116
+ # expect(app.last_response.body.join).to eq('middleware1, hello')
117
+ # end
118
+ # end
119
+ #
120
+ # context 'middleware added to specific route' do
121
+ # let(:builder) do
122
+ # middleware = middleware(:middleware1)
123
+ # downstream_url = downstream_url()
124
+ #
125
+ # SiteHub::Builder.new do
126
+ # access_logger StringIO.new
127
+ # proxy '/1' do
128
+ # use middleware
129
+ # route label: :with_middleware, url: downstream_url
130
+ # end
131
+ # proxy '/2' => downstream_url
132
+ # end
133
+ # end
134
+ #
135
+ # it 'adds it to that route only' do
136
+ # get('/1')
137
+ # expect(app.last_response.body.join).to eq('middleware1, hello')
138
+ # get('/2')
139
+ # expect(app.last_response.body.join).to eq('hello')
140
+ # end
141
+ # end
142
+ #
143
+ # context 'base inherited middleware' do
144
+ # let(:builder) do
145
+ # middleware1 = middleware(:middleware1)
146
+ # middleware2 = middleware(:middleware2)
147
+ # downstream_url = downstream_url()
148
+ #
149
+ # SiteHub::Builder.new do
150
+ # access_logger StringIO.new
151
+ # use middleware1
152
+ # proxy '/1' do
153
+ # use middleware2
154
+ # route label: :with_middleware, url: downstream_url
155
+ # end
156
+ # # proxy '/2' => downstream_url
157
+ # end
158
+ # end
159
+ #
160
+ # it 'adds it to that route only' do
161
+ # get('/1')
162
+ # expect(app.last_response.body.join).to eq('middleware1, middleware2, hello')
163
+ # get('/2')
164
+ # expect(app.last_response.body.join).to eq('middleware1, hello')
165
+ # end
166
+ # end
167
+ #
168
+ # context 'nested inherited middleware' do
169
+ # let(:builder) do
170
+ # middleware1 = middleware(:middleware1)
171
+ # middleware2 = middleware(:middleware2)
172
+ # downstream_url = downstream_url()
173
+ #
174
+ # SiteHub::Builder.new do
175
+ # access_logger StringIO.new
176
+ #
177
+ # proxy '/1' do
178
+ # split percentage: 100, label: :experiment1 do
179
+ # use middleware1
180
+ # split percentage: 100, label: :with_middleware do
181
+ # use middleware2
182
+ # split percentage: 100, label: :with_nested_middleware, url: downstream_url
183
+ # end
184
+ # end
185
+ # end
186
+ # proxy '/2' => downstream_url
187
+ # end
188
+ # end
189
+ #
190
+ # it 'adds it to that route only' do
191
+ # get('/1')
192
+ # expect(app.last_response.body.join).to eq('middleware1, middleware2, hello')
193
+ # get('/2')
194
+ # expect(app.last_response.body.join).to eq('middleware1, hello')
195
+ # end
196
+ # end
197
+ # end
20
198
  end
@@ -41,7 +41,7 @@ class SiteHub
41
41
  end
42
42
  end
43
43
 
44
- context 'no version explicitly defined' do
44
+ context 'url specified' do
45
45
  let(:expected_route) do
46
46
  proxy = ForwardProxy.new(mapped_path: mapped_path, mapped_url: :url)
47
47
  route(proxy, id: :default)
@@ -50,7 +50,7 @@ class SiteHub
50
50
  it 'adds a default proxy for the given mapping' do
51
51
  subject.add_route(url: :url, mapped_path: mapped_path)
52
52
  route = subject[mapped_path]
53
- expect(route.default_proxy).to eq(expected_route)
53
+ expect(route.default_route).to eq(expected_route)
54
54
  end
55
55
  end
56
56
  end
@@ -69,7 +69,7 @@ class SiteHub
69
69
  context 'mapped_route found' do
70
70
  it 'uses the forward proxy' do
71
71
  subject
72
- expect(forward_proxy_builder.endpoints[:current]).to receive(:call) do
72
+ expect(forward_proxy_builder.routes[:current]).to receive(:call) do
73
73
  [200, {}, []]
74
74
  end
75
75
  expect(get(mapped_path).status).to eq(200)
@@ -87,11 +87,17 @@ class SiteHub
87
87
  describe '#mapped_route' do
88
88
  let(:request) { Rack::Request.new({}) }
89
89
 
90
- it 'uses the id in the sitehub_cookie to resolve the correct route' do
90
+ before do
91
91
  subject.sitehub_cookie_name :cookie_name
92
+ subject.add_route mapped_path: mapped_path do
93
+ route label: :preset_id, url: :url
94
+ end
95
+ end
96
+
97
+ it 'uses the id in the sitehub_cookie to resolve the correct route' do
92
98
  request.cookies[:cookie_name] = :preset_id
93
99
  expect(forward_proxy_builder).to receive(:resolve).with(id: :preset_id, env: request.env).and_call_original
94
- subject.mapped_proxy(path: mapped_path, request: request)
100
+ subject.mapped_route(path: mapped_path, request: request)
95
101
  end
96
102
 
97
103
  context 'regex match on path' do
@@ -106,7 +112,7 @@ class SiteHub
106
112
  end
107
113
 
108
114
  it 'matches and subsitutes the captured group' do
109
- mapped_endpoint = subject.mapped_proxy(path: "#{mapped_path}/123/view", request: request)
115
+ mapped_endpoint = subject.mapped_route(path: "#{mapped_path}/123/view", request: request)
110
116
  expected_endpoint = fuzzy_matcher.resolve(env: {})
111
117
  expect(mapped_endpoint).to eq(expected_endpoint)
112
118
  end
@@ -114,7 +120,7 @@ class SiteHub
114
120
 
115
121
  context 'exact match on path' do
116
122
  it 'proxies to the requested path' do
117
- mapped_endpoint = subject.mapped_proxy(path: mapped_path, request: request)
123
+ mapped_endpoint = subject.mapped_route(path: mapped_path, request: request)
118
124
  expected_endpoint = forward_proxy_builder.resolve(env: {})
119
125
  expect(mapped_endpoint).to eq(expected_endpoint)
120
126
  end
@@ -134,7 +140,7 @@ class SiteHub
134
140
 
135
141
  it 'matches the first endpoint' do
136
142
  expected_endpoint = more_specific_proxy_builder.resolve(env: {})
137
- mapped_endpoint = subject.mapped_proxy(path: "#{mapped_path}/sub_url", request: request)
143
+ mapped_endpoint = subject.mapped_route(path: "#{mapped_path}/sub_url", request: request)
138
144
  expect(mapped_endpoint).to eq(expected_endpoint)
139
145
  end
140
146
  end
@@ -9,7 +9,7 @@ class SiteHub
9
9
  include_context :sitehub_json
10
10
 
11
11
  subject do
12
- described_class.from_hash(proxy_1, :expected).endpoints[route_1[:label]]
12
+ described_class.from_hash(proxy_1, :expected).routes[route_1[:label]]
13
13
  end
14
14
 
15
15
  context 'splits' do
@@ -49,22 +49,57 @@ class SiteHub
49
49
  mapped_path: '/path')
50
50
  end
51
51
 
52
+ describe '#routes' do
53
+ it 'returns RouteCollection by default' do
54
+ expect(subject.routes).to be_a(Collection::RouteCollection)
55
+ end
56
+
57
+ it 'returns the same intance everytime' do
58
+ collection = Collection::SplitRouteCollection.new
59
+ subject.routes(collection)
60
+ expect(subject.routes).to be(collection)
61
+ end
62
+
63
+ context 'endpoints already set' do
64
+ context 'different object supplied' do
65
+ it 'raises an error' do
66
+ subject.routes(Collection::SplitRouteCollection.new)
67
+ expect { subject.routes(Collection::RouteCollection.new) }
68
+ .to raise_error(RouteBuilder::InvalidDefinitionException)
69
+ end
70
+ end
71
+ end
72
+ end
73
+
52
74
  it 'supports middleware' do
53
75
  expect(described_class).to include(Middleware)
54
76
  end
55
77
 
56
78
  describe '#initialize' do
79
+ let(:named_parameters) do
80
+ { sitehub_cookie_name: :name,
81
+ mapped_path: '/path' }
82
+ end
83
+
57
84
  context 'with a block' do
58
85
  it 'evaluates the block in the context of the instance' do
59
86
  self_inside_block = nil
60
- instance = described_class.new(sitehub_cookie_name: :name,
61
- mapped_path: '/path') do
87
+ instance = described_class.new(named_parameters) do
62
88
  self_inside_block = self
63
89
  default(url: :url)
64
90
  end
65
91
  expect(self_inside_block).to eq(instance)
66
92
  end
67
93
  end
94
+
95
+ context 'id' do
96
+ context 'id supplied' do
97
+ it 'sets the id using it' do
98
+ subject = described_class.new(named_parameters.merge(id: :custom_id))
99
+ expect(subject.id).to eq(:custom_id)
100
+ end
101
+ end
102
+ end
68
103
  end
69
104
 
70
105
  describe 'valid?' do
@@ -104,86 +139,22 @@ class SiteHub
104
139
  end
105
140
 
106
141
  describe '#split' do
107
- context 'duplicate label used' do
108
- it 'raises an error' do
109
- subject.split percentage: 10, url: :url, label: :label
110
-
111
- expect { subject.split percentage: 10, url: :url, label: :label }
112
- .to raise_exception(Collection::DuplicateVersionException, 'supply unique labels')
113
- end
142
+ it 'setups up a splits collection' do
143
+ subject.split percentage: 10, url: :url, label: :label
144
+ expect(subject.routes).to be_a(Collection::SplitRouteCollection)
114
145
  end
146
+ end
115
147
 
116
- context 'split supplied' do
117
- let(:block) do
118
- proc do
119
- default url: :url
120
- end
121
- end
122
-
123
- context 'url' do
124
- it 'gives a warning to say that the url will not be used' do
125
- expect(subject).to receive(:warn).with(described_class::IGNORING_URL_LABEL_MSG)
126
- subject.split(percentage: 50, url: :url, &block)
127
- end
128
- end
129
-
130
- context 'label' do
131
- it 'gives a warning to say that the url will not be used' do
132
- expect(subject).to receive(:warn).with(described_class::IGNORING_URL_LABEL_MSG)
133
- subject.split(percentage: 50, label: :label, &block)
134
- end
135
- end
136
-
137
- context 'block supplied' do
138
- it 'stores a forward proxy builder' do
139
- subject.split(percentage: 50, &block)
140
-
141
- expected_builder = described_class.new(sitehub_cookie_name: :cookie_name,
142
- mapped_path: subject.mapped_path, &block).build # sitehub_cookie_name: subject.sitehub_cookie_name
143
- expected_split = SiteHub::Collection::SplitRouteCollection::Split.new(0, 50, expected_builder)
144
- expect(subject.endpoints.values).to eq([expected_split])
145
- end
146
- end
147
- end
148
-
149
- context 'block not supplied' do
150
- it 'stores a split for the version' do
151
- subject.split url: :url, label: :label, percentage: 50
152
-
153
- proxy = ForwardProxy.new(mapped_url: :url,
154
- mapped_path: subject.mapped_path)
155
-
156
- expected_route = Route.new(proxy,
157
- id: :label,
158
- sitehub_cookie_name: :cookie_name,
159
- sitehub_cookie_path: nil)
160
-
161
- expected = Collection::SplitRouteCollection.new(expected_route => 50)
162
-
163
- expect(subject.endpoints).to eq(expected)
164
- end
165
-
166
- context 'url not supplied' do
167
- it 'raises an error' do
168
- expect { subject.split(label: :label, percentage: 50) }
169
- .to raise_error(RouteBuilder::InvalidDefinitionException)
170
- end
171
- end
172
- end
173
-
174
- context 'routes defined' do
175
- it 'throws and error' do
176
- subject.route url: :url, label: :label
177
-
178
- expect { subject.split(url: :url, label: :label, percentage: 50) }
179
- .to raise_error(RouteBuilder::InvalidDefinitionException)
180
- end
148
+ describe '#route' do
149
+ it 'sets up the routes collection' do
150
+ subject.route url: :url, label: :current
151
+ expect(subject.routes).to be_a(Collection::RouteCollection)
181
152
  end
182
153
  end
183
154
 
184
- describe '#route' do
185
- it 'accepts a rule' do
186
- subject.route url: :url, label: :current, rule: :rule
155
+ describe '#add_endpoint' do
156
+ it 'stores the route against the given label' do
157
+ subject.add_route url: :url, label: :current
187
158
 
188
159
  proxy = ForwardProxy.new(mapped_url: :url,
189
160
  mapped_path: subject.mapped_path)
@@ -191,60 +162,80 @@ class SiteHub
191
162
  expected_route = Route.new(proxy,
192
163
  id: :current,
193
164
  sitehub_cookie_name: :cookie_name,
194
- sitehub_cookie_path: nil).tap do |route|
195
- route.rule(:rule)
196
- end
197
- expect(subject.endpoints).to eq(current: expected_route)
165
+ sitehub_cookie_path: nil)
166
+
167
+ expect(subject.routes[:current]).to eq(expected_route)
168
+ end
169
+
170
+ it 'accepts a rule' do
171
+ endpoint = subject.add_route url: :url, label: :current, rule: :rule
172
+ expect(endpoint.rule).to eq(:rule)
173
+ end
174
+
175
+ it 'accepts a percentage' do
176
+ subject.routes(Collection::SplitRouteCollection.new)
177
+ endpoint = subject.add_route url: :url, label: :current, percentage: 50
178
+ expect(endpoint.upper).to eq(50)
198
179
  end
199
180
 
200
181
  context 'block supplied' do
201
182
  let(:block) do
202
183
  proc do
203
- route url: :url, label: :label1
184
+ route url: :url, label: :label2, rule: :rule do
185
+ route url: :url, label: :label3
186
+ end
204
187
  end
205
188
  end
206
189
 
190
+ it 'stores the nested route_builder against the label' do
191
+ rule = proc { true }
192
+ subject.add_route(rule: rule, label: :label1, &block)
193
+ subject.use middleware
194
+
195
+ expected_endpoints = RouteBuilder.new(rule: rule,
196
+ id: :label1,
197
+ sitehub_cookie_name: :cookie_name,
198
+ mapped_path: '/path',
199
+ &block).build
200
+
201
+ expect(subject.routes[:label1]).to eq(expected_endpoints)
202
+ subject.build
203
+ end
204
+
207
205
  describe '#errors and warnings' do
208
- context 'rule not supplied' do
206
+ context 'precentage and rule not supplied' do
209
207
  it 'raise an error' do
210
- expected_message = described_class::INVALID_ROUTE_DEF_MSG
211
- expect { subject.route {} }
208
+ expected_message = described_class::RULE_NOT_SPECIFIED_MSG
209
+ expect { subject.add_route(label: :label) {} }
212
210
  .to raise_exception described_class::InvalidDefinitionException, expected_message
213
211
  end
214
212
  end
215
213
 
216
214
  context 'url' do
217
215
  it 'gives a warning to say that the url will not be used' do
218
- expect(subject).to receive(:warn).with(described_class::IGNORING_URL_LABEL_MSG)
219
- subject.route(rule: :rule, url: :url, &block)
220
- end
221
- end
222
-
223
- context 'label' do
224
- it 'gives a warning to say that the url will not be used' do
225
- expect(subject).to receive(:warn).with(described_class::IGNORING_URL_LABEL_MSG)
226
- subject.route(rule: :rule, label: :label, &block)
216
+ expect(subject).to receive(:warn).with(described_class::IGNORING_URL_MSG)
217
+ subject.add_route(rule: :rule, url: :url, label: :label, &block)
227
218
  end
228
219
  end
229
220
  end
230
221
 
231
222
  it 'stores a proxy builder' do
232
223
  rule = proc { true }
233
- subject.route(rule: rule, &block)
224
+ subject.add_route(rule: rule, label: :label, &block)
234
225
 
235
- expected_builder = described_class.new(sitehub_cookie_name: :cookie_name,
236
- rule: rule, mapped_path: subject.mapped_path, &block).tap do |builder|
226
+ expected_endpoints = described_class.new(id: :label, sitehub_cookie_name: :cookie_name,
227
+ rule: rule, mapped_path: subject.mapped_path, &block).tap do |builder|
237
228
  builder.sitehub_cookie_name subject.sitehub_cookie_name
238
229
  end.build
239
230
 
240
- expect(subject.endpoints.values).to eq([expected_builder])
231
+ expect(subject.routes.values).to eq([expected_endpoints])
241
232
  end
242
233
 
243
234
  context 'invalid definitions inside block' do
244
235
  it 'raises an error' do
245
236
  rule = proc { true }
246
237
  expect do
247
- subject.route rule: rule do
238
+ subject.add_route rule: rule, label: :label do
248
239
  split percentage: 20, url: :url, label: :label1
249
240
  end
250
241
  end.to raise_exception described_class::InvalidDefinitionException
@@ -259,9 +250,9 @@ class SiteHub
259
250
  context 'middleware not specified' do
260
251
  it 'leaves it the proxies alone' do
261
252
  subject.route url: :url, label: :current
262
- expect(subject.endpoints[:current]).to be_using_rack_stack(ForwardProxy)
253
+ expect(subject.routes[:current]).to be_using_rack_stack(ForwardProxy)
263
254
  subject.build
264
- expect(subject.endpoints[:current]).to be_using_rack_stack(ForwardProxy)
255
+ expect(subject.routes[:current]).to be_using_rack_stack(ForwardProxy)
265
256
  end
266
257
  end
267
258
 
@@ -273,79 +264,77 @@ class SiteHub
273
264
  it 'wraps the forward proxies in the middleware' do
274
265
  subject.route url: :url, label: :current
275
266
  subject.build
276
- expect(subject.endpoints[:current]).to be_using_rack_stack(middleware, ForwardProxy)
267
+ expect(subject.routes[:current]).to be_using_rack_stack(middleware, ForwardProxy)
277
268
  end
278
269
 
279
270
  it 'wraps the default in the middleware' do
280
271
  subject.default url: :url
281
272
  subject.build
282
- expect(subject.default_proxy).to be_using_rack_stack(middleware, ForwardProxy)
273
+ expect(subject.default_route).to be_using_rack_stack(middleware, ForwardProxy)
274
+ end
275
+
276
+ context 'nested routes' do
277
+ pending 'what should it do?'
283
278
  end
284
279
  end
285
280
  end
286
281
 
287
282
  describe '#resolve' do
288
- subject do
289
- described_class.new(sitehub_cookie_name: :cookie_name,
290
- mapped_path: '/')
291
- end
292
-
293
- context 'routes defined' do
294
- it 'returns that route' do
295
- subject.route url: :url, label: :current
296
- expect(subject.resolve(env: {})).to eq(subject.endpoints.values.first)
297
- end
298
-
299
- it 'passes the env to the when resolving the correct route' do
300
- expect_any_instance_of(subject.endpoints.class).to receive(:resolve).with(id: :'', env: :env).and_call_original
301
- subject.resolve(env: :env)
302
- end
303
-
304
- it 'passes the requested route id when resolving the correct route' do
305
- expect_any_instance_of(subject.endpoints.class).to receive(:resolve).with(id: :required_route_id, env: :env).and_call_original
306
- subject.resolve(id: :required_route_id, env: :env)
307
- end
308
- end
283
+ context 'id not supplied' do
284
+ context 'routes defined' do
285
+ it 'returns that route' do
286
+ subject.route url: :url, label: :current
287
+ expect(subject.resolve(env: {})).to eq(subject.routes.values.first)
288
+ end
309
289
 
310
- context 'splits defined' do
311
- it 'serves an entry from the routes' do
312
- subject.split(percentage: 100, url: :url, label: :label)
313
- expect(subject.endpoints).to receive(:resolve).and_return(:pick)
314
- expect(subject.resolve(env: {})).to eq(:pick)
290
+ it 'passes the env to the when resolving the correct route' do
291
+ expect_any_instance_of(subject.routes.class).to receive(:resolve).with(env: :env).and_call_original
292
+ subject.resolve(env: :env)
293
+ end
315
294
  end
316
295
 
317
296
  context 'splits not defined' do
318
297
  it 'returns the default' do
319
298
  subject.default url: :url
320
- expect(subject.resolve(env: {})).to eq(subject.default_proxy)
299
+ expect(subject.resolve(env: {})).to eq(subject.default_route)
321
300
  end
322
301
  end
323
302
  end
324
303
 
325
- context 'version selected' do
326
- context 'version applies to a route' do
327
- before do
328
- subject.split percentage: 50, url: :url1, label: :new
329
- subject.split percentage: 50, url: :url2, label: :old
304
+ context 'id supplied' do
305
+ context 'nested routes' do
306
+ let!(:expected) do
307
+ result = nil
308
+ subject.split percentage: 0, label: :experiment1 do
309
+ result = split percentage: 100, url: :url1, label: :new
310
+ end
311
+ subject.split percentage: 100, label: :experiment2, url: :url
312
+ result.value
330
313
  end
331
314
 
332
- let(:application_version1) do
333
- subject.endpoints.values.find do |pick|
334
- pick.value.id == :new
335
- end.value
315
+ it 'returns that route' do
316
+ expect(subject.resolve(id: expected.id, env: {})).to eq(expected)
336
317
  end
318
+ end
337
319
 
338
- context 'string supplied' do
339
- it 'redirects to that version' do
340
- expect(subject.resolve(id: :new.to_s, env: {})).to eq(application_version1)
341
- end
320
+ context 'id does not exist' do
321
+ let!(:expected) do
322
+ subject.default url: :url
323
+ subject.default_route
342
324
  end
343
325
 
344
- context 'symbol supplied' do
345
- it 'redirects to that version' do
346
- expect(subject).to_not receive(:auto_resolve)
347
- expect(subject.resolve(id: :new, env: {})).to eq(application_version1)
348
- end
326
+ it 'returns the default route' do
327
+ expect(subject.resolve(id: :missing, env: {})).to eq(expected)
328
+ end
329
+ end
330
+
331
+ context 'non nested route' do
332
+ let!(:expected) do
333
+ subject.split(percentage: 100, label: :experiment1, url: :url).value
334
+ end
335
+
336
+ it 'returns that route' do
337
+ expect(subject.resolve(id: expected.id, env: {})).to eq(expected)
349
338
  end
350
339
  end
351
340
  end
@@ -354,15 +343,15 @@ class SiteHub
354
343
  context '#endpoints' do
355
344
  context 'called with a collection' do
356
345
  it 'sets endpoints to be that collection' do
357
- subject.endpoints(:collection)
358
- expect(subject.endpoints).to eq(:collection)
346
+ subject.routes(:collection)
347
+ expect(subject.routes).to eq(:collection)
359
348
  end
360
349
  end
361
350
 
362
351
  context 'already set with a different collection' do
363
352
  it 'raise an error' do
364
- subject.endpoints(:collection1)
365
- expect { subject.endpoints(:collection2) }.to raise_exception described_class::InvalidDefinitionException
353
+ subject.routes(:collection1)
354
+ expect { subject.routes(:collection2) }.to raise_exception described_class::InvalidDefinitionException
366
355
  end
367
356
  end
368
357
  end