heroics 0.0.17 → 0.0.18

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.
@@ -1,221 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'minitest/autorun'
3
- require 'time'
4
-
5
- require 'heroics'
6
-
7
- module ExconHelper
8
- def setup
9
- super
10
- Excon.stubs.clear
11
- Excon.defaults[:mock] = true
12
- end
13
-
14
- def teardown
15
- # FIXME This is a bit ugly, but Excon doesn't provide a builtin way to
16
- # ensure that a request was invoked, so we have to do it ourselves.
17
- # Without this, and the Excon.stubs.pop calls in the tests that use this
18
- # helper, tests will pass if request logic is completely removed from
19
- # application code. -jkakar
20
- assert(Excon.stubs.empty?, 'Expected HTTP requests were not made.')
21
- super
22
- end
23
- end
24
-
25
- # A simple JSON schema for testing purposes.
26
- SAMPLE_SCHEMA = {
27
- 'description' => 'Sample schema for use in tests.',
28
- 'definitions' => {
29
- 'resource' => {
30
- 'description' => 'A sample resource to use in tests.',
31
- 'id' => 'schema/resource',
32
- '$schema' => 'http://json-schema.org/draft-04/hyper-schema',
33
- 'title' => 'Sample resource title',
34
- 'type' => ['object'],
35
-
36
- 'definitions' => {
37
- 'date_field' => {
38
- 'description' => 'A sample date field',
39
- 'example' => '2013-10-19 22:10:29Z',
40
- 'format' => 'date-time',
41
- 'readOnly' => true,
42
- 'type' => ['string']
43
- },
44
-
45
- 'string_field' => {
46
- 'description' => 'A sample string field',
47
- 'example' => 'Sample text.',
48
- 'readOnly' => true,
49
- 'type' => ['string']
50
- },
51
-
52
- 'boolean_field' => {
53
- 'description' => 'A sample boolean field',
54
- 'example' => true,
55
- 'type' => ['boolean']
56
- },
57
-
58
- 'uuid_field' => {
59
- 'description' => 'A sample UUID field',
60
- 'example' => '44724831-bf66-4bc2-865f-e2c4c2b14c78',
61
- 'format' => 'uuid',
62
- 'readOnly' => true,
63
- 'type' => ['string']
64
- },
65
-
66
- 'email_field' => {
67
- 'description' => 'A sample email address field',
68
- 'example' => 'username@example.com',
69
- 'format' => 'email',
70
- 'readOnly' => true,
71
- 'type' => ['string']
72
- },
73
-
74
- 'identity' => {
75
- 'oneOf' => [
76
- {'$ref' => '#/definitions/resource/definitions/uuid_field'},
77
- {'$ref' => '#/definitions/resource/definitions/email_field'}]
78
- }
79
- },
80
-
81
- 'properties' => {
82
- 'date_field' => {
83
- '$ref' => '#/definitions/resource/definitions/date_field'},
84
- 'string_field' => {
85
- '$ref' => '#/definitions/resource/definitions/string_field'},
86
- 'boolean_field' => {
87
- '$ref' => '#/definitions/resource/definitions/boolean_field'},
88
- 'uuid_field' => {
89
- '$ref' => '#/definitions/resource/definitions/uuid_field'},
90
- 'email_field' => {
91
- '$ref' => '#/definitions/resource/definitions/email_field'},
92
- },
93
-
94
- 'links' => [
95
- {'description' => 'Show all sample resources',
96
- 'href' => '/resource',
97
- 'method' => 'GET',
98
- 'rel' => 'instances',
99
- 'title' => 'List'},
100
-
101
- {'description' => 'Show a sample resource',
102
- 'href' => '/resource/{(%23%2Fdefinitions%2Fresource%2Fdefinitions%2Fuuid_field)}',
103
- 'method' => 'GET',
104
- 'rel' => 'self',
105
- 'title' => 'Info'},
106
-
107
- {'description' => 'Show a sample resource',
108
- 'href' => '/resource/{(%23%2Fdefinitions%2Fresource%2Fdefinitions%2Fidentity)}',
109
- 'method' => 'GET',
110
- 'rel' => 'self',
111
- 'title' => 'Identify resource'},
112
-
113
- {'description' => 'Create a sample resource',
114
- 'href' => '/resource',
115
- 'method' => 'POST',
116
- 'rel' => 'create',
117
- 'title' => 'Create',
118
- 'schema' => {
119
- 'properties' => {
120
- 'date_field' => {
121
- '$ref' => '#/definitions/resource/definitions/date_field'},
122
- 'string_field' => {
123
- '$ref' => '#/definitions/resource/definitions/string_field'},
124
- 'boolean_field' => {
125
- '$ref' => '#/definitions/resource/definitions/boolean_field'},
126
- 'uuid_field' => {
127
- '$ref' => '#/definitions/resource/definitions/uuid_field'},
128
- 'email_field' => {
129
- '$ref' => '#/definitions/resource/definitions/email_field'}}}},
130
-
131
- {'description' => 'Submit a sample resource as form data',
132
- 'encType' => 'application/x-www-form-urlencoded',
133
- 'href' => '/resource',
134
- 'method' => 'POST',
135
- 'rel' => 'submit',
136
- 'title' => 'Submit',
137
- 'schema' => {
138
- 'properties' => {
139
- 'date_field' => {
140
- '$ref' => '#/definitions/resource/definitions/date_field'},
141
- 'string_field' => {
142
- '$ref' => '#/definitions/resource/definitions/string_field'},
143
- 'boolean_field' => {
144
- '$ref' => '#/definitions/resource/definitions/boolean_field'},
145
- 'uuid_field' => {
146
- '$ref' => '#/definitions/resource/definitions/uuid_field'},
147
- 'email_field' => {
148
- '$ref' => '#/definitions/resource/definitions/email_field'}}}},
149
-
150
- {'description' => 'Update a sample resource',
151
- 'href' => '/resource/{(%23%2Fdefinitions%2Fresource%2Fdefinitions%2Fuuid_field)}',
152
- 'method' => 'PATCH',
153
- 'rel' => 'update',
154
- 'title' => 'Update',
155
- 'schema' => {
156
- 'properties' => {
157
- 'date_field' => {
158
- '$ref' => '#/definitions/resource/definitions/date_field'},
159
- 'string_field' => {
160
- '$ref' => '#/definitions/resource/definitions/string_field'},
161
- 'boolean_field' => {
162
- '$ref' => '#/definitions/resource/definitions/boolean_field'},
163
- 'uuid_field' => {
164
- '$ref' => '#/definitions/resource/definitions/uuid_field'},
165
- 'email_field' => {
166
- '$ref' => '#/definitions/resource/definitions/email_field'}}}},
167
-
168
- {'description' => 'Delete an existing sample resource at specific time',
169
- 'href' => '/resource/{(%23%2Fdefinitions%2Fresource%2Fdefinitions%2Fdate_field)}',
170
- 'method' => 'DELETE',
171
- 'rel' => 'destroy',
172
- 'title' => 'Delete'}
173
- ]
174
- },
175
-
176
- 'another-resource' => {
177
- 'description' => 'Another sample resource to use in tests.',
178
- 'id' => 'schema/another-resource',
179
- '$schema' => 'http://json-schema.org/draft-04/hyper-schema',
180
- 'title' => 'Another sample resource title',
181
- 'type' => ['object'],
182
-
183
- 'definitions' => {},
184
-
185
- 'properties' => {},
186
-
187
- 'links' => [
188
- {'description' => 'Show all sample resources',
189
- 'href' => '/another-resource',
190
- 'method' => 'GET',
191
- 'rel' => 'instances',
192
- 'title' => 'List'}
193
- ]
194
- },
195
-
196
- 'underscored_resource' => {
197
- 'description' => 'Underscores the importance of supporting underscored resources',
198
- 'id' => 'schema/underscored_resource',
199
- '$schema' => 'http://json-schema.org/draft-04/hyper-schema',
200
- 'title' => 'Another underscored resource to use in tests',
201
- 'type' => ['object'],
202
-
203
- 'definitions' => {},
204
-
205
- 'properties' => {},
206
-
207
- 'links' => [
208
- {'description' => 'Show all underscored resources',
209
- 'href' => '/underscored_resource',
210
- 'method' => 'GET',
211
- 'rel' => 'instances',
212
- 'title' => 'List'}
213
- ]
214
- },
215
- },
216
- 'properties' => {
217
- 'resource' => { '$ref' => '#/definitions/resource' },
218
- 'another-resource' => { '$ref' => '#/definitions/another-resource' },
219
- 'underscored_resource' => { '$ref' => '#/definitions/underscored_resource' }
220
- }
221
- }
@@ -1,444 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'helper'
3
-
4
- class LinkTest < MiniTest::Unit::TestCase
5
- include ExconHelper
6
-
7
- # Link.run invokes a request against the service identified by the URL. The
8
- # path is left unchanged when parameters aren't required and the username
9
- # and password from the URL are passed using HTTP basic auth.
10
- def test_run_without_parameters_and_with_empty_response
11
- Excon.stub(method: :get) do |request|
12
- assert_equal('Basic dXNlcm5hbWU6c2VjcmV0',
13
- request[:headers]['Authorization'])
14
- assert_equal('example.com', request[:host])
15
- assert_equal(443, request[:port])
16
- assert_equal('/resource', request[:path])
17
- Excon.stubs.pop
18
- {status: 200, body: ''}
19
- end
20
-
21
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
22
- link = Heroics::Link.new('https://username:secret@example.com',
23
- schema.resource('resource').link('list'))
24
- assert_equal(nil, link.run)
25
- end
26
-
27
- # Link.run injects parameters into the path in the order they were received.
28
- def test_run_with_parameters_and_empty_response
29
- Excon.stub(method: :get) do |request|
30
- assert_equal('/resource/44724831-bf66-4bc2-865f-e2c4c2b14c78',
31
- request[:path])
32
- Excon.stubs.pop
33
- {status: 200, body: ''}
34
- end
35
-
36
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
37
- link = Heroics::Link.new('https://example.com',
38
- schema.resource('resource').link('info'))
39
- assert_equal(nil, link.run('44724831-bf66-4bc2-865f-e2c4c2b14c78'))
40
- end
41
-
42
- # Link.run URL-escapes special characters in parameters.
43
- def test_run_with_parameters_needing_escaping
44
- Excon.stub(method: :get) do |request|
45
- assert_equal('/resource/foo%23bar', request[:path])
46
- Excon.stubs.pop
47
- {status: 200, body: ''}
48
- end
49
-
50
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
51
- link = Heroics::Link.new('https://example.com',
52
- schema.resource('resource').link('info'))
53
- assert_equal(nil, link.run('foo#bar'))
54
- end
55
-
56
- # Link.run converts Time parameters to UTC before sending them to the
57
- # server.
58
- def test_run_converts_time_parameters_to_utc
59
- Excon.stub(method: :delete) do |request|
60
- assert_equal("/resource/2013-01-01T08:00:00Z", request[:path])
61
- Excon.stubs.pop
62
- {status: 200, body: ''}
63
- end
64
-
65
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
66
- link = Heroics::Link.new('https://example.com',
67
- schema.resource('resource').link('delete'))
68
- assert_equal(nil, link.run(Time.parse('2013-01-01 00:00:00-0800')))
69
- end
70
-
71
- # Link.run optionally takes an extra parameter to send in the request body.
72
- # It automatically converts the specified object to JSON and includes a
73
- # Content-Type header in the request.
74
- def test_run_without_parameters_and_with_request_body
75
- body = {'Hello' => 'world!'}
76
- Excon.stub(method: :post) do |request|
77
- assert_equal('application/json', request[:headers]['Content-Type'])
78
- assert_equal(body, MultiJson.load(request[:body]))
79
- Excon.stubs.pop
80
- {status: 200, body: ''}
81
- end
82
-
83
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
84
- link = Heroics::Link.new('https://example.com',
85
- schema.resource('resource').link('create'))
86
- assert_equal(nil, link.run(body))
87
- end
88
-
89
- # Link.run optionally takes an extra parameter to send in the request body.
90
- # It automatically converts the specified object to the specified encoding
91
- # type and includes a Content-Type header in the request
92
- def test_run_without_parameters_and_with_non_json_request_body
93
- body = {'Hello' => 'world!'}
94
- Excon.stub(method: :post) do |request|
95
- assert_equal('application/x-www-form-urlencoded', request[:headers]['Content-Type'])
96
- assert_equal('Hello=world%21', request[:body])
97
- Excon.stubs.pop
98
- {status: 200, body: ''}
99
- end
100
-
101
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
102
- link = Heroics::Link.new('https://example.com',
103
- schema.resource('resource').link('submit'))
104
- assert_equal(nil, link.run(body))
105
- end
106
-
107
-
108
- # Link.run passes custom headers to the server when they've been provided.
109
- def test_run_with_custom_request_headers
110
- Excon.stub(method: :get) do |request|
111
- assert_equal('application/vnd.heroku+json; version=3',
112
- request[:headers]['Accept'])
113
- Excon.stubs.pop
114
- {status: 200}
115
- end
116
-
117
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
118
- link = Heroics::Link.new(
119
- 'https://example.com', schema.resource('resource').link('list'),
120
- {default_headers: {'Accept' => 'application/vnd.heroku+json; version=3'}})
121
- assert_equal(nil, link.run())
122
- end
123
-
124
- # Link.run passes custom headers to the server when they've been provided.
125
- # It merges in the Content-Type when a body is included in the request.
126
- def test_run_with_custom_request_headers_and_with_request_body
127
- body = {'Hello' => 'world!'}
128
- Excon.stub(method: :post) do |request|
129
- assert_equal('application/json', request[:headers]['Content-Type'])
130
- assert_equal('application/vnd.heroku+json; version=3',
131
- request[:headers]['Accept'])
132
- assert_equal(body, MultiJson.load(request[:body]))
133
- Excon.stubs.pop
134
- {status: 200}
135
- end
136
-
137
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
138
- link = Heroics::Link.new(
139
- 'https://example.com', schema.resource('resource').link('create'),
140
- default_headers: {'Accept' => 'application/vnd.heroku+json; version=3'})
141
- assert_equal(nil, link.run(body))
142
- end
143
-
144
- # Link.run doesn't mutate the default headers.
145
- def test_run_never_overwrites_default_headers
146
- body = {'Hello' => 'world!'}
147
- Excon.stub(method: :post) do |request|
148
- assert_equal('application/json', request[:headers]['Content-Type'])
149
- assert_equal('application/vnd.heroku+json; version=3',
150
- request[:headers]['Accept'])
151
- assert_equal(body, MultiJson.load(request[:body]))
152
- Excon.stubs.pop
153
- {status: 200}
154
- end
155
-
156
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
157
- link = Heroics::Link.new(
158
- 'https://example.com', schema.resource('resource').link('create'),
159
- {default_headers: {'Accept' => 'application/vnd.heroku+json; version=3'}})
160
- assert_equal(nil, link.run(body))
161
-
162
- # The second time we use the link, without providing a request body, the
163
- # Content-Type set during the first run is not present, as expected.
164
- Excon.stub(method: :post) do |request|
165
- assert_equal(nil, request[:headers]['Content-Type'])
166
- assert_equal('application/vnd.heroku+json; version=3',
167
- request[:headers]['Accept'])
168
- Excon.stubs.pop
169
- {status: 200}
170
- end
171
- assert_equal(nil, link.run)
172
- end
173
-
174
- # Link.run returns text responses sent by the server without processing them
175
- # in any way.
176
- def test_run_with_text_response
177
- Excon.stub(method: :get) do |request|
178
- assert_equal('/resource', request[:path])
179
- Excon.stubs.pop
180
- {status: 200, headers: {'Content-Type' => 'application/text'},
181
- body: "Hello, world!\r\n"}
182
- end
183
-
184
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
185
- link = Heroics::Link.new('https://example.com',
186
- schema.resource('resource').link('list'))
187
- assert_equal("Hello, world!\r\n", link.run)
188
- end
189
-
190
- # Link.run automatically decodes JSON responses sent by the server into Ruby
191
- # objects.
192
- def test_run_with_json_response
193
- body = {'Hello' => 'World!'}
194
- Excon.stub(method: :post) do |request|
195
- assert_equal('/resource', request[:path])
196
- Excon.stubs.pop
197
- {status: 201, headers: {'Content-Type' => 'application/json'},
198
- body: MultiJson.dump(body)}
199
- end
200
-
201
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
202
- link = Heroics::Link.new('https://example.com',
203
- schema.resource('resource').link('create'))
204
- assert_equal(body, link.run)
205
- end
206
-
207
- # Link.run automatically decodes JSON responses with a complex Content-Type
208
- # header sent by the server into Ruby objects.
209
- def test_run_with_json_response_and_complex_content_type
210
- body = {'Hello' => 'World!'}
211
- Excon.stub(method: :get) do |request|
212
- assert_equal('/resource', request[:path])
213
- Excon.stubs.pop
214
- {status: 200,
215
- headers: {'Content-Type' => 'application/vnd.api+json;charset=utf-8'},
216
- body: MultiJson.dump(body)}
217
- end
218
-
219
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
220
- link = Heroics::Link.new('https://example.com',
221
- schema.resource('resource').link('list'))
222
- assert_equal(body, link.run)
223
- end
224
-
225
- # Link.run considers HTTP 202 Accepted responses as successful.
226
- def test_run_with_accepted_request
227
- body = {'Hello' => 'World!'}
228
- Excon.stub(method: :post) do |request|
229
- assert_equal('/resource', request[:path])
230
- Excon.stubs.pop
231
- {status: 202, headers: {'Content-Type' => 'application/json'},
232
- body: MultiJson.dump(body)}
233
- end
234
-
235
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
236
- link = Heroics::Link.new('https://example.com',
237
- schema.resource('resource').link('create'))
238
- assert_equal(body, link.run)
239
- end
240
-
241
- # Link.run considers HTTP 204 No Content responses as successful.
242
- def test_run_with_no_content_response
243
- Excon.stub(method: :delete) do |request|
244
- assert_equal("/resource/2013-01-01T08:00:00Z", request[:path])
245
- Excon.stubs.pop
246
- {status: 204, body: ''}
247
- end
248
-
249
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
250
- link = Heroics::Link.new('https://example.com',
251
- schema.resource('resource').link('delete'))
252
- assert_equal(nil, link.run(Time.parse('2013-01-01 00:00:00-0800')))
253
- end
254
-
255
- # Link.run raises an Excon error if anything other than a 200 or 201 HTTP
256
- # status code was returned by the server.
257
- def test_run_with_failed_request
258
- Excon.stub(method: :get) do |request|
259
- assert_equal('/resource', request[:path])
260
- Excon.stubs.pop
261
- {status: 400}
262
- end
263
-
264
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
265
- link = Heroics::Link.new('https://example.com',
266
- schema.resource('resource').link('list'))
267
- assert_raises Excon::Errors::BadRequest do
268
- link.run
269
- end
270
- end
271
-
272
- # Link.run raises an ArgumentError if too few parameters are provided.
273
- def test_run_with_missing_parameters
274
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
275
- link = Heroics::Link.new('https://example.com',
276
- schema.resource('resource').link('info'))
277
- error = assert_raises ArgumentError do
278
- link.run
279
- end
280
- assert_equal('wrong number of arguments (0 for 1)', error.message)
281
- end
282
-
283
- # Link.run raises an ArgumentError if too many parameters are provided.
284
- def test_run_with_too_many_parameters
285
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
286
- link = Heroics::Link.new('https://example.com',
287
- schema.resource('resource').link('info'))
288
- error = assert_raises ArgumentError do
289
- link.run('too', 'many', 'parameters')
290
- end
291
- assert_equal('wrong number of arguments (3 for 1)', error.message)
292
- end
293
-
294
- # Link.run passes ETags from the cache to the server with GET requests.
295
- def test_run_passes_cached_etags_in_get_requests
296
- Excon.stub(method: :get) do |request|
297
- assert_equal('etag-contents', request[:headers]['If-None-Match'])
298
- Excon.stubs.pop
299
- {status: 200}
300
- end
301
-
302
- headers = {}
303
- cache = Moneta.new(:Memory)
304
- cache["etag:/resource:#{headers.hash}"] = 'etag-contents'
305
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
306
- link = Heroics::Link.new('https://example.com',
307
- schema.resource('resource').link('list'),
308
- cache: cache)
309
- link.run
310
- end
311
-
312
- # Link.run will not pas ETags from the cache for non-GET requests.
313
- def test_run_ignores_etags_for_non_get_requests
314
- Excon.stub(method: :post) do |request|
315
- assert_equal(nil, request[:headers]['If-None-Match'])
316
- Excon.stubs.pop
317
- {status: 201}
318
- end
319
-
320
- cache = Moneta.new(:Memory)
321
- cache['etag:/resource:0'] = 'etag-contents'
322
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
323
- link = Heroics::Link.new('https://example.com',
324
- schema.resource('resource').link('create'),
325
- cache: cache)
326
- link.run({'Hello' => 'World'})
327
- end
328
-
329
- # Link.run returns JSON content loaded from the cache when a GET request
330
- # with an ETag yields a 304 Not Modified response.
331
- def test_run_returns_cached_json_content_for_not_modified_response
332
- body = {'Hello' => 'World!'}
333
- Excon.stub(method: :get) do |request|
334
- assert_equal('etag-contents', request[:headers]['If-None-Match'])
335
- Excon.stubs.pop
336
- {status: 304, headers: {'Content-Type' => 'application/json'}}
337
- end
338
-
339
- headers = {}
340
- cache = Moneta.new(:Memory)
341
- cache["etag:/resource:#{headers.hash}"] = 'etag-contents'
342
- cache["data:/resource:#{headers.hash}"] = MultiJson.dump(body)
343
- cache["status:/resource:#{headers.hash}"] = 200
344
- cache["headers:/resource:#{headers.hash}"] = {'Content-Type' => 'application/json'}
345
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
346
- link = Heroics::Link.new('https://example.com',
347
- schema.resource('resource').link('list'),
348
- cache: cache)
349
- assert_equal(body, link.run)
350
- end
351
-
352
- # Link.run caches JSON content received from the server when an ETag is
353
- # included in the response.
354
- def test_run_caches_json_body_when_an_etag_is_received
355
- body = {'Hello' => 'World!'}
356
- Excon.stub(method: :get) do |request|
357
- Excon.stubs.pop
358
- {status: 200, headers: {'Content-Type' => 'application/json',
359
- 'ETag' => 'etag-contents'},
360
- body: MultiJson.dump(body)}
361
- end
362
-
363
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
364
- link = Heroics::Link.new('https://example.com',
365
- schema.resource('resource').link('list'),
366
- cache: Moneta.new(:Memory))
367
- assert_equal(body, link.run)
368
-
369
- Excon.stub(method: :get) do |request|
370
- assert_equal('etag-contents', request[:headers]['If-None-Match'])
371
- Excon.stubs.pop
372
- {status: 304, headers: {'Content-Type' => 'application/json'}}
373
- end
374
- assert_equal(body, link.run)
375
- end
376
-
377
- # Link.run returns an enumerator when a 206 Partial Content status code and
378
- # Content-Range header is included in a server response. The enumerator
379
- # makes requests to fetch missing pages as its iterated.
380
- def test_run_with_range_response
381
- Excon.stub(method: :get) do |request|
382
- Excon.stubs.shift
383
- {status: 206, headers: {'Content-Type' => 'application/json',
384
- 'Content-Range' => 'id 1..2; max=200'},
385
- body: MultiJson.dump([2])}
386
- end
387
-
388
- Excon.stub(method: :get) do |request|
389
- Excon.stubs.shift
390
- {status: 206, headers: {'Content-Type' => 'application/json',
391
- 'Content-Range' => 'id 0..1; max=200',
392
- 'Next-Range' => '201'},
393
- body: MultiJson.dump([1])}
394
- end
395
-
396
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
397
- link = Heroics::Link.new('https://example.com',
398
- schema.resource('resource').link('list'))
399
- assert_equal([1, 2], link.run.to_a)
400
- end
401
-
402
- # Ensure that caching does not prevent pagination from working correctly.
403
- # See https://github.com/heroku/platform-api/issues/16
404
- def test_run_with_range_response_and_cache
405
- Excon.stub(method: :get) do |request|
406
- Excon.stubs.shift
407
- {status: 206, headers: {'Content-Type' => 'application/json',
408
- 'Content-Range' => 'id 1..2; max=200',
409
- 'ETag' => 'second-page'},
410
- body: MultiJson.dump([2])}
411
- end
412
-
413
- Excon.stub(method: :get) do |request|
414
- Excon.stubs.shift
415
- {status: 206, headers: {'Content-Type' => 'application/json',
416
- 'Content-Range' => 'id 0..1; max=200',
417
- 'Next-Range' => '201',
418
- 'ETag' => 'first-page'},
419
- body: MultiJson.dump([1])}
420
- end
421
-
422
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
423
- link = Heroics::Link.new('https://example.com',
424
- schema.resource('resource').link('list'),
425
- cache: Moneta.new(:Memory))
426
- assert_equal([1, 2], link.run.to_a)
427
-
428
- Excon.stub(method: :get) do |request|
429
- assert_equal('second-page', request[:headers]['If-None-Match'])
430
- assert_equal('201', request[:headers]['Range'])
431
- Excon.stubs.shift
432
- {status: 304, headers: {'Content-Type' => 'application/json'}}
433
- end
434
-
435
- Excon.stub(method: :get) do |request|
436
- assert_equal('first-page', request[:headers]['If-None-Match'])
437
- assert_equal(nil, request[:headers]['Range'])
438
- Excon.stubs.shift
439
- {status: 304, headers: {'Content-Type' => 'application/json'}}
440
- end
441
-
442
- assert_equal([1, 2], link.run.to_a)
443
- end
444
- end