komoju 0.0.4 → 0.0.7

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