heroics 0.0.17 → 0.0.18

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'helper'
3
- require 'netrc'
4
- require 'stringio'
5
-
6
- class GenerateClientTest < MiniTest::Unit::TestCase
7
- include ExconHelper
8
-
9
- # generate_client takes a module, schema, API URL and options and returns a
10
- # string containing generated Ruby client code.
11
- def test_generate_client
12
- Excon.stub(method: :get) do |request|
13
- assert_equal('example.com', request[:host])
14
- assert_equal('/schema', request[:path])
15
- assert_equal('application/vnd.example+json; version=3',
16
- request[:headers]['Accept'])
17
- Excon.stubs.pop
18
- {status: 200, headers: {'Content-Type' => 'application/json'},
19
- body: MultiJson.dump(SAMPLE_SCHEMA)}
20
- end
21
-
22
- netrc = Netrc.read
23
- username, token = netrc['example.com']
24
- schema_url = "https://example.com/schema"
25
- options = {
26
- default_headers: {'Accept' => 'application/vnd.example+json; version=3'},
27
- cache: 'Moneta.new(:File, dir: "#{Dir.home}/.heroics/example")'
28
- }
29
- schema = Heroics.download_schema(schema_url, options)
30
- client_source = Heroics.generate_client("ExampleAPI", schema,
31
- "api.example.com", options)
32
- # Ensure the generated code is syntactically valid.
33
- eval(client_source)
34
- end
35
- end
@@ -1,275 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'helper'
3
-
4
- class ClientTest < MiniTest::Unit::TestCase
5
- include ExconHelper
6
-
7
- # Client.to_s returns a simple human-readable description of the client
8
- # instance with the URL embedded in it. A password, if present in the URL,
9
- # is redacted to avoid leaking credentials.
10
- def test_to_s
11
- client = Heroics::Client.new({}, 'http://foo:bar@example.com')
12
- assert_equal('#<Heroics::Client url="http://foo:REDACTED@example.com">',
13
- client.to_s)
14
- end
15
-
16
- # Client.<resource> raises a NoMethodError when a method is invoked
17
- # without a matching resource.
18
- def test_invalid_resource
19
- client = Heroics::Client.new({}, 'http://example.com')
20
- error = assert_raises NoMethodError do
21
- client.unknown
22
- end
23
- assert_equal("undefined method `unknown' for " +
24
- '#<Heroics::Client url="http://example.com">',
25
- error.message)
26
- end
27
-
28
- # Client.<resource>.<link> finds the appropriate link and invokes it.
29
- def test_resource
30
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
31
- link = Heroics::Link.new('https://username:secret@example.com',
32
- schema.resource('resource').link('list'))
33
- resource = Heroics::Resource.new({'link' => link})
34
- client = Heroics::Client.new({'resource' => resource},
35
- 'http://example.com')
36
- Excon.stub(method: :get) do |request|
37
- assert_equal('Basic dXNlcm5hbWU6c2VjcmV0',
38
- request[:headers]['Authorization'])
39
- assert_equal('example.com', request[:host])
40
- assert_equal(443, request[:port])
41
- assert_equal('/resource', request[:path])
42
- Excon.stubs.pop
43
- {status: 200, body: 'Hello, world!'}
44
- end
45
- assert_equal('Hello, world!', client.resource.link)
46
- end
47
-
48
- # Client.<resource>.<link> finds the appropriate link and invokes it with
49
- # query params, since it is a GET resource
50
- def test_resource_with_query_param
51
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
52
- link = Heroics::Link.new('https://username:secret@example.com',
53
- schema.resource('resource').link('list'))
54
- resource = Heroics::Resource.new({'link' => link})
55
- client = Heroics::Client.new({'resource' => resource},
56
- 'http://example.com')
57
- Excon.stub(method: :get) do |request|
58
- assert_equal({:limit => '50', :page => '25'}, request[:query])
59
- Excon.stubs.pop
60
- {status: 200, body: 'Hello, world!'}
61
- end
62
- assert_equal('Hello, world!', client.resource.link(limit: '50', page: '25'))
63
- end
64
-
65
- # Client converts underscores in resource method names to dashes to match
66
- # names specified in the schema.
67
- def test_resource_with_dashed_name
68
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
69
- link = Heroics::Link.new('https://username:secret@example.com',
70
- schema.resource('another-resource').link('list'))
71
- resource = Heroics::Resource.new({'link' => link})
72
- client = Heroics::Client.new({'another-resource' => resource},
73
- 'http://example.com')
74
- Excon.stub(method: :get) do |request|
75
- assert_equal('Basic dXNlcm5hbWU6c2VjcmV0',
76
- request[:headers]['Authorization'])
77
- assert_equal('example.com', request[:host])
78
- assert_equal(443, request[:port])
79
- assert_equal('/another-resource', request[:path])
80
- Excon.stubs.pop
81
- {status: 200, body: 'Hello, world!'}
82
- end
83
- assert_equal('Hello, world!', client.another_resource.link)
84
- end
85
-
86
- # Client.<resource>.<link> finds the appropriate link and invokes it, even if
87
- # the resource has an underscore in its name
88
- def test_resource_with_underscored_name
89
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
90
- link = Heroics::Link.new('https://username:secret@example.com',
91
- schema.resource('underscored_resource').link('list'))
92
- resource = Heroics::Resource.new({'link' => link})
93
- client = Heroics::Client.new({'underscored_resource' => resource},
94
- 'http://example.com')
95
- Excon.stub(method: :get) do |request|
96
- assert_equal('Basic dXNlcm5hbWU6c2VjcmV0',
97
- request[:headers]['Authorization'])
98
- assert_equal('example.com', request[:host])
99
- assert_equal(443, request[:port])
100
- assert_equal('/underscored_resource', request[:path])
101
- Excon.stubs.pop
102
- {status: 200, body: 'Hello, world!'}
103
- end
104
- assert_equal('Hello, world!', client.underscored_resource.link)
105
- end
106
- end
107
-
108
- class ClientFromSchemaTest < MiniTest::Unit::TestCase
109
- include ExconHelper
110
-
111
- # client_from_schema returns a Client generated from the specified schema.
112
- def test_client_from_schema
113
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
114
- client = Heroics::client_from_schema(schema, 'https://example.com')
115
- body = {'Hello' => 'World!'}
116
- Excon.stub(method: :post) do |request|
117
- assert_equal('/resource', request[:path])
118
- Excon.stubs.pop
119
- {status: 200, headers: {'Content-Type' => 'application/json'},
120
- body: MultiJson.dump(body)}
121
- end
122
- assert_equal(body, client.resource.create)
123
- end
124
-
125
- # client_from_schema returns a Client that can make requests to APIs mounted
126
- # under a prefix, such as http://example.com/api, for example.
127
- def test_client_from_schema_with_url_prefix
128
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
129
- client = Heroics::client_from_schema(schema, 'https://example.com/api')
130
- body = {'Hello' => 'World!'}
131
- Excon.stub(method: :post) do |request|
132
- assert_equal('/api/resource', request[:path])
133
- Excon.stubs.pop
134
- {status: 200, headers: {'Content-Type' => 'application/json'},
135
- body: MultiJson.dump(body)}
136
- end
137
- assert_equal(body, client.resource.create)
138
- end
139
-
140
- # client_from_schema optionally accepts custom headers to pass with every
141
- # request made by the generated client.
142
- def test_client_from_schema_with_custom_headers
143
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
144
- client = Heroics::client_from_schema(
145
- schema, 'https://example.com',
146
- default_headers: {'Accept' => 'application/vnd.heroku+json; version=3'})
147
- Excon.stub(method: :post) do |request|
148
- assert_equal('application/vnd.heroku+json; version=3',
149
- request[:headers]['Accept'])
150
- Excon.stubs.pop
151
- {status: 200}
152
- end
153
- client.resource.create
154
- end
155
-
156
- # client_from_schema takes an optional :cache parameter which it uses when
157
- # constructing Link instances.
158
- def test_client_from_schema_with_cache
159
- body = {'Hello' => 'World!'}
160
- Excon.stub(method: :get) do |request|
161
- Excon.stubs.pop
162
- {status: 201, headers: {'Content-Type' => 'application/json',
163
- 'ETag' => 'etag-contents'},
164
- body: MultiJson.dump(body)}
165
- end
166
-
167
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
168
- client = Heroics::client_from_schema(schema, 'https://example.com',
169
- cache: Moneta.new(:Memory))
170
- assert_equal(body, client.resource.list)
171
-
172
- Excon.stub(method: :get) do |request|
173
- assert_equal('etag-contents', request[:headers]['If-None-Match'])
174
- Excon.stubs.pop
175
- {status: 304, headers: {'Content-Type' => 'application/json'}}
176
- end
177
- assert_equal(body, client.resource.list)
178
- end
179
- end
180
-
181
- class OAuthClientFromSchemaTest < MiniTest::Unit::TestCase
182
- include ExconHelper
183
-
184
- # oauth_client_from_schema injects an Authorization header, built from the
185
- # specified OAuth token, into the default header options.
186
- def test_oauth_client_from_schema
187
- body = {'Hello' => 'World!'}
188
- Excon.stub(method: :get) do |request|
189
- assert_equal(
190
- 'Bearer c55ef0d8-40b6-4759-b1bf-4a6f94190a66',
191
- request[:headers]['Authorization'])
192
- Excon.stubs.pop
193
- {status: 200, headers: {'Content-Type' => 'application/json'},
194
- body: MultiJson.dump(body)}
195
- end
196
-
197
- oauth_token = 'c55ef0d8-40b6-4759-b1bf-4a6f94190a66'
198
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
199
- client = Heroics.oauth_client_from_schema(oauth_token, schema,
200
- 'https://example.com')
201
- assert_equal(body, client.resource.list)
202
- end
203
-
204
- # oauth_client_from_schema doesn't mutate the options object, and in
205
- # particular, it doesn't mutate the :default_headers Hash in that object.
206
- def test_oauth_client_from_schema_with_options
207
- body = {'Hello' => 'World!'}
208
- Excon.stub(method: :get) do |request|
209
- assert_equal('application/vnd.heroku+json; version=3',
210
- request[:headers]['Accept'])
211
- assert_equal(
212
- 'Bearer c55ef0d8-40b6-4759-b1bf-4a6f94190a66',
213
- request[:headers]['Authorization'])
214
- Excon.stubs.pop
215
- {status: 200, headers: {'Content-Type' => 'application/json'},
216
- body: MultiJson.dump(body)}
217
- end
218
-
219
- oauth_token = 'c55ef0d8-40b6-4759-b1bf-4a6f94190a66'
220
- options = {
221
- default_headers: {'Accept' => 'application/vnd.heroku+json; version=3'}}
222
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
223
- client = Heroics.oauth_client_from_schema(oauth_token, schema,
224
- 'https://example.com', options)
225
- assert_equal(body, client.resource.list)
226
- end
227
- end
228
-
229
- class TokenClientFromSchemaTest < MiniTest::Unit::TestCase
230
- include ExconHelper
231
-
232
- # token_client_from_schema injects an Authorization header, built from the
233
- # specified token, into the default header options.
234
- def test_token_client_from_schema
235
- body = {'Hello' => 'World!'}
236
- Excon.stub(method: :get) do |request|
237
- assert_equal(
238
- 'Token token=c55ef0d8-40b6-4759-b1bf-4a6f94190a66',
239
- request[:headers]['Authorization'])
240
- Excon.stubs.pop
241
- {status: 200, headers: {'Content-Type' => 'application/json'},
242
- body: MultiJson.dump(body)}
243
- end
244
-
245
- token = 'c55ef0d8-40b6-4759-b1bf-4a6f94190a66'
246
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
247
- client = Heroics.token_client_from_schema(token, schema,
248
- 'https://example.com')
249
- assert_equal(body, client.resource.list)
250
- end
251
-
252
- # token_client_from_schema doesn't mutate the options object, and in
253
- # particular, it doesn't mutate the :default_headers Hash in that object.
254
- def test_token_client_from_schema_with_options
255
- body = {'Hello' => 'World!'}
256
- Excon.stub(method: :get) do |request|
257
- assert_equal('application/vnd.heroku+json; version=3',
258
- request[:headers]['Accept'])
259
- assert_equal(
260
- 'Token token=c55ef0d8-40b6-4759-b1bf-4a6f94190a66',
261
- request[:headers]['Authorization'])
262
- Excon.stubs.pop
263
- {status: 200, headers: {'Content-Type' => 'application/json'},
264
- body: MultiJson.dump(body)}
265
- end
266
-
267
- token = 'c55ef0d8-40b6-4759-b1bf-4a6f94190a66'
268
- options = {
269
- default_headers: {'Accept' => 'application/vnd.heroku+json; version=3'}}
270
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
271
- client = Heroics.token_client_from_schema(token, schema,
272
- 'https://example.com', options)
273
- assert_equal(body, client.resource.list)
274
- end
275
- end
@@ -1,215 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'helper'
3
- require 'stringio'
4
-
5
- class CommandTest < MiniTest::Unit::TestCase
6
- include ExconHelper
7
-
8
- # Command.name returns the name of the command, which is made up by joining
9
- # the resource name and link title with a colon.
10
- def test_name
11
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
12
- client = Heroics::client_from_schema(schema, 'https://example.com')
13
- output = StringIO.new
14
- command = Heroics::Command.new(
15
- 'cli', schema.resource('resource').link('list'), client, output)
16
- assert_equal('resource:list', command.name)
17
- end
18
-
19
- # Command.description returns a description for the command.
20
- def test_description
21
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
22
- client = Heroics::client_from_schema(schema, 'https://example.com')
23
- output = StringIO.new
24
- command = Heroics::Command.new(
25
- 'cli', schema.resource('resource').link('list'), client, output)
26
- assert_equal('Show all sample resources', command.description)
27
- end
28
-
29
- # Command.run calls the correct method on the client when no link parameters
30
- # are provided.
31
- def test_run_without_parameters
32
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
33
- client = Heroics::client_from_schema(schema, 'https://example.com')
34
- output = StringIO.new
35
- command = Heroics::Command.new(
36
- 'cli', schema.resource('resource').link('list'), client, output)
37
-
38
- body = ['Hello', 'World!']
39
- Excon.stub(method: :get) do |request|
40
- assert_equal('/resource', request[:path])
41
- Excon.stubs.pop
42
- {status: 200, headers: {'Content-Type' => 'application/json'},
43
- body: MultiJson.dump(body)}
44
- end
45
-
46
- command.run
47
- assert_equal(MultiJson.dump(body, pretty: true) + "\n", output.string)
48
- end
49
-
50
- # Command.run calls the correct method on the client and passes link
51
- # parameters when they're provided.
52
- def test_run_with_parameters
53
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
54
- client = Heroics::client_from_schema(schema, 'https://example.com')
55
- output = StringIO.new
56
- command = Heroics::Command.new(
57
- 'cli', schema.resource('resource').link('info'), client, output)
58
-
59
- uuid = '1ab1c589-df46-40aa-b786-60e83b1efb10'
60
- body = {'Hello' => 'World!'}
61
- Excon.stub(method: :get) do |request|
62
- assert_equal("/resource/#{uuid}", request[:path])
63
- Excon.stubs.pop
64
- {status: 200, headers: {'Content-Type' => 'application/json'},
65
- body: MultiJson.dump(body)}
66
- end
67
-
68
- command.run(uuid)
69
- assert_equal(MultiJson.dump(body, pretty: true) + "\n", output.string)
70
- end
71
-
72
- # Command.run calls the correct method on the client and passes a request
73
- # body to the link when it's provided.
74
- def test_run_with_request_body_and_text_response
75
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
76
- client = Heroics::client_from_schema(schema, 'https://example.com')
77
- output = StringIO.new
78
- command = Heroics::Command.new(
79
- 'cli', schema.resource('resource').link('create'), client, output)
80
-
81
- body = {'Hello' => 'World!'}
82
- Excon.stub(method: :post) do |request|
83
- assert_equal('/resource', request[:path])
84
- assert_equal('application/json', request[:headers]['Content-Type'])
85
- assert_equal(body, MultiJson.load(request[:body]))
86
- Excon.stubs.pop
87
- {status: 201}
88
- end
89
-
90
- command.run(body)
91
- assert_equal('', output.string)
92
- end
93
-
94
- # Command.run calls the correct method on the client and converts the result
95
- # to an array, if a range response is received, before writing it out.
96
- def test_run_with_range_response
97
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
98
- client = Heroics::client_from_schema(schema, 'https://example.com')
99
- output = StringIO.new
100
- command = Heroics::Command.new(
101
- 'cli', schema.resource('resource').link('list'), client, output)
102
-
103
- Excon.stub(method: :get) do |request|
104
- Excon.stubs.shift
105
- {status: 206, headers: {'Content-Type' => 'application/json',
106
- 'Content-Range' => 'id 1..2; max=200'},
107
- body: MultiJson.dump([2])}
108
- end
109
-
110
- Excon.stub(method: :get) do |request|
111
- Excon.stubs.shift
112
- {status: 206, headers: {'Content-Type' => 'application/json',
113
- 'Content-Range' => 'id 0..1; max=200',
114
- 'Next-Range' => '201'},
115
- body: MultiJson.dump([1])}
116
- end
117
-
118
- command.run
119
- assert_equal(MultiJson.dump([1, 2], pretty: true) + "\n", output.string)
120
- end
121
-
122
- # Command.run calls the correct method on the client and passes parameters
123
- # and a request body to the link when they're provided.
124
- def test_run_with_request_body_and_parameters
125
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
126
- client = Heroics::client_from_schema(schema, 'https://example.com')
127
- output = StringIO.new
128
- command = Heroics::Command.new(
129
- 'cli', schema.resource('resource').link('update'), client, output)
130
-
131
- uuid = '1ab1c589-df46-40aa-b786-60e83b1efb10'
132
- body = {'Hello' => 'World!'}
133
- result = {'Goodbye' => 'Universe!'}
134
- Excon.stub(method: :patch) do |request|
135
- assert_equal("/resource/#{uuid}", request[:path])
136
- assert_equal('application/json', request[:headers]['Content-Type'])
137
- assert_equal(body, MultiJson.load(request[:body]))
138
- Excon.stubs.pop
139
- {status: 200, headers: {'Content-Type' => 'application/json'},
140
- body: MultiJson.dump(result)}
141
- end
142
-
143
- command.run(uuid, body)
144
- assert_equal(MultiJson.dump(result, pretty: true) + "\n", output.string)
145
- end
146
-
147
- # Command.run raises an ArgumentError if too few parameters are provided.
148
- def test_run_with_too_few_parameters
149
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
150
- client = Heroics::client_from_schema(schema, 'https://example.com')
151
- output = StringIO.new
152
- command = Heroics::Command.new(
153
- 'cli', schema.resource('resource').link('info'), client, output)
154
- assert_raises ArgumentError do
155
- command.run
156
- end
157
- end
158
-
159
- # Command.run raises an ArgumentError if too many parameters are provided.
160
- def test_run_with_too_many_parameters
161
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
162
- client = Heroics::client_from_schema(schema, 'https://example.com')
163
- output = StringIO.new
164
- command = Heroics::Command.new(
165
- 'cli', schema.resource('resource').link('info'), client, output)
166
- assert_raises ArgumentError do
167
- command.run('too', 'many', 'parameters')
168
- end
169
- end
170
-
171
- # Command.usage displays usage information.
172
- def test_usage
173
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
174
- client = Heroics::client_from_schema(schema, 'https://example.com')
175
- output = StringIO.new
176
- command = Heroics::Command.new(
177
- 'cli', schema.resource('resource').link('update'), client, output)
178
- command.usage
179
- expected = <<-USAGE
180
- Usage: cli resource:update <uuid_field> <body>
181
-
182
- Description:
183
- Update a sample resource
184
-
185
- Body example:
186
- {
187
- "date_field": "2013-10-19 22:10:29Z",
188
- "string_field": "Sample text.",
189
- "boolean_field": true,
190
- "uuid_field": "44724831-bf66-4bc2-865f-e2c4c2b14c78",
191
- "email_field": "username@example.com"
192
- }
193
- USAGE
194
- assert_equal(expected, output.string)
195
- end
196
-
197
- # Command.usage correctly handles parameters that are described by 'oneOf'
198
- # and 'anyOf' sub-parameter lists.
199
- def test_usage_with_one_of_field
200
- schema = Heroics::Schema.new(SAMPLE_SCHEMA)
201
- client = Heroics::client_from_schema(schema, 'https://example.com')
202
- output = StringIO.new
203
- command = Heroics::Command.new(
204
- 'cli', schema.resource('resource').link('identify_resource'), client,
205
- output)
206
- command.usage
207
- expected = <<-USAGE
208
- Usage: cli resource:identify-resource <uuid_field|email_field>
209
-
210
- Description:
211
- Show a sample resource
212
- USAGE
213
- assert_equal(expected, output.string)
214
- end
215
- end