komoju 0.0.0 → 0.0.3

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.
@@ -0,0 +1,214 @@
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
@@ -0,0 +1,204 @@
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
+ }