minitest-rack 0.2.0
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.
- checksums.yaml +7 -0
- data/.github/dependabot.yml +24 -0
- data/.github/workflows/ruby.yml +45 -0
- data/.gitignore +9 -0
- data/.rubocop.yml +33 -0
- data/.rubocop_todo.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +83 -0
- data/Guardfile +26 -0
- data/LICENSE +21 -0
- data/README.md +99 -0
- data/Rakefile +24 -0
- data/lib/minitest/rack/all.rb +7 -0
- data/lib/minitest/rack/headers.rb +298 -0
- data/lib/minitest/rack/json.rb +250 -0
- data/lib/minitest/rack/status.rb +524 -0
- data/lib/minitest/rack/version.rb +7 -0
- data/lib/minitest/rack.rb +35 -0
- data/minitest-rack.gemspec +44 -0
- metadata +133 -0
@@ -0,0 +1,298 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'minitest/assertions'
|
4
|
+
require 'minitest/spec'
|
5
|
+
|
6
|
+
# reopening to add validations functionality
|
7
|
+
module Minitest
|
8
|
+
# add support for Assert syntax
|
9
|
+
module Assertions
|
10
|
+
# Test if a specific response header has an expected value
|
11
|
+
# Essentially, a shortcut for testing the `last_response.header` value
|
12
|
+
#
|
13
|
+
# @param [String] header The name of the HTTP header to check
|
14
|
+
# @param [String] contents The expected value of the header
|
15
|
+
#
|
16
|
+
# @return [Boolean] True if header matches expected value
|
17
|
+
#
|
18
|
+
# Example:
|
19
|
+
# assert_header('Accept', 'text/plain')
|
20
|
+
#
|
21
|
+
def assert_header(header, contents)
|
22
|
+
msg = "Expected response header '#{header}' to be '#{contents}', "
|
23
|
+
msg << "but was '#{last_response.headers[header]}'"
|
24
|
+
|
25
|
+
assert_equal(contents, last_response.headers[header], msg)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Tests that a header contains the Accept content-type
|
29
|
+
# Accept indicates which content-types the client can process
|
30
|
+
#
|
31
|
+
# @param [String] type The content-type to check for
|
32
|
+
#
|
33
|
+
# @return [Boolean] True if Accept header matches the specified type
|
34
|
+
#
|
35
|
+
# Example:
|
36
|
+
# assert_header_accept("text/plain")
|
37
|
+
#
|
38
|
+
def assert_header_accept(type)
|
39
|
+
assert_header('Accept', type)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Test for the `application/` type header via `Content-Type`
|
43
|
+
# Valid application types include pdf, json, xml, etc.
|
44
|
+
#
|
45
|
+
# @param [String] type The application content-type suffix (e.g. "pdf", "json")
|
46
|
+
#
|
47
|
+
# @return [Boolean] True if Content-Type header matches "application/type"
|
48
|
+
#
|
49
|
+
# Example:
|
50
|
+
# assert_header_application_type('pdf')
|
51
|
+
# # Tests Content-Type equals 'application/pdf'
|
52
|
+
#
|
53
|
+
def assert_header_application_type(type)
|
54
|
+
assert_header('Content-Type', "application/#{type}")
|
55
|
+
end
|
56
|
+
|
57
|
+
# Test if Content-Encoding header matches expected value
|
58
|
+
# Content-Encoding specifies what encodings have been applied to the payload.
|
59
|
+
# Common encoding types include gzip, compress, deflate, br
|
60
|
+
#
|
61
|
+
# @param [String] encoding_str The expected content encoding value
|
62
|
+
#
|
63
|
+
# @return [Boolean] True if Content-Encoding matches expected value
|
64
|
+
#
|
65
|
+
# Example:
|
66
|
+
# assert_header_content_encoding('gzip')
|
67
|
+
#
|
68
|
+
# assert_header_encoding('gzip')
|
69
|
+
#
|
70
|
+
def assert_header_content_encoding(encoding_str)
|
71
|
+
assert_header('Content-Encoding', encoding_str)
|
72
|
+
end
|
73
|
+
alias assert_header_encoding assert_header_content_encoding
|
74
|
+
|
75
|
+
# Tests that the Content-Language header matches an expected value
|
76
|
+
# Content-Language indicates the language of the content returned by the server
|
77
|
+
#
|
78
|
+
# @param [String] lang The expected language value
|
79
|
+
#
|
80
|
+
# @return [Boolean] True if Content-Language matches the expected value
|
81
|
+
#
|
82
|
+
# Example:
|
83
|
+
# assert_header_content_language('en')
|
84
|
+
# assert_header_content_language('fr')
|
85
|
+
#
|
86
|
+
def assert_header_content_language(lang)
|
87
|
+
assert_header('Content-Language', lang)
|
88
|
+
end
|
89
|
+
alias assert_header_language assert_header_content_language
|
90
|
+
|
91
|
+
# Tests that the Content-Length header matches the expected value
|
92
|
+
# Content-Length specifies the size of the response body in bytes
|
93
|
+
#
|
94
|
+
# @param [String, Integer] length The expected content length value
|
95
|
+
#
|
96
|
+
# @return [Boolean] True if Content-Length matches the expected value
|
97
|
+
#
|
98
|
+
# Example:
|
99
|
+
# assert_header_content_length(348)
|
100
|
+
# assert_header_content_length("348")
|
101
|
+
#
|
102
|
+
def assert_header_content_length(length)
|
103
|
+
assert_header('Content-Length', length.to_s)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Test if Content-Location header matches expected value
|
107
|
+
# Content-Location indicates an alternate location for the returned data
|
108
|
+
#
|
109
|
+
# @param [String] url The expected alternate URL value
|
110
|
+
#
|
111
|
+
# @return [Boolean] True if Content-Location matches expected value
|
112
|
+
#
|
113
|
+
# Example:
|
114
|
+
# assert_header_content_location('/index.htm')
|
115
|
+
#
|
116
|
+
def assert_header_content_location(url)
|
117
|
+
assert_header('Content-Location', url.to_s)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Tests that the Content-Type header matches an expected value
|
121
|
+
# Content-Type specifies the MIME type of the content being sent
|
122
|
+
#
|
123
|
+
# @param [String] type The expected MIME type
|
124
|
+
#
|
125
|
+
# @return [Boolean] True if Content-Type matches expected value
|
126
|
+
#
|
127
|
+
# Example:
|
128
|
+
# assert_header_content_type('text/html; charset=utf-8')
|
129
|
+
#
|
130
|
+
def assert_header_content_type(type)
|
131
|
+
assert_header('Content-Type', type)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Tests that the ETag header matches an expected value
|
135
|
+
# ETag is a unique identifier for a specific version of a resource, often a hash
|
136
|
+
#
|
137
|
+
# @param [String] tag The expected ETag value
|
138
|
+
#
|
139
|
+
# @return [Boolean] True if ETag matches expected value
|
140
|
+
#
|
141
|
+
# Example:
|
142
|
+
# assert_header_etag('"737060cd8c284d8af7ad3082f209582d"')
|
143
|
+
#
|
144
|
+
def assert_header_etag(tag)
|
145
|
+
assert_header('ETag', tag)
|
146
|
+
end
|
147
|
+
|
148
|
+
# Tests that the Expires header matches an expected timestamp
|
149
|
+
# Expires defines when the response should be considered stale
|
150
|
+
#
|
151
|
+
# @param [String] timestamp The expected expiration date in HTTP-date format
|
152
|
+
#
|
153
|
+
# @return [Boolean] True if Expires matches expected timestamp
|
154
|
+
#
|
155
|
+
# Example:
|
156
|
+
# assert_header_expires('Thu, 01 Dec 1994 16:00:00 GMT')
|
157
|
+
#
|
158
|
+
def assert_header_expires(timestamp)
|
159
|
+
assert_header('Expires', timestamp)
|
160
|
+
end
|
161
|
+
|
162
|
+
# Tests that the Content-Type header matches an image MIME type
|
163
|
+
# Validates that content is an image with the specified format
|
164
|
+
#
|
165
|
+
# @param [String, Symbol] type The expected image format (bmp, gif, jpg, jpeg, png, tiff)
|
166
|
+
#
|
167
|
+
# @return [Boolean] True if Content-Type matches "image/type"
|
168
|
+
#
|
169
|
+
# Example:
|
170
|
+
# assert_header_image_type('png')
|
171
|
+
# # Tests Content-Type equals 'image/png'
|
172
|
+
#
|
173
|
+
def assert_header_image_type(type)
|
174
|
+
assert_header('Content-Type', "image/#{type}")
|
175
|
+
end
|
176
|
+
|
177
|
+
# Tests that the Last-Modified header matches an expected timestamp
|
178
|
+
# Last-Modified indicates when the resource was last changed
|
179
|
+
#
|
180
|
+
# @param [String] timestamp The expected last modified date in HTTP-date format
|
181
|
+
#
|
182
|
+
# @return [Boolean] True if Last-Modified matches expected timestamp
|
183
|
+
#
|
184
|
+
# Example:
|
185
|
+
# assert_header_last_modified('Tue, 15 Nov 1994 12:45:26 GMT')
|
186
|
+
#
|
187
|
+
def assert_header_last_modified(timestamp)
|
188
|
+
assert_header('Last-Modified', timestamp)
|
189
|
+
end
|
190
|
+
|
191
|
+
# Tests that the Server header matches an expected value
|
192
|
+
# Server specifies information about the software used by the origin server
|
193
|
+
#
|
194
|
+
# @param [String] server_str The expected server identification string
|
195
|
+
#
|
196
|
+
# @return [Boolean] True if Server header matches expected value
|
197
|
+
#
|
198
|
+
# Example:
|
199
|
+
# assert_header_server('Apache/2.4.1 (Unix)')
|
200
|
+
#
|
201
|
+
def assert_header_server(server_str)
|
202
|
+
assert_header('Server', server_str)
|
203
|
+
end
|
204
|
+
|
205
|
+
# Test for the `text/` type header via `Content-Type`
|
206
|
+
# Tests that the Content-Type header matches a text/* MIME type
|
207
|
+
#
|
208
|
+
# @param [String] type The text content-type suffix (e.g. "plain", "html")
|
209
|
+
#
|
210
|
+
# @return [Boolean] True if Content-Type header matches "text/type"
|
211
|
+
#
|
212
|
+
# Example:
|
213
|
+
# assert_header_text_type('plain')
|
214
|
+
# # Tests Content-Type equals 'text/plain'
|
215
|
+
#
|
216
|
+
def assert_header_text_type(type)
|
217
|
+
assert_header('Content-Type', "text/#{type}")
|
218
|
+
end
|
219
|
+
|
220
|
+
# Tests that the WWW-Authenticate header matches an expected value
|
221
|
+
# WWW-Authenticate indicates the authentication scheme that should be used
|
222
|
+
# to access the requested resource
|
223
|
+
#
|
224
|
+
# @param [String] auth_str The expected authentication scheme value
|
225
|
+
#
|
226
|
+
# @return [Boolean] True if WWW-Authenticate matches expected value
|
227
|
+
#
|
228
|
+
# Example:
|
229
|
+
# assert_header_www_authenticate('Basic')
|
230
|
+
# assert_header_www_authenticate('Bearer realm="example"')
|
231
|
+
#
|
232
|
+
def assert_header_www_authenticate(auth_str)
|
233
|
+
assert_header('WWW-Authenticate', auth_str)
|
234
|
+
end
|
235
|
+
|
236
|
+
# Tests that the Content-Disposition header indicates an attachment download
|
237
|
+
# Content-Disposition suggests whether content should be displayed inline or downloaded
|
238
|
+
# as an attachment with an optional filename
|
239
|
+
#
|
240
|
+
# Raise a "File Download" dialogue box for a known MIME type with binary format or suggest
|
241
|
+
# a filename for dynamic content. Quotes are necessary with special characters
|
242
|
+
#
|
243
|
+
# @param [String] filename The suggested filename for the attachment
|
244
|
+
#
|
245
|
+
# @return [Boolean] True if Content-Disposition matches expected attachment format
|
246
|
+
#
|
247
|
+
# Example:
|
248
|
+
# assert_header_attachment('document.pdf')
|
249
|
+
# # Tests Content-Disposition equals 'attachment; filename="document.pdf"'
|
250
|
+
#
|
251
|
+
def assert_header_attachment(filename)
|
252
|
+
assert_header('Content-Disposition', "attachment; filename=\"#{filename}\"")
|
253
|
+
end
|
254
|
+
|
255
|
+
# Tests that the Content-Type header is set to "application/json"
|
256
|
+
# Validates that the response is formatted as JSON data
|
257
|
+
#
|
258
|
+
# @return [Boolean] True if Content-Type matches "application/json"
|
259
|
+
#
|
260
|
+
# Example:
|
261
|
+
# assert_header_type_is_json
|
262
|
+
# # Tests Content-Type equals 'application/json'
|
263
|
+
#
|
264
|
+
def assert_header_type_is_json
|
265
|
+
assert_header('Content-Type', 'application/json')
|
266
|
+
end
|
267
|
+
end
|
268
|
+
# /module Assertions
|
269
|
+
|
270
|
+
# add support for Spec syntax
|
271
|
+
module Expectations
|
272
|
+
infect_an_assertion :assert_header_accept, :must_have_header_accept, :reverse
|
273
|
+
infect_an_assertion :assert_header_application_type, :must_have_header_application_type,
|
274
|
+
:reverse
|
275
|
+
infect_an_assertion :assert_header_content_encoding, :must_have_header_content_encoding,
|
276
|
+
:reverse
|
277
|
+
infect_an_assertion :assert_header_content_language, :must_have_header_content_language,
|
278
|
+
:reverse
|
279
|
+
infect_an_assertion :assert_header_content_length, :must_have_header_content_length,
|
280
|
+
:reverse
|
281
|
+
infect_an_assertion :assert_header_content_location, :must_have_header_content_location,
|
282
|
+
:reverse
|
283
|
+
infect_an_assertion :assert_header_content_type, :must_have_header_content_type,
|
284
|
+
:reverse
|
285
|
+
infect_an_assertion :assert_header_etag, :must_have_header_etag, :reverse
|
286
|
+
infect_an_assertion :assert_header_expires, :must_have_header_expires, :reverse
|
287
|
+
infect_an_assertion :assert_header_image_type, :must_have_header_image_type,
|
288
|
+
:reverse
|
289
|
+
infect_an_assertion :assert_header_last_modified, :must_have_header_last_modified,
|
290
|
+
:reverse
|
291
|
+
infect_an_assertion :assert_header_server, :must_have_header_server, :reverse
|
292
|
+
infect_an_assertion :assert_header_text_type, :must_have_header_text_type, :reverse
|
293
|
+
infect_an_assertion :assert_header_www_authenticate, :must_have_header_www_authenticate,
|
294
|
+
:reverse
|
295
|
+
infect_an_assertion :assert_header_attachment, :must_have_header_attachment, :reverse
|
296
|
+
infect_an_assertion :assert_header_type_is_json, :must_have_header_type_as_json, :reverse
|
297
|
+
end
|
298
|
+
end
|
@@ -0,0 +1,250 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
require 'rack/test'
|
4
|
+
require 'json'
|
5
|
+
require 'minitest/assertions'
|
6
|
+
require 'minitest/spec'
|
7
|
+
|
8
|
+
# reopening to add validations functionality
|
9
|
+
module Minitest
|
10
|
+
# add support for Assert syntax
|
11
|
+
module Assertions
|
12
|
+
# Parse the response body of the last response as JSON using the native Ruby
|
13
|
+
# JSON parser. This method helps in quickly grabbing the JSON data from the
|
14
|
+
# response to verify in assertions.
|
15
|
+
#
|
16
|
+
# @return [Hash] parsed JSON data from the response body
|
17
|
+
#
|
18
|
+
def json_data
|
19
|
+
::JSON.parse(last_response.body)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Asserts against the presence of specific key/value pairs in the response JSON data. When
|
23
|
+
# testing endpoint responses for JSON data conformity, it ensures the response matches the
|
24
|
+
# expected data exactly. Takes a hash of expected data and validates it against the parsed
|
25
|
+
# JSON response.
|
26
|
+
#
|
27
|
+
# @param res [Hash] hash containing the expected key/value pairs that should be
|
28
|
+
# present in the JSON response data
|
29
|
+
#
|
30
|
+
# @return [Boolean] true when response data matches expected data
|
31
|
+
#
|
32
|
+
# @example
|
33
|
+
# # Response body contains: {"id": 1, "name": "test"}
|
34
|
+
# assert_json_data({id: 1, name: "test"}) # => true
|
35
|
+
#
|
36
|
+
def assert_json_data(res)
|
37
|
+
data = json_data
|
38
|
+
|
39
|
+
msg = "Expected response JSON data to be '#{res}', but was '#{data}'"
|
40
|
+
|
41
|
+
assert_equal(res, data, msg)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Verify if the response JSON data contains a success attribute with specified truth value.
|
45
|
+
# This method specifically checks for the presence of a "success" key and validates its
|
46
|
+
# value against the expected boolean. By default, it expects true unless otherwise specified.
|
47
|
+
#
|
48
|
+
# @param bool [Boolean] the expected value of success attribute (defaults to true)
|
49
|
+
#
|
50
|
+
# @return [Boolean] true when the success value matches the expected boolean
|
51
|
+
#
|
52
|
+
def assert_json_success(bool: true)
|
53
|
+
data = json_data
|
54
|
+
|
55
|
+
msg = "Expected response JSON data to include '\"success\": #{bool}', "
|
56
|
+
msg << "but was '#{data.inspect}'"
|
57
|
+
|
58
|
+
assert_equal(bool, data['success'], msg)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Asserts that the response JSON data contains an 'error' attribute with the specified
|
62
|
+
# error code and validates that its value matches the expected error code string.
|
63
|
+
# Default error code is "404" if none specified.
|
64
|
+
#
|
65
|
+
# @param errno [String] the expected error code value (defaults to "404")
|
66
|
+
#
|
67
|
+
# @return [Boolean] true when the error value matches the expected error code
|
68
|
+
#
|
69
|
+
def assert_json_error(errno = '404')
|
70
|
+
data = json_data
|
71
|
+
|
72
|
+
msg = "Expected response JSON data to include '\"error\": #{errno}', "
|
73
|
+
msg << "but was '#{data.inspect}'"
|
74
|
+
|
75
|
+
assert_equal(errno.to_s, data['error'].to_s, msg)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Verifies that the response JSON data contains a message attribute with the
|
79
|
+
# specified message string.
|
80
|
+
# This method checks for the presence of a "message" key and validates that its
|
81
|
+
# value matches the expected message text.
|
82
|
+
#
|
83
|
+
# @param msg [String] the expected message value to check for in the response
|
84
|
+
#
|
85
|
+
# @return [Boolean] true when the message value matches the expected message string
|
86
|
+
#
|
87
|
+
def assert_json_message(message)
|
88
|
+
data = json_data
|
89
|
+
|
90
|
+
msg = "Expected response JSON data to include '\"message\": #{message}', "
|
91
|
+
msg << "but was '#{data.inspect}'"
|
92
|
+
|
93
|
+
assert_equal(message, data['message'], msg)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Verifies that the response JSON data contains a specific model attribute with
|
97
|
+
# the expected model data.
|
98
|
+
# This method checks if the response contains a key matching the provided model name and
|
99
|
+
# validates that its JSON representation matches the expected model object.
|
100
|
+
#
|
101
|
+
# @param key [String, Symbol] the model key to check for in the response
|
102
|
+
# @param model [Object] the model object whose JSON representation matches the response data
|
103
|
+
#
|
104
|
+
# @return [Boolean] true when the model JSON matches the response data for the given key
|
105
|
+
#
|
106
|
+
# @example
|
107
|
+
# # Response body contains: {"user": {"id": 1, "name": "Bob"}}
|
108
|
+
# user = User.new(id: 1, name: "Bob")
|
109
|
+
# assert_json_model('user', user) # => true
|
110
|
+
#
|
111
|
+
def assert_json_model(key, model)
|
112
|
+
data = json_data
|
113
|
+
key = key.to_s
|
114
|
+
|
115
|
+
msg = 'Expected response JSON data to include '
|
116
|
+
|
117
|
+
# handle wrong key value being passed
|
118
|
+
if data.key?(key)
|
119
|
+
msg << "'#{key}: #{model.to_json}', but was '#{data[key].to_json}'"
|
120
|
+
|
121
|
+
assert_equal(model.values.to_json, data[key].to_json, msg)
|
122
|
+
else
|
123
|
+
msg << "key: '#{key}', but JSON is: '#{data}'"
|
124
|
+
|
125
|
+
assert_has_key data, key, msg
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Verifies that the response JSON data contains the specified key with a non-empty value.
|
130
|
+
# This method checks for the presence of a given key in the response and validates that
|
131
|
+
# its value is not empty, ensuring the expected data field exists and has content.
|
132
|
+
#
|
133
|
+
# @param key [String, Symbol] the key to check for in the response
|
134
|
+
#
|
135
|
+
# @return [Boolean] true when the key exists and has a non-empty value
|
136
|
+
#
|
137
|
+
def assert_json_key(key)
|
138
|
+
data = json_data
|
139
|
+
key = key.to_s
|
140
|
+
|
141
|
+
msg = 'Expected response JSON data to include '
|
142
|
+
msg << "key: '#{key}', but JSON is '#{data}'"
|
143
|
+
|
144
|
+
# handle the model being present
|
145
|
+
if data.key?(key)
|
146
|
+
refute_empty(data[key], msg)
|
147
|
+
else
|
148
|
+
assert_has_key data, key, msg
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Verifies that the response JSON data contains a nested key within a model attribute
|
153
|
+
# and that the key's value is not empty.
|
154
|
+
# This method checks if the response contains a model key and a nested key within it,
|
155
|
+
# validating that the nested key's value exists and is not empty.
|
156
|
+
#
|
157
|
+
# @param model [String, Symbol] the model key to check for in the response
|
158
|
+
# @param key [String, Symbol] the nested key to check within the model object
|
159
|
+
#
|
160
|
+
# @return [Boolean] true when the nested key exists and has a non-empty value
|
161
|
+
#
|
162
|
+
# rubocop:disable Metrics/MethodLength
|
163
|
+
def assert_json_model_key(model, key)
|
164
|
+
data = json_data
|
165
|
+
model = model.to_s
|
166
|
+
key = key.to_s
|
167
|
+
|
168
|
+
msg = 'Expected response JSON data to include '
|
169
|
+
|
170
|
+
# handle the model being present
|
171
|
+
if data.key?(model)
|
172
|
+
if data[model].key?(key)
|
173
|
+
msg = 'life is great'
|
174
|
+
|
175
|
+
refute_empty(data[model][key], msg)
|
176
|
+
else
|
177
|
+
msg << "model.key: '#{model}.#{key}', but it did not"
|
178
|
+
|
179
|
+
assert_has_key data, "#{model}.#{key}", msg
|
180
|
+
end
|
181
|
+
else
|
182
|
+
msg << "model: '#{model}', but it did not"
|
183
|
+
|
184
|
+
assert_has_key data, model, msg
|
185
|
+
end
|
186
|
+
end
|
187
|
+
# rubocop:enable Metrics/MethodLength
|
188
|
+
|
189
|
+
# Shortcut for sending GET requests as JSON
|
190
|
+
#
|
191
|
+
# get_json("/api/users")
|
192
|
+
#
|
193
|
+
def get_json(path, params = {}, headers = {})
|
194
|
+
json_request(:get, path, params, headers)
|
195
|
+
end
|
196
|
+
|
197
|
+
# Shortcut for sending POST requests as JSON
|
198
|
+
#
|
199
|
+
# post_json("/api/users", {name: "Joe"})
|
200
|
+
#
|
201
|
+
def post_json(path, params = {}, headers = {})
|
202
|
+
json_request(:post, path, params, headers)
|
203
|
+
end
|
204
|
+
|
205
|
+
# Shortcut for sending PUT requests as JSON
|
206
|
+
#
|
207
|
+
# put_json("/api/users/1234", {id: 1, name: "Joe"})
|
208
|
+
#
|
209
|
+
def put_json(path, params = {}, headers = {})
|
210
|
+
json_request(:put, path, params, headers)
|
211
|
+
end
|
212
|
+
|
213
|
+
# Shortcut for sending DELETE requests as JSON
|
214
|
+
#
|
215
|
+
# delete_json("/api/users/1234")
|
216
|
+
#
|
217
|
+
def delete_json(path, params = {}, headers = {})
|
218
|
+
json_request(:delete, path, params, headers)
|
219
|
+
end
|
220
|
+
|
221
|
+
private
|
222
|
+
|
223
|
+
# Makes an HTTP request with JSON data. This helper method is used by the HTTP verb shortcuts
|
224
|
+
# (get_json, post_json, etc) to standardize JSON request handling. It converts the params
|
225
|
+
# to JSON and sets the appropriate content type header.
|
226
|
+
#
|
227
|
+
# @param verb [Symbol] the HTTP verb to use (:get, :post, :put, :delete)
|
228
|
+
# @param path [String] the URL path for the request
|
229
|
+
# @param params [Hash] parameters to be converted to JSON and sent with request (default: {})
|
230
|
+
# @param headers [Hash] HTTP headers to include with request (default: {})
|
231
|
+
#
|
232
|
+
# @return [Response] the response from the HTTP request
|
233
|
+
#
|
234
|
+
def json_request(verb, path, params = {}, headers = {})
|
235
|
+
send(verb, path, params.to_json, headers.merge({ 'Content-Type' => 'application/json' }))
|
236
|
+
end
|
237
|
+
end
|
238
|
+
# /module Assertions
|
239
|
+
|
240
|
+
# add support for Spec syntax
|
241
|
+
module Expectations
|
242
|
+
infect_an_assertion :assert_json_data, :must_have_json_data, :reverse
|
243
|
+
infect_an_assertion :assert_json_success, :must_have_json_success, :reverse
|
244
|
+
infect_an_assertion :assert_json_error, :must_have_json_error, :reverse
|
245
|
+
infect_an_assertion :assert_json_message, :must_have_json_message, :reverse
|
246
|
+
infect_an_assertion :assert_json_key, :must_have_json_key, :reverse
|
247
|
+
infect_an_assertion :assert_json_model, :must_have_json_model, :reverse
|
248
|
+
infect_an_assertion :assert_json_model_key, :must_have_json_model_key, :reverse
|
249
|
+
end
|
250
|
+
end
|