jsonapi-resources 0.1.1 → 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 +4 -4
- data/README.md +68 -1
- data/Rakefile +3 -7
- data/lib/jsonapi-resources.rb +1 -0
- data/lib/jsonapi/configuration.rb +29 -4
- data/lib/jsonapi/error_codes.rb +6 -2
- data/lib/jsonapi/exceptions.rb +92 -19
- data/lib/jsonapi/operation.rb +0 -18
- data/lib/jsonapi/paginator.rb +98 -0
- data/lib/jsonapi/request.rb +257 -182
- data/lib/jsonapi/resource.rb +58 -47
- data/lib/jsonapi/resource_controller.rb +85 -29
- data/lib/jsonapi/resource_serializer.rb +88 -33
- data/lib/jsonapi/resources/version.rb +1 -1
- data/lib/jsonapi/routing_ext.rb +38 -12
- data/test/controllers/controller_test.rb +761 -455
- data/test/fixtures/active_record.rb +90 -18
- data/test/integration/requests/request_test.rb +183 -25
- data/test/integration/routes/routes_test.rb +0 -5
- data/test/test_helper.rb +31 -7
- data/test/unit/operation/operations_processor_test.rb +28 -1
- data/test/unit/resource/resource_test.rb +4 -0
- data/test/unit/serializer/serializer_test.rb +882 -377
- metadata +3 -2
data/lib/jsonapi/routing_ext.rb
CHANGED
@@ -65,8 +65,10 @@ module ActionDispatch
|
|
65
65
|
res._associations.each do |association_name, association|
|
66
66
|
if association.is_a?(JSONAPI::Association::HasMany)
|
67
67
|
jsonapi_links(association_name)
|
68
|
+
jsonapi_related_resources(association_name)
|
68
69
|
else
|
69
70
|
jsonapi_link(association_name)
|
71
|
+
jsonapi_related_resource(association_name)
|
70
72
|
end
|
71
73
|
end
|
72
74
|
end
|
@@ -95,22 +97,17 @@ module ActionDispatch
|
|
95
97
|
|
96
98
|
if methods.include?(:show)
|
97
99
|
match "links/#{formatted_association_name}", controller: res._type.to_s,
|
98
|
-
|
99
|
-
end
|
100
|
-
|
101
|
-
if methods.include?(:create)
|
102
|
-
match "links/#{formatted_association_name}", controller: res._type.to_s,
|
103
|
-
action: 'create_association', association: link_type.to_s, via: [:post]
|
100
|
+
action: 'show_association', association: link_type.to_s, via: [:get]
|
104
101
|
end
|
105
102
|
|
106
103
|
if methods.include?(:update)
|
107
104
|
match "links/#{formatted_association_name}", controller: res._type.to_s,
|
108
|
-
|
105
|
+
action: 'update_association', association: link_type.to_s, via: [:put]
|
109
106
|
end
|
110
107
|
|
111
108
|
if methods.include?(:destroy)
|
112
109
|
match "links/#{formatted_association_name}", controller: res._type.to_s,
|
113
|
-
|
110
|
+
action: 'destroy_association', association: link_type.to_s, via: [:delete]
|
114
111
|
end
|
115
112
|
end
|
116
113
|
|
@@ -125,25 +122,54 @@ module ActionDispatch
|
|
125
122
|
|
126
123
|
if methods.include?(:show)
|
127
124
|
match "links/#{formatted_association_name}", controller: res._type.to_s,
|
128
|
-
|
125
|
+
action: 'show_association', association: link_type.to_s, via: [:get]
|
129
126
|
end
|
130
127
|
|
131
128
|
if methods.include?(:create)
|
132
129
|
match "links/#{formatted_association_name}", controller: res._type.to_s,
|
133
|
-
|
130
|
+
action: 'create_association', association: link_type.to_s, via: [:post]
|
134
131
|
end
|
135
132
|
|
136
133
|
if methods.include?(:update) && res._association(link_type).acts_as_set
|
137
134
|
match "links/#{formatted_association_name}", controller: res._type.to_s,
|
138
|
-
|
135
|
+
action: 'update_association', association: link_type.to_s, via: [:put]
|
139
136
|
end
|
140
137
|
|
141
138
|
if methods.include?(:destroy)
|
142
139
|
match "links/#{formatted_association_name}/:keys", controller: res._type.to_s,
|
143
|
-
|
140
|
+
action: 'destroy_association', association: link_type.to_s, via: [:delete]
|
144
141
|
end
|
145
142
|
end
|
146
143
|
|
144
|
+
def jsonapi_related_resource(*association)
|
145
|
+
source = JSONAPI::Resource.resource_for(resource_type_with_module_prefix)
|
146
|
+
|
147
|
+
association_name = association.first
|
148
|
+
association = source._associations[association_name]
|
149
|
+
|
150
|
+
formatted_association_name = format_route(association.name)
|
151
|
+
related_resource = JSONAPI::Resource.resource_for(resource_type_with_module_prefix(association.name.pluralize))
|
152
|
+
|
153
|
+
match "#{formatted_association_name}", controller: related_resource._type.to_s,
|
154
|
+
association: association.name, source: resource_type_with_module_prefix(source._type),
|
155
|
+
action: 'get_related_resource', via: [:get]
|
156
|
+
end
|
157
|
+
|
158
|
+
def jsonapi_related_resources(*association)
|
159
|
+
source = JSONAPI::Resource.resource_for(resource_type_with_module_prefix)
|
160
|
+
|
161
|
+
association_name = association.first
|
162
|
+
association = source._associations[association_name]
|
163
|
+
|
164
|
+
formatted_association_name = format_route(association.name)
|
165
|
+
related_resource = JSONAPI::Resource.resource_for(resource_type_with_module_prefix(association.name))
|
166
|
+
|
167
|
+
match "#{formatted_association_name}", controller: related_resource._type.to_s,
|
168
|
+
association: association.name, source: resource_type_with_module_prefix(source._type),
|
169
|
+
action: 'get_related_resources', via: [:get]
|
170
|
+
end
|
171
|
+
|
172
|
+
private
|
147
173
|
def resource_type_with_module_prefix(resource = nil)
|
148
174
|
resource_name = resource || @scope[:jsonapi_resource]
|
149
175
|
[@scope[:module], resource_name].compact.collect(&:to_s).join("/")
|
@@ -9,198 +9,211 @@ class PostsControllerTest < ActionController::TestCase
|
|
9
9
|
def test_index
|
10
10
|
get :index
|
11
11
|
assert_response :success
|
12
|
-
assert json_response['
|
12
|
+
assert json_response['data'].is_a?(Array)
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_index_filter_with_empty_result
|
16
|
-
get :index, {title: 'post that does not exist'}
|
16
|
+
get :index, {filter: {title: 'post that does not exist'}}
|
17
17
|
assert_response :success
|
18
|
-
assert json_response['
|
19
|
-
assert_equal 0, json_response['
|
18
|
+
assert json_response['data'].is_a?(Array)
|
19
|
+
assert_equal 0, json_response['data'].size
|
20
20
|
end
|
21
21
|
|
22
22
|
def test_index_filter_by_id
|
23
|
-
get :index, {id: '1'}
|
23
|
+
get :index, {filter: {id: '1'}}
|
24
24
|
assert_response :success
|
25
|
-
assert json_response['
|
25
|
+
assert json_response['data'].is_a?(Array)
|
26
|
+
assert_equal 1, json_response['data'].size
|
26
27
|
end
|
27
28
|
|
28
29
|
def test_index_filter_by_title
|
29
|
-
get :index, {title: 'New post'}
|
30
|
+
get :index, {filter: {title: 'New post'}}
|
30
31
|
assert_response :success
|
31
|
-
assert json_response['
|
32
|
+
assert json_response['data'].is_a?(Array)
|
33
|
+
assert_equal 1, json_response['data'].size
|
32
34
|
end
|
33
35
|
|
34
36
|
def test_index_filter_by_ids
|
35
|
-
get :index, {ids: '1,2'}
|
37
|
+
get :index, {filter: {ids: '1,2'}}
|
36
38
|
assert_response :success
|
37
|
-
assert json_response['
|
38
|
-
assert_equal 2, json_response['
|
39
|
+
assert json_response['data'].is_a?(Array)
|
40
|
+
assert_equal 2, json_response['data'].size
|
39
41
|
end
|
40
42
|
|
41
43
|
def test_index_filter_by_ids_and_include_related
|
42
|
-
get :index,
|
44
|
+
get :index, {filter: {id: '2'}, include: 'comments'}
|
43
45
|
assert_response :success
|
44
|
-
assert_equal 1, json_response['
|
45
|
-
assert_equal 1, json_response['linked']
|
46
|
+
assert_equal 1, json_response['data'].size
|
47
|
+
assert_equal 1, json_response['linked'].size
|
46
48
|
end
|
47
49
|
|
48
50
|
def test_index_filter_by_ids_and_include_related_different_type
|
49
|
-
get :index, {
|
51
|
+
get :index, {filter: {id: '1,2'}, include: 'author'}
|
50
52
|
assert_response :success
|
51
|
-
assert_equal 2, json_response['
|
52
|
-
assert_equal 1, json_response['linked']
|
53
|
+
assert_equal 2, json_response['data'].size
|
54
|
+
assert_equal 1, json_response['linked'].size
|
53
55
|
end
|
54
56
|
|
55
57
|
def test_index_filter_by_ids_and_fields
|
56
|
-
get :index, {
|
58
|
+
get :index, {filter: {id: '1,2'}, 'fields' => 'id,title,author'}
|
57
59
|
assert_response :success
|
58
|
-
assert_equal 2, json_response['
|
60
|
+
assert_equal 2, json_response['data'].size
|
59
61
|
|
60
|
-
# id, title, links
|
61
|
-
assert_equal
|
62
|
-
assert json_response['
|
63
|
-
assert json_response['
|
64
|
-
assert json_response['
|
62
|
+
# type, id, title, links
|
63
|
+
assert_equal 4, json_response['data'][0].size
|
64
|
+
assert json_response['data'][0].has_key?('type')
|
65
|
+
assert json_response['data'][0].has_key?('id')
|
66
|
+
assert json_response['data'][0].has_key?('title')
|
67
|
+
assert json_response['data'][0].has_key?('links')
|
65
68
|
end
|
66
69
|
|
67
70
|
def test_index_filter_by_ids_and_fields_specify_type
|
68
|
-
get :index, {
|
71
|
+
get :index, {filter: {id: '1,2'}, 'fields' => {'posts' => 'id,title,author'}}
|
69
72
|
assert_response :success
|
70
|
-
assert_equal 2, json_response['
|
73
|
+
assert_equal 2, json_response['data'].size
|
71
74
|
|
72
|
-
# id, title, links
|
73
|
-
assert_equal
|
74
|
-
assert json_response['
|
75
|
-
assert json_response['
|
76
|
-
assert json_response['
|
75
|
+
# type, id, title, links
|
76
|
+
assert_equal 4, json_response['data'][0].size
|
77
|
+
assert json_response['data'][0].has_key?('type')
|
78
|
+
assert json_response['data'][0].has_key?('id')
|
79
|
+
assert json_response['data'][0].has_key?('title')
|
80
|
+
assert json_response['data'][0].has_key?('links')
|
77
81
|
end
|
78
82
|
|
79
83
|
def test_index_filter_by_ids_and_fields_specify_unrelated_type
|
80
|
-
get :index, {
|
84
|
+
get :index, {filter: {id: '1,2'}, 'fields' => {'currencies' => 'code'}}
|
81
85
|
assert_response :bad_request
|
82
86
|
assert_match /currencies is not a valid resource./, json_response['errors'][0]['detail']
|
83
87
|
end
|
84
88
|
|
85
89
|
def test_index_filter_by_ids_and_fields_2
|
86
|
-
get :index, {
|
90
|
+
get :index, {filter: {id: '1,2'}, 'fields' => 'author'}
|
87
91
|
assert_response :success
|
88
|
-
assert_equal 2, json_response['
|
92
|
+
assert_equal 2, json_response['data'].size
|
89
93
|
|
90
|
-
# links
|
91
|
-
assert_equal
|
92
|
-
assert json_response['
|
94
|
+
# links, id, type
|
95
|
+
assert_equal 3, json_response['data'][0].size
|
96
|
+
assert json_response['data'][0].has_key?('type')
|
97
|
+
assert json_response['data'][0].has_key?('id')
|
98
|
+
assert json_response['data'][0]['links'].has_key?('author')
|
93
99
|
end
|
94
100
|
|
95
101
|
def test_filter_association_single
|
96
|
-
get :index, {tags: '5,1'}
|
102
|
+
get :index, {filter: {tags: '5,1'}}
|
97
103
|
assert_response :success
|
98
|
-
assert_equal 3, json_response['
|
104
|
+
assert_equal 3, json_response['data'].size
|
99
105
|
assert_match /New post/, response.body
|
100
106
|
assert_match /JR Solves your serialization woes!/, response.body
|
101
107
|
assert_match /JR How To/, response.body
|
102
108
|
end
|
103
109
|
|
104
110
|
def test_filter_associations_multiple
|
105
|
-
get :index, {tags: '5,1', comments: '3'}
|
111
|
+
get :index, {filter: {tags: '5,1', comments: '3'}}
|
106
112
|
assert_response :success
|
107
|
-
assert_equal 1, json_response['
|
113
|
+
assert_equal 1, json_response['data'].size
|
108
114
|
assert_match /JR Solves your serialization woes!/, response.body
|
109
115
|
end
|
110
116
|
|
111
117
|
def test_filter_associations_multiple_not_found
|
112
|
-
get :index, {tags: '1', comments: '3'}
|
118
|
+
get :index, {filter: {tags: '1', comments: '3'}}
|
113
119
|
assert_response :success
|
114
|
-
assert_equal 0, json_response['
|
120
|
+
assert_equal 0, json_response['data'].size
|
115
121
|
end
|
116
122
|
|
117
123
|
def test_bad_filter
|
118
|
-
get :index, {post_ids: '1,2'}
|
124
|
+
get :index, {filter: {post_ids: '1,2'}}
|
119
125
|
assert_response :bad_request
|
120
126
|
assert_match /post_ids is not allowed/, response.body
|
121
127
|
end
|
122
128
|
|
123
129
|
def test_bad_filter_value_not_integer_array
|
124
|
-
get :index, {
|
130
|
+
get :index, {filter: {id: 'asdfg'}}
|
125
131
|
assert_response :bad_request
|
126
132
|
assert_match /asdfg is not a valid value for id/, response.body
|
127
133
|
end
|
128
134
|
|
129
135
|
def test_bad_filter_value_not_integer
|
130
|
-
get :index, {id: 'asdfg'}
|
136
|
+
get :index, {filter: {id: 'asdfg'}}
|
131
137
|
assert_response :bad_request
|
132
138
|
assert_match /asdfg is not a valid value for id/, response.body
|
133
139
|
end
|
134
140
|
|
135
141
|
def test_bad_filter_value_not_found_array
|
136
|
-
get :index, {
|
142
|
+
get :index, {filter: {id: '5412333'}}
|
137
143
|
assert_response :not_found
|
138
144
|
assert_match /5412333 could not be found/, response.body
|
139
145
|
end
|
140
146
|
|
141
147
|
def test_bad_filter_value_not_found
|
142
|
-
get :index, {id: '5412333'}
|
148
|
+
get :index, {filter: {id: '5412333'}}
|
143
149
|
assert_response :not_found
|
144
150
|
assert_match /5412333 could not be found/, json_response['errors'][0]['detail']
|
145
151
|
end
|
146
152
|
|
147
153
|
def test_index_malformed_fields
|
148
|
-
get :index, {
|
154
|
+
get :index, {filter: {id: '1,2'}, 'fields' => 'posts'}
|
149
155
|
assert_response :bad_request
|
150
156
|
assert_match /posts is not a valid field for posts./, json_response['errors'][0]['detail']
|
151
157
|
end
|
152
158
|
|
153
159
|
def test_field_not_supported
|
154
|
-
get :index, {
|
160
|
+
get :index, {filter: {id: '1,2'}, 'fields' => {'posts' => 'id,title,rank,author'}}
|
155
161
|
assert_response :bad_request
|
156
162
|
assert_match /rank is not a valid field for posts./, json_response['errors'][0]['detail']
|
157
163
|
end
|
158
164
|
|
159
165
|
def test_resource_not_supported
|
160
|
-
get :index, {
|
166
|
+
get :index, {filter: {id: '1,2'}, 'fields' => {'posters' => 'id,title'}}
|
161
167
|
assert_response :bad_request
|
162
168
|
assert_match /posters is not a valid resource./, json_response['errors'][0]['detail']
|
163
169
|
end
|
164
170
|
|
165
171
|
def test_index_filter_on_association
|
166
|
-
get :index, {author: '1'}
|
172
|
+
get :index, {filter: {author: '1'}}
|
167
173
|
assert_response :success
|
168
|
-
assert_equal 3, json_response['
|
174
|
+
assert_equal 3, json_response['data'].size
|
169
175
|
end
|
170
176
|
|
171
177
|
def test_sorting_asc
|
172
|
-
get :index, {sort: 'title'}
|
178
|
+
get :index, {sort: '+title'}
|
173
179
|
|
174
180
|
assert_response :success
|
175
|
-
assert_equal "Delete This Later - Multiple2-1", json_response['
|
181
|
+
assert_equal "Delete This Later - Multiple2-1", json_response['data'][0]['title']
|
176
182
|
end
|
177
183
|
|
178
184
|
def test_sorting_desc
|
179
185
|
get :index, {sort: '-title'}
|
180
186
|
|
181
187
|
assert_response :success
|
182
|
-
assert_equal "Update This Later - Multiple", json_response['
|
188
|
+
assert_equal "Update This Later - Multiple", json_response['data'][0]['title']
|
183
189
|
end
|
184
190
|
|
185
191
|
def test_sorting_by_multiple_fields
|
186
|
-
get :index, {sort: 'title
|
192
|
+
get :index, {sort: '+title,+body'}
|
187
193
|
|
188
194
|
assert_response :success
|
189
|
-
assert_equal '8', json_response['
|
195
|
+
assert_equal '8', json_response['data'][0]['id']
|
190
196
|
end
|
191
197
|
|
192
198
|
def test_invalid_sort_param
|
193
|
-
get :index, {sort: 'asdfg'}
|
199
|
+
get :index, {sort: '+asdfg'}
|
200
|
+
|
201
|
+
assert_response :bad_request
|
202
|
+
assert_match /asdfg is not a valid sort criteria for post/, response.body
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_invalid_sort_param_missing_direction
|
206
|
+
get :index, {sort: 'title'}
|
194
207
|
|
195
208
|
assert_response :bad_request
|
196
|
-
assert_match /
|
209
|
+
assert_match /title must start with a direction/, response.body
|
197
210
|
end
|
198
211
|
|
199
212
|
def test_excluded_sort_param
|
200
|
-
get :index, {sort: 'id'}
|
213
|
+
get :index, {sort: '+id'}
|
201
214
|
|
202
215
|
assert_response :bad_request
|
203
|
-
assert_match /id is not a valid sort
|
216
|
+
assert_match /id is not a valid sort criteria for post/, response.body
|
204
217
|
end
|
205
218
|
|
206
219
|
# ToDo: test validating the parameter values
|
@@ -212,33 +225,30 @@ class PostsControllerTest < ActionController::TestCase
|
|
212
225
|
def test_show_single
|
213
226
|
get :show, {id: '1'}
|
214
227
|
assert_response :success
|
215
|
-
assert json_response['
|
216
|
-
assert_equal 'New post', json_response['
|
217
|
-
assert_equal 'A body!!!', json_response['
|
218
|
-
assert_equal ['1', '2', '3'], json_response['posts']['links']['tags']
|
219
|
-
assert_equal ['1', '2'], json_response['posts']['links']['comments']
|
228
|
+
assert json_response['data'].is_a?(Hash)
|
229
|
+
assert_equal 'New post', json_response['data']['title']
|
230
|
+
assert_equal 'A body!!!', json_response['data']['body']
|
220
231
|
assert_nil json_response['linked']
|
221
232
|
end
|
222
233
|
|
223
234
|
def test_show_single_with_includes
|
224
235
|
get :show, {id: '1', include: 'comments'}
|
225
236
|
assert_response :success
|
226
|
-
assert json_response['
|
227
|
-
assert_equal 'New post', json_response['
|
228
|
-
assert_equal 'A body!!!', json_response['
|
229
|
-
|
230
|
-
assert_equal ['1', '2'], json_response['
|
231
|
-
assert_equal 2, json_response['linked']
|
232
|
-
assert_nil json_response['linked']['tags']
|
237
|
+
assert json_response['data'].is_a?(Hash)
|
238
|
+
assert_equal 'New post', json_response['data']['title']
|
239
|
+
assert_equal 'A body!!!', json_response['data']['body']
|
240
|
+
assert_nil json_response['data']['links']['tags']['ids']
|
241
|
+
assert_equal ['1', '2'], json_response['data']['links']['comments']['ids']
|
242
|
+
assert_equal 2, json_response['linked'].size
|
233
243
|
end
|
234
244
|
|
235
245
|
def test_show_single_with_fields
|
236
246
|
get :show, {id: '1', fields: 'author'}
|
237
247
|
assert_response :success
|
238
|
-
assert json_response['
|
239
|
-
assert_nil json_response['
|
240
|
-
assert_nil json_response['
|
241
|
-
assert_equal '1', json_response['
|
248
|
+
assert json_response['data'].is_a?(Hash)
|
249
|
+
assert_nil json_response['data']['title']
|
250
|
+
assert_nil json_response['data']['body']
|
251
|
+
assert_equal '1', json_response['data']['links']['author']['id']
|
242
252
|
end
|
243
253
|
|
244
254
|
def test_show_single_invalid_id_format
|
@@ -269,31 +279,33 @@ class PostsControllerTest < ActionController::TestCase
|
|
269
279
|
set_content_type_header!
|
270
280
|
post :create,
|
271
281
|
{
|
272
|
-
|
282
|
+
data: {
|
283
|
+
type: 'posts',
|
273
284
|
title: 'JR is Great',
|
274
285
|
body: 'JSONAPIResources is the greatest thing since unsliced bread.',
|
275
286
|
links: {
|
276
|
-
author: 3
|
287
|
+
author: {type: 'people', id: '3'}
|
277
288
|
}
|
278
289
|
}
|
279
290
|
}
|
280
291
|
|
281
292
|
assert_response :created
|
282
|
-
assert json_response['
|
283
|
-
assert_equal '3', json_response['
|
284
|
-
assert_equal 'JR is Great', json_response['
|
285
|
-
assert_equal 'JSONAPIResources is the greatest thing since unsliced bread.', json_response['
|
293
|
+
assert json_response['data'].is_a?(Hash)
|
294
|
+
assert_equal '3', json_response['data']['links']['author']['id']
|
295
|
+
assert_equal 'JR is Great', json_response['data']['title']
|
296
|
+
assert_equal 'JSONAPIResources is the greatest thing since unsliced bread.', json_response['data']['body']
|
286
297
|
end
|
287
298
|
|
288
299
|
def test_create_link_to_missing_object
|
289
300
|
set_content_type_header!
|
290
301
|
post :create,
|
291
302
|
{
|
292
|
-
|
303
|
+
data: {
|
304
|
+
type: 'posts',
|
293
305
|
title: 'JR is Great',
|
294
306
|
body: 'JSONAPIResources is the greatest thing since unsliced bread.',
|
295
307
|
links: {
|
296
|
-
author: 304567
|
308
|
+
author: {type: 'people', id: '304567'}
|
297
309
|
}
|
298
310
|
}
|
299
311
|
}
|
@@ -307,12 +319,13 @@ class PostsControllerTest < ActionController::TestCase
|
|
307
319
|
set_content_type_header!
|
308
320
|
post :create,
|
309
321
|
{
|
310
|
-
|
322
|
+
data: {
|
323
|
+
type: 'posts',
|
311
324
|
asdfg: 'aaaa',
|
312
325
|
title: 'JR is Great',
|
313
326
|
body: 'JSONAPIResources is the greatest thing since unsliced bread.',
|
314
327
|
links: {
|
315
|
-
author: 3
|
328
|
+
author: {type: 'people', id: '3'}
|
316
329
|
}
|
317
330
|
}
|
318
331
|
}
|
@@ -325,7 +338,8 @@ class PostsControllerTest < ActionController::TestCase
|
|
325
338
|
set_content_type_header!
|
326
339
|
post :create,
|
327
340
|
{
|
328
|
-
|
341
|
+
data: {
|
342
|
+
type: 'posts',
|
329
343
|
title: 'JSONAPIResources is the greatest thing...',
|
330
344
|
body: 'JSONAPIResources is the greatest thing since unsliced bread.',
|
331
345
|
links: {
|
@@ -349,28 +363,30 @@ class PostsControllerTest < ActionController::TestCase
|
|
349
363
|
set_content_type_header!
|
350
364
|
post :create,
|
351
365
|
{
|
352
|
-
|
366
|
+
data: [
|
353
367
|
{
|
368
|
+
type: 'posts',
|
354
369
|
title: 'JR is Great',
|
355
370
|
body: 'JSONAPIResources is the greatest thing since unsliced bread.',
|
356
371
|
links: {
|
357
|
-
author: 3
|
372
|
+
author: {type: 'people', id: '3'}
|
358
373
|
}
|
359
374
|
},
|
360
375
|
{
|
376
|
+
type: 'posts',
|
361
377
|
title: 'Ember is Great',
|
362
378
|
body: 'Ember is the greatest thing since unsliced bread.',
|
363
379
|
links: {
|
364
|
-
author: 3
|
380
|
+
author: {type: 'people', id: '3'}
|
365
381
|
}
|
366
382
|
}
|
367
383
|
]
|
368
384
|
}
|
369
385
|
|
370
386
|
assert_response :created
|
371
|
-
assert json_response['
|
372
|
-
assert_equal json_response['
|
373
|
-
assert_equal json_response['
|
387
|
+
assert json_response['data'].is_a?(Array)
|
388
|
+
assert_equal json_response['data'].size, 2
|
389
|
+
assert_equal json_response['data'][0]['links']['author']['id'], '3'
|
374
390
|
assert_match /JR is Great/, response.body
|
375
391
|
assert_match /Ember is Great/, response.body
|
376
392
|
end
|
@@ -379,19 +395,21 @@ class PostsControllerTest < ActionController::TestCase
|
|
379
395
|
set_content_type_header!
|
380
396
|
post :create,
|
381
397
|
{
|
382
|
-
|
398
|
+
data: [
|
383
399
|
{
|
400
|
+
type: 'posts',
|
384
401
|
Title: 'JR is Great',
|
385
402
|
body: 'JSONAPIResources is the greatest thing since unsliced bread.',
|
386
403
|
links: {
|
387
|
-
author: 3
|
404
|
+
author: {type: 'people', id: '3'}
|
388
405
|
}
|
389
406
|
},
|
390
407
|
{
|
408
|
+
type: 'posts',
|
391
409
|
title: 'Ember is Great',
|
392
410
|
BODY: 'Ember is the greatest thing since unsliced bread.',
|
393
411
|
links: {
|
394
|
-
author: 3
|
412
|
+
author: {type: 'people', id: '3'}
|
395
413
|
}
|
396
414
|
}
|
397
415
|
]
|
@@ -405,28 +423,65 @@ class PostsControllerTest < ActionController::TestCase
|
|
405
423
|
set_content_type_header!
|
406
424
|
post :create,
|
407
425
|
{
|
408
|
-
|
426
|
+
data_spelled_wrong: {
|
427
|
+
type: 'posts',
|
428
|
+
title: 'JR is Great',
|
429
|
+
body: 'JSONAPIResources is the greatest thing since unsliced bread.',
|
430
|
+
links: {
|
431
|
+
author: {type: 'people', id: '3'}
|
432
|
+
}
|
433
|
+
}
|
434
|
+
}
|
435
|
+
|
436
|
+
assert_response :bad_request
|
437
|
+
assert_match /The required parameter, data, is missing./, json_response['errors'][0]['detail']
|
438
|
+
end
|
439
|
+
|
440
|
+
def test_create_simple_wrong_type
|
441
|
+
set_content_type_header!
|
442
|
+
post :create,
|
443
|
+
{
|
444
|
+
data: {
|
445
|
+
type: 'posts_spelled_wrong',
|
446
|
+
title: 'JR is Great',
|
447
|
+
body: 'JSONAPIResources is the greatest thing since unsliced bread.',
|
448
|
+
links: {
|
449
|
+
author: {type: 'people', id: '3'}
|
450
|
+
}
|
451
|
+
}
|
452
|
+
}
|
453
|
+
|
454
|
+
assert_response :bad_request
|
455
|
+
assert_match /posts_spelled_wrong is not a valid resource./, json_response['errors'][0]['detail']
|
456
|
+
end
|
457
|
+
|
458
|
+
def test_create_simple_missing_type
|
459
|
+
set_content_type_header!
|
460
|
+
post :create,
|
461
|
+
{
|
462
|
+
data: {
|
409
463
|
title: 'JR is Great',
|
410
464
|
body: 'JSONAPIResources is the greatest thing since unsliced bread.',
|
411
465
|
links: {
|
412
|
-
author: 3
|
466
|
+
author: {type: 'people', id: '3'}
|
413
467
|
}
|
414
468
|
}
|
415
469
|
}
|
416
470
|
|
417
471
|
assert_response :bad_request
|
418
|
-
assert_match /The required parameter,
|
472
|
+
assert_match /The required parameter, type, is missing./, json_response['errors'][0]['detail']
|
419
473
|
end
|
420
474
|
|
421
475
|
def test_create_simple_unpermitted_attributes
|
422
476
|
set_content_type_header!
|
423
477
|
post :create,
|
424
478
|
{
|
425
|
-
|
479
|
+
data: {
|
480
|
+
type: 'posts',
|
426
481
|
subject: 'JR is Great',
|
427
482
|
body: 'JSONAPIResources is the greatest thing since unsliced bread.',
|
428
483
|
links: {
|
429
|
-
author: 3
|
484
|
+
author: {type: 'people', id: '3'}
|
430
485
|
}
|
431
486
|
}
|
432
487
|
}
|
@@ -435,38 +490,61 @@ class PostsControllerTest < ActionController::TestCase
|
|
435
490
|
assert_match /subject/, json_response['errors'][0]['detail']
|
436
491
|
end
|
437
492
|
|
438
|
-
def
|
493
|
+
def test_create_with_links_has_many_type_ids
|
439
494
|
set_content_type_header!
|
440
495
|
post :create,
|
441
496
|
{
|
442
|
-
|
497
|
+
data: {
|
498
|
+
type: 'posts',
|
443
499
|
title: 'JR is Great',
|
444
500
|
body: 'JSONAPIResources is the greatest thing since unsliced bread.',
|
445
501
|
links: {
|
446
|
-
author: 3,
|
447
|
-
tags: [3, 4]
|
502
|
+
author: {type: 'people', id: '3'},
|
503
|
+
tags: {type: 'tags', ids: [3, 4]}
|
448
504
|
}
|
449
505
|
}
|
450
506
|
}
|
451
507
|
|
452
508
|
assert_response :created
|
453
|
-
assert json_response['
|
454
|
-
assert_equal '3', json_response['
|
455
|
-
assert_equal 'JR is Great', json_response['
|
456
|
-
assert_equal 'JSONAPIResources is the greatest thing since unsliced bread.', json_response['
|
457
|
-
|
509
|
+
assert json_response['data'].is_a?(Hash)
|
510
|
+
assert_equal '3', json_response['data']['links']['author']['id']
|
511
|
+
assert_equal 'JR is Great', json_response['data']['title']
|
512
|
+
assert_equal 'JSONAPIResources is the greatest thing since unsliced bread.', json_response['data']['body']
|
513
|
+
end
|
514
|
+
|
515
|
+
def test_create_with_links_has_many_array
|
516
|
+
set_content_type_header!
|
517
|
+
post :create,
|
518
|
+
{
|
519
|
+
data: {
|
520
|
+
type: 'posts',
|
521
|
+
title: 'JR is Great',
|
522
|
+
body: 'JSONAPIResources is the greatest thing since unsliced bread.',
|
523
|
+
links: {
|
524
|
+
author: {type: 'people', id: '3'},
|
525
|
+
tags: [{type: 'tags', id: '3'}, {type: 'tags', id: '4'}]
|
526
|
+
}
|
527
|
+
}
|
528
|
+
}
|
529
|
+
|
530
|
+
assert_response :created
|
531
|
+
assert json_response['data'].is_a?(Hash)
|
532
|
+
assert_equal '3', json_response['data']['links']['author']['id']
|
533
|
+
assert_equal 'JR is Great', json_response['data']['title']
|
534
|
+
assert_equal 'JSONAPIResources is the greatest thing since unsliced bread.', json_response['data']['body']
|
458
535
|
end
|
459
536
|
|
460
537
|
def test_create_with_links_include_and_fields
|
461
538
|
set_content_type_header!
|
462
539
|
post :create,
|
463
540
|
{
|
464
|
-
|
541
|
+
data: {
|
542
|
+
type: 'posts',
|
465
543
|
title: 'JR is Great!',
|
466
544
|
body: 'JSONAPIResources is the greatest thing since unsliced bread!',
|
467
545
|
links: {
|
468
|
-
author: 3,
|
469
|
-
tags: [3, 4]
|
546
|
+
author: {type: 'people', id: '3'},
|
547
|
+
tags: {type: 'tags', ids: [3, 4]}
|
470
548
|
}
|
471
549
|
},
|
472
550
|
include: 'author,author.posts',
|
@@ -474,14 +552,10 @@ class PostsControllerTest < ActionController::TestCase
|
|
474
552
|
}
|
475
553
|
|
476
554
|
assert_response :created
|
477
|
-
assert json_response['
|
478
|
-
assert_equal '3', json_response['
|
479
|
-
assert_equal 'JR is Great!', json_response['
|
480
|
-
|
481
|
-
assert_equal nil, json_response['posts']['links']['tags']
|
482
|
-
assert_not_nil json_response['linked']['posts']
|
483
|
-
assert_not_nil json_response['linked']['people']
|
484
|
-
assert_nil json_response['linked']['tags']
|
555
|
+
assert json_response['data'].is_a?(Hash)
|
556
|
+
assert_equal '3', json_response['data']['links']['author']['id']
|
557
|
+
assert_equal 'JR is Great!', json_response['data']['title']
|
558
|
+
assert_not_nil json_response['linked'].size
|
485
559
|
end
|
486
560
|
|
487
561
|
def test_update_with_links
|
@@ -491,22 +565,25 @@ class PostsControllerTest < ActionController::TestCase
|
|
491
565
|
put :update,
|
492
566
|
{
|
493
567
|
id: 3,
|
494
|
-
|
568
|
+
data: {
|
569
|
+
id: '3',
|
570
|
+
type: 'posts',
|
495
571
|
title: 'A great new Post',
|
496
572
|
links: {
|
497
|
-
section: javascript.id,
|
498
|
-
tags: [3, 4]
|
573
|
+
section: {type: 'sections', id: "#{javascript.id}"},
|
574
|
+
tags: {type: 'tags', ids: [3, 4]}
|
499
575
|
}
|
500
|
-
}
|
576
|
+
},
|
577
|
+
include: 'tags'
|
501
578
|
}
|
502
579
|
|
503
580
|
assert_response :success
|
504
|
-
assert json_response['
|
505
|
-
assert_equal '3', json_response['
|
506
|
-
assert_equal javascript.id.to_s, json_response['
|
507
|
-
assert_equal 'A great new Post', json_response['
|
508
|
-
assert_equal 'AAAA', json_response['
|
509
|
-
assert matches_array?(['3', '4'], json_response['
|
581
|
+
assert json_response['data'].is_a?(Hash)
|
582
|
+
assert_equal '3', json_response['data']['links']['author']['id']
|
583
|
+
assert_equal javascript.id.to_s, json_response['data']['links']['section']['id']
|
584
|
+
assert_equal 'A great new Post', json_response['data']['title']
|
585
|
+
assert_equal 'AAAA', json_response['data']['body']
|
586
|
+
assert matches_array?(['3', '4'], json_response['data']['links']['tags']['ids'])
|
510
587
|
end
|
511
588
|
|
512
589
|
def test_update_remove_links
|
@@ -514,22 +591,25 @@ class PostsControllerTest < ActionController::TestCase
|
|
514
591
|
put :update,
|
515
592
|
{
|
516
593
|
id: 3,
|
517
|
-
|
594
|
+
data: {
|
595
|
+
type: 'posts',
|
596
|
+
id: 3,
|
518
597
|
title: 'A great new Post',
|
519
598
|
links: {
|
520
599
|
section: nil,
|
521
600
|
tags: []
|
522
601
|
}
|
523
|
-
}
|
602
|
+
},
|
603
|
+
include: 'tags'
|
524
604
|
}
|
525
605
|
|
526
606
|
assert_response :success
|
527
|
-
assert json_response['
|
528
|
-
assert_equal '3', json_response['
|
529
|
-
assert_equal nil, json_response['
|
530
|
-
assert_equal 'A great new Post', json_response['
|
531
|
-
assert_equal 'AAAA', json_response['
|
532
|
-
assert matches_array?([], json_response['
|
607
|
+
assert json_response['data'].is_a?(Hash)
|
608
|
+
assert_equal '3', json_response['data']['links']['author']['id']
|
609
|
+
assert_equal nil, json_response['data']['links']['section']['id']
|
610
|
+
assert_equal 'A great new Post', json_response['data']['title']
|
611
|
+
assert_equal 'AAAA', json_response['data']['body']
|
612
|
+
assert matches_array?([], json_response['data']['links']['tags']['ids'])
|
533
613
|
end
|
534
614
|
|
535
615
|
def test_update_relationship_has_one
|
@@ -538,82 +618,148 @@ class PostsControllerTest < ActionController::TestCase
|
|
538
618
|
post_object = Post.find(3)
|
539
619
|
assert_not_equal ruby.id, post_object.section_id
|
540
620
|
|
541
|
-
put :update_association, {post_id: 3, association: 'section', sections: ruby.id}
|
621
|
+
put :update_association, {post_id: 3, association: 'section', data: {type: 'sections', id: "#{ruby.id}"}}
|
542
622
|
|
543
623
|
assert_response :no_content
|
544
624
|
post_object = Post.find(3)
|
545
625
|
assert_equal ruby.id, post_object.section_id
|
546
626
|
end
|
547
627
|
|
548
|
-
def
|
628
|
+
def test_update_relationship_has_one_invalid_links_hash_keys_ids
|
549
629
|
set_content_type_header!
|
550
|
-
|
551
|
-
|
630
|
+
put :update_association, {post_id: 3, association: 'section', data: {types: 'sections', ids: 'foo'}}
|
631
|
+
|
632
|
+
assert_response :bad_request
|
633
|
+
assert_match /Invalid Links Object/, response.body
|
634
|
+
end
|
635
|
+
|
636
|
+
def test_update_relationship_has_one_invalid_links_hash_count
|
637
|
+
set_content_type_header!
|
638
|
+
put :update_association, {post_id: 3, association: 'section', data: {types: 'sections'}}
|
639
|
+
|
640
|
+
assert_response :bad_request
|
641
|
+
assert_match /Invalid Links Object/, response.body
|
642
|
+
end
|
552
643
|
|
553
|
-
|
644
|
+
def test_update_relationship_has_one_invalid_links_hash_keys_type_mismatch
|
645
|
+
set_content_type_header!
|
646
|
+
put :update_association, {post_id: 3, association: 'section', data: {type: 'comment', id: '3'}}
|
554
647
|
|
555
648
|
assert_response :bad_request
|
649
|
+
assert_match /Type Mismatch/, response.body
|
556
650
|
end
|
557
651
|
|
558
|
-
def
|
652
|
+
def test_update_nil_has_many_links
|
653
|
+
set_content_type_header!
|
654
|
+
put :update,
|
655
|
+
{
|
656
|
+
id: 3,
|
657
|
+
data: {
|
658
|
+
type: 'posts',
|
659
|
+
id: 3,
|
660
|
+
links: {
|
661
|
+
tags: nil
|
662
|
+
}
|
663
|
+
}
|
664
|
+
}
|
665
|
+
|
666
|
+
assert_response :bad_request
|
667
|
+
assert_match /Invalid Links Object/, response.body
|
668
|
+
end
|
669
|
+
|
670
|
+
def test_update_bad_hash_has_many_links
|
671
|
+
set_content_type_header!
|
672
|
+
put :update,
|
673
|
+
{
|
674
|
+
id: 3,
|
675
|
+
data: {
|
676
|
+
type: 'posts',
|
677
|
+
id: 3,
|
678
|
+
links: {
|
679
|
+
tags: {typ: 'bad link', idd: 'as'}
|
680
|
+
}
|
681
|
+
}
|
682
|
+
}
|
683
|
+
|
684
|
+
assert_response :bad_request
|
685
|
+
assert_match /Invalid Links Object/, response.body
|
686
|
+
end
|
687
|
+
|
688
|
+
def test_update_other_has_many_links
|
689
|
+
set_content_type_header!
|
690
|
+
put :update,
|
691
|
+
{
|
692
|
+
id: 3,
|
693
|
+
data: {
|
694
|
+
type: 'posts',
|
695
|
+
id: 3,
|
696
|
+
links: {
|
697
|
+
tags: 'bad link'
|
698
|
+
}
|
699
|
+
}
|
700
|
+
}
|
701
|
+
|
702
|
+
assert_response :bad_request
|
703
|
+
assert_match /Invalid Links Object/, response.body
|
704
|
+
end
|
705
|
+
|
706
|
+
def test_update_relationship_has_one_singular_param_id_nil
|
559
707
|
set_content_type_header!
|
560
708
|
ruby = Section.find_by(name: 'ruby')
|
561
709
|
post_object = Post.find(3)
|
562
|
-
post_object.section_id =
|
710
|
+
post_object.section_id = ruby.id
|
563
711
|
post_object.save!
|
564
712
|
|
565
|
-
put :update_association, {post_id: 3, association: 'section', sections:
|
713
|
+
put :update_association, {post_id: 3, association: 'section', data: {type: 'sections', id: nil}}
|
566
714
|
|
567
715
|
assert_response :no_content
|
568
716
|
post_object = Post.find(3)
|
569
|
-
assert_equal
|
717
|
+
assert_equal nil, post_object.section_id
|
570
718
|
end
|
571
719
|
|
572
|
-
def
|
720
|
+
def test_remove_relationship_has_one
|
573
721
|
set_content_type_header!
|
574
722
|
ruby = Section.find_by(name: 'ruby')
|
575
723
|
post_object = Post.find(3)
|
576
|
-
post_object.section_id =
|
724
|
+
post_object.section_id = ruby.id
|
577
725
|
post_object.save!
|
578
726
|
|
579
|
-
|
727
|
+
put :destroy_association, {post_id: 3, association: 'section'}
|
580
728
|
|
581
729
|
assert_response :no_content
|
582
730
|
post_object = Post.find(3)
|
583
|
-
assert_equal
|
731
|
+
assert_equal nil, post_object.section_id
|
584
732
|
end
|
585
733
|
|
586
|
-
def
|
734
|
+
def test_update_relationship_has_one_singular_param
|
587
735
|
set_content_type_header!
|
588
736
|
ruby = Section.find_by(name: 'ruby')
|
589
|
-
js = Section.find_by(name: 'javascript')
|
590
737
|
post_object = Post.find(3)
|
591
|
-
post_object.section_id =
|
738
|
+
post_object.section_id = nil
|
592
739
|
post_object.save!
|
593
740
|
|
594
|
-
|
741
|
+
put :update_association, {post_id: 3, association: 'section', data: {type: 'sections', id: "#{ruby.id}"}}
|
595
742
|
|
596
|
-
assert_response :
|
597
|
-
assert_match /The relation already exists./, response.body
|
743
|
+
assert_response :no_content
|
598
744
|
post_object = Post.find(3)
|
599
|
-
assert_equal
|
745
|
+
assert_equal ruby.id, post_object.section_id
|
600
746
|
end
|
601
747
|
|
602
748
|
def test_update_relationship_has_many_join_table_single
|
603
749
|
set_content_type_header!
|
604
|
-
put :update_association, {post_id: 3, association: 'tags', tags: []}
|
750
|
+
put :update_association, {post_id: 3, association: 'tags', data: {type: 'tags', ids: []}}
|
605
751
|
assert_response :no_content
|
606
752
|
|
607
753
|
post_object = Post.find(3)
|
608
754
|
assert_equal 0, post_object.tags.length
|
609
755
|
|
610
|
-
put :update_association, {post_id: 3, association: 'tags', tags: [2]}
|
756
|
+
put :update_association, {post_id: 3, association: 'tags', data: {type: 'tags', ids: [2]}}
|
611
757
|
|
612
758
|
assert_response :no_content
|
613
759
|
post_object = Post.find(3)
|
614
760
|
assert_equal 1, post_object.tags.length
|
615
761
|
|
616
|
-
put :update_association, {post_id: 3, association: 'tags', tags: 5}
|
762
|
+
put :update_association, {post_id: 3, association: 'tags', data: {type: 'tags', ids: [5]}}
|
617
763
|
|
618
764
|
assert_response :no_content
|
619
765
|
post_object = Post.find(3)
|
@@ -622,9 +768,19 @@ class PostsControllerTest < ActionController::TestCase
|
|
622
768
|
assert matches_array? [5], tags
|
623
769
|
end
|
624
770
|
|
625
|
-
def
|
771
|
+
def test_update_relationship_has_many_join_table_homogenous
|
772
|
+
set_content_type_header!
|
773
|
+
put :update_association, {post_id: 3, association: 'tags', data: {type: 'tags', ids: [2, 3]}}
|
774
|
+
|
775
|
+
assert_response :no_content
|
776
|
+
post_object = Post.find(3)
|
777
|
+
assert_equal 2, post_object.tags.collect { |tag| tag.id }.length
|
778
|
+
assert matches_array? [2, 3], post_object.tags.collect { |tag| tag.id }
|
779
|
+
end
|
780
|
+
|
781
|
+
def test_update_relationship_has_many_join_table_heterogenous
|
626
782
|
set_content_type_header!
|
627
|
-
put :update_association, {post_id: 3, association: 'tags', tags:
|
783
|
+
put :update_association, {post_id: 3, association: 'tags', data: [{type: 'tags', id: 2}, {type: 'tags', id: 3}]}
|
628
784
|
|
629
785
|
assert_response :no_content
|
630
786
|
post_object = Post.find(3)
|
@@ -634,14 +790,14 @@ class PostsControllerTest < ActionController::TestCase
|
|
634
790
|
|
635
791
|
def test_create_relationship_has_many_join_table
|
636
792
|
set_content_type_header!
|
637
|
-
put :update_association, {post_id: 3, association: 'tags', tags: [2, 3]}
|
793
|
+
put :update_association, {post_id: 3, association: 'tags', data: {type: 'tags', ids: [2, 3]}}
|
638
794
|
|
639
795
|
assert_response :no_content
|
640
796
|
post_object = Post.find(3)
|
641
797
|
assert_equal 2, post_object.tags.collect { |tag| tag.id }.length
|
642
798
|
assert matches_array? [2, 3], post_object.tags.collect { |tag| tag.id }
|
643
799
|
|
644
|
-
post :create_association, {post_id: 3, association: 'tags', tags: [5]}
|
800
|
+
post :create_association, {post_id: 3, association: 'tags', data: {type: 'tags', ids: [5]}}
|
645
801
|
|
646
802
|
assert_response :no_content
|
647
803
|
post_object = Post.find(3)
|
@@ -649,63 +805,62 @@ class PostsControllerTest < ActionController::TestCase
|
|
649
805
|
assert matches_array? [2, 3, 5], post_object.tags.collect { |tag| tag.id }
|
650
806
|
end
|
651
807
|
|
652
|
-
def
|
808
|
+
def test_create_relationship_has_many_mismatched_type
|
809
|
+
set_content_type_header!
|
810
|
+
post :create_association, {post_id: 3, association: 'tags', data: {type: 'comments', ids: [5]}}
|
811
|
+
|
812
|
+
assert_response :bad_request
|
813
|
+
assert_match /Type Mismatch/, response.body
|
814
|
+
end
|
815
|
+
|
816
|
+
def test_create_relationship_has_many_missing_id
|
817
|
+
set_content_type_header!
|
818
|
+
post :create_association, {post_id: 3, association: 'tags', data: {type: 'tags', idds: [5]}}
|
819
|
+
|
820
|
+
assert_response :bad_request
|
821
|
+
assert_match /The required parameter, ids, is missing/, response.body
|
822
|
+
end
|
823
|
+
|
824
|
+
def test_create_relationship_has_many_missing_data
|
653
825
|
set_content_type_header!
|
654
826
|
post :create_association, {post_id: 3, association: 'tags'}
|
655
827
|
|
656
828
|
assert_response :bad_request
|
657
|
-
assert_match /The required parameter,
|
829
|
+
assert_match /The required parameter, data, is missing./, response.body
|
830
|
+
end
|
831
|
+
|
832
|
+
def test_create_relationship_has_many_join
|
833
|
+
set_content_type_header!
|
834
|
+
post :create_association, {post_id: 4, association: 'tags', data: {type: 'tags', ids: [1, 2, 3]}}
|
835
|
+
assert_response :no_content
|
658
836
|
end
|
659
837
|
|
660
838
|
def test_create_relationship_has_many_join_table_record_exists
|
661
839
|
set_content_type_header!
|
662
|
-
put :update_association, {post_id: 3, association: 'tags', tags: [2, 3]}
|
840
|
+
put :update_association, {post_id: 3, association: 'tags', data: {type: 'tags', ids: [2, 3]}}
|
663
841
|
|
664
842
|
assert_response :no_content
|
665
843
|
post_object = Post.find(3)
|
666
844
|
assert_equal 2, post_object.tags.collect { |tag| tag.id }.length
|
667
845
|
assert matches_array? [2, 3], post_object.tags.collect { |tag| tag.id }
|
668
846
|
|
669
|
-
post :create_association, {post_id: 3, association: 'tags', tags: [5, 2]}
|
847
|
+
post :create_association, {post_id: 3, association: 'tags', data: {type: 'tags', ids: [5, 2]}}
|
670
848
|
|
671
849
|
assert_response :bad_request
|
672
850
|
assert_match /The relation to 2 already exists./, response.body
|
673
851
|
end
|
674
852
|
|
675
|
-
def test_update_relationship_has_one_mismatch_params
|
676
|
-
set_content_type_header!
|
677
|
-
post :create_association, {post_id: 3, association: 'section', authors: 1}
|
678
|
-
|
679
|
-
assert_response :bad_request
|
680
|
-
assert_match /The required parameter, sections, is missing./, response.body
|
681
|
-
end
|
682
|
-
|
683
853
|
def test_update_relationship_has_many_missing_tags
|
684
854
|
set_content_type_header!
|
685
855
|
put :update_association, {post_id: 3, association: 'tags'}
|
686
856
|
|
687
857
|
assert_response :bad_request
|
688
|
-
assert_match /The required parameter,
|
689
|
-
end
|
690
|
-
|
691
|
-
def test_delete_relationship_has_one
|
692
|
-
set_content_type_header!
|
693
|
-
ruby = Section.find_by(name: 'ruby')
|
694
|
-
|
695
|
-
post :create_association, {post_id: 9, association: 'section', sections: ruby.id}
|
696
|
-
|
697
|
-
assert_response :no_content
|
698
|
-
|
699
|
-
delete :destroy_association, {post_id: 9, association: 'section'}
|
700
|
-
|
701
|
-
assert_response :no_content
|
702
|
-
post = Post.find(9)
|
703
|
-
assert_nil post.section
|
858
|
+
assert_match /The required parameter, data, is missing./, response.body
|
704
859
|
end
|
705
860
|
|
706
861
|
def test_delete_relationship_has_many
|
707
862
|
set_content_type_header!
|
708
|
-
put :update_association, {post_id: 9, association: 'tags', tags: [2, 3]}
|
863
|
+
put :update_association, {post_id: 9, association: 'tags', data: {type: 'tags', ids: [2, 3]}}
|
709
864
|
assert_response :no_content
|
710
865
|
p = Post.find(9)
|
711
866
|
assert_equal [2, 3], p.tag_ids
|
@@ -719,7 +874,7 @@ class PostsControllerTest < ActionController::TestCase
|
|
719
874
|
|
720
875
|
def test_delete_relationship_has_many_does_not_exist
|
721
876
|
set_content_type_header!
|
722
|
-
put :update_association, {post_id: 9, association: 'tags', tags: [2, 3]}
|
877
|
+
put :update_association, {post_id: 9, association: 'tags', data: {type: 'tags', ids: [2, 3]}}
|
723
878
|
assert_response :no_content
|
724
879
|
p = Post.find(9)
|
725
880
|
assert_equal [2, 3], p.tag_ids
|
@@ -738,12 +893,13 @@ class PostsControllerTest < ActionController::TestCase
|
|
738
893
|
put :update,
|
739
894
|
{
|
740
895
|
id: 3,
|
741
|
-
|
896
|
+
data: {
|
897
|
+
type: 'posts',
|
742
898
|
id: 2,
|
743
899
|
title: 'A great new Post',
|
744
900
|
links: {
|
745
|
-
section: javascript.id,
|
746
|
-
tags: [3, 4]
|
901
|
+
section: {type: 'sections', id: "#{javascript.id}"},
|
902
|
+
tags: {type: 'tags', ids: [3, 4]}
|
747
903
|
}
|
748
904
|
}
|
749
905
|
}
|
@@ -759,12 +915,14 @@ class PostsControllerTest < ActionController::TestCase
|
|
759
915
|
put :update,
|
760
916
|
{
|
761
917
|
id: 3,
|
762
|
-
|
918
|
+
data: {
|
919
|
+
type: 'posts',
|
920
|
+
id: '3',
|
763
921
|
asdfg: 'aaaa',
|
764
922
|
title: 'A great new Post',
|
765
923
|
links: {
|
766
|
-
section: javascript.id,
|
767
|
-
tags: [3, 4]
|
924
|
+
section: {type: 'sections', id: "#{javascript.id}"},
|
925
|
+
tags: {type: 'tags', ids: [3, 4]}
|
768
926
|
}
|
769
927
|
}
|
770
928
|
}
|
@@ -780,12 +938,14 @@ class PostsControllerTest < ActionController::TestCase
|
|
780
938
|
put :update,
|
781
939
|
{
|
782
940
|
id: 3,
|
783
|
-
|
941
|
+
data: {
|
942
|
+
type: 'posts',
|
943
|
+
id: '3',
|
784
944
|
title: 'A great new Post',
|
785
945
|
links: {
|
786
946
|
asdfg: 'aaaa',
|
787
|
-
section: javascript.id,
|
788
|
-
tags: [3, 4]
|
947
|
+
section: {type: 'sections', id: "#{javascript.id}"},
|
948
|
+
tags: {type: 'tags', ids: [3, 4]}
|
789
949
|
}
|
790
950
|
}
|
791
951
|
}
|
@@ -801,17 +961,56 @@ class PostsControllerTest < ActionController::TestCase
|
|
801
961
|
put :update,
|
802
962
|
{
|
803
963
|
id: 3,
|
804
|
-
|
964
|
+
data_spelled_wrong: {
|
965
|
+
type: 'posts',
|
805
966
|
title: 'A great new Post',
|
806
967
|
links: {
|
807
|
-
section: javascript.id,
|
808
|
-
tags: [3, 4]
|
968
|
+
section: {type: 'sections', id: "#{javascript.id}"},
|
969
|
+
tags: {type: 'tags', ids: [3, 4]}
|
809
970
|
}
|
810
971
|
}
|
811
972
|
}
|
812
973
|
|
813
974
|
assert_response :bad_request
|
814
|
-
assert_match /The required parameter,
|
975
|
+
assert_match /The required parameter, data, is missing./, response.body
|
976
|
+
end
|
977
|
+
|
978
|
+
def test_update_missing_key
|
979
|
+
set_content_type_header!
|
980
|
+
|
981
|
+
put :update,
|
982
|
+
{
|
983
|
+
id: 3,
|
984
|
+
data: {
|
985
|
+
type: 'posts',
|
986
|
+
title: 'A great new Post'
|
987
|
+
}
|
988
|
+
}
|
989
|
+
|
990
|
+
assert_response :bad_request
|
991
|
+
assert_match /The resource object does not contain a key/, response.body
|
992
|
+
end
|
993
|
+
|
994
|
+
def test_update_missing_type
|
995
|
+
set_content_type_header!
|
996
|
+
javascript = Section.find_by(name: 'javascript')
|
997
|
+
|
998
|
+
put :update,
|
999
|
+
{
|
1000
|
+
id: 3,
|
1001
|
+
data: {
|
1002
|
+
id: '3',
|
1003
|
+
type_spelled_wrong: 'posts',
|
1004
|
+
title: 'A great new Post',
|
1005
|
+
links: {
|
1006
|
+
section: {type: 'sections', id: "#{javascript.id}"},
|
1007
|
+
tags: {type: 'tags', ids: [3, 4]}
|
1008
|
+
}
|
1009
|
+
}
|
1010
|
+
}
|
1011
|
+
|
1012
|
+
assert_response :bad_request
|
1013
|
+
assert_match /The required parameter, type, is missing./, response.body
|
815
1014
|
end
|
816
1015
|
|
817
1016
|
def test_update_multiple
|
@@ -821,38 +1020,42 @@ class PostsControllerTest < ActionController::TestCase
|
|
821
1020
|
put :update,
|
822
1021
|
{
|
823
1022
|
id: [3, 9],
|
824
|
-
|
1023
|
+
data: [
|
825
1024
|
{
|
1025
|
+
type: 'posts',
|
826
1026
|
id: 3,
|
827
1027
|
title: 'A great new Post QWERTY',
|
828
1028
|
links: {
|
829
|
-
section: javascript.id,
|
830
|
-
tags: [3, 4]
|
1029
|
+
section: {type: 'sections', id: "#{javascript.id}"},
|
1030
|
+
tags: {type: 'tags', ids: [3, 4]}
|
831
1031
|
}
|
832
1032
|
},
|
833
1033
|
{
|
1034
|
+
type: 'posts',
|
834
1035
|
id: 9,
|
835
1036
|
title: 'A great new Post ASDFG',
|
836
1037
|
links: {
|
837
|
-
section: javascript.id,
|
838
|
-
tags: [3, 4]
|
1038
|
+
section: {type: 'sections', id: "#{javascript.id}"},
|
1039
|
+
tags: {type: 'tags', ids: [3, 4]}
|
839
1040
|
}
|
840
1041
|
}
|
841
|
-
]
|
1042
|
+
],
|
1043
|
+
include: 'tags'
|
1044
|
+
}
|
842
1045
|
|
843
1046
|
assert_response :success
|
844
|
-
assert_equal json_response['
|
845
|
-
assert_equal json_response['
|
846
|
-
assert_equal json_response['
|
847
|
-
assert_equal json_response['
|
848
|
-
assert_equal json_response['
|
849
|
-
assert_equal json_response['
|
1047
|
+
assert_equal json_response['data'].size, 2
|
1048
|
+
assert_equal json_response['data'][0]['links']['author']['id'], '3'
|
1049
|
+
assert_equal json_response['data'][0]['links']['section']['id'], javascript.id.to_s
|
1050
|
+
assert_equal json_response['data'][0]['title'], 'A great new Post QWERTY'
|
1051
|
+
assert_equal json_response['data'][0]['body'], 'AAAA'
|
1052
|
+
assert_equal json_response['data'][0]['links']['tags']['ids'], ['3', '4']
|
850
1053
|
|
851
|
-
assert_equal json_response['
|
852
|
-
assert_equal json_response['
|
853
|
-
assert_equal json_response['
|
854
|
-
assert_equal json_response['
|
855
|
-
assert_equal json_response['
|
1054
|
+
assert_equal json_response['data'][1]['links']['author']['id'], '3'
|
1055
|
+
assert_equal json_response['data'][1]['links']['section']['id'], javascript.id.to_s
|
1056
|
+
assert_equal json_response['data'][1]['title'], 'A great new Post ASDFG'
|
1057
|
+
assert_equal json_response['data'][1]['body'], 'AAAA'
|
1058
|
+
assert_equal json_response['data'][1]['links']['tags']['ids'], ['3', '4']
|
856
1059
|
end
|
857
1060
|
|
858
1061
|
def test_update_multiple_missing_keys
|
@@ -862,19 +1065,21 @@ class PostsControllerTest < ActionController::TestCase
|
|
862
1065
|
put :update,
|
863
1066
|
{
|
864
1067
|
id: [3, 9],
|
865
|
-
|
1068
|
+
data: [
|
866
1069
|
{
|
1070
|
+
type: 'posts',
|
867
1071
|
title: 'A great new Post ASDFG',
|
868
1072
|
links: {
|
869
|
-
section: javascript.id,
|
870
|
-
tags: [3, 4]
|
1073
|
+
section: {type: 'sections', id: "#{javascript.id}"},
|
1074
|
+
tags: {type: 'tags', ids: [3, 4]}
|
871
1075
|
}
|
872
1076
|
},
|
873
1077
|
{
|
1078
|
+
type: 'posts',
|
874
1079
|
title: 'A great new Post QWERTY',
|
875
1080
|
links: {
|
876
|
-
section: javascript.id,
|
877
|
-
tags: [3, 4]
|
1081
|
+
section: {type: 'sections', id: "#{javascript.id}"},
|
1082
|
+
tags: {type: 'tags', ids: [3, 4]}
|
878
1083
|
}
|
879
1084
|
}
|
880
1085
|
]}
|
@@ -890,21 +1095,23 @@ class PostsControllerTest < ActionController::TestCase
|
|
890
1095
|
put :update,
|
891
1096
|
{
|
892
1097
|
id: [3, 9],
|
893
|
-
|
1098
|
+
data: [
|
894
1099
|
{
|
1100
|
+
type: 'posts',
|
895
1101
|
id: 3,
|
896
1102
|
title: 'A great new Post ASDFG',
|
897
1103
|
links: {
|
898
|
-
section: javascript.id,
|
899
|
-
tags: [3, 4]
|
1104
|
+
section: {type: 'sections', id: "#{javascript.id}"},
|
1105
|
+
tags: {type: 'tags', ids: [3, 4]}
|
900
1106
|
}
|
901
1107
|
},
|
902
1108
|
{
|
1109
|
+
type: 'posts',
|
903
1110
|
id: 8,
|
904
1111
|
title: 'A great new Post QWERTY',
|
905
1112
|
links: {
|
906
|
-
section: javascript.id,
|
907
|
-
tags: [3, 4]
|
1113
|
+
section: {type: 'sections', id: "#{javascript.id}"},
|
1114
|
+
tags: {type: 'tags', ids: [3, 4]}
|
908
1115
|
}
|
909
1116
|
}
|
910
1117
|
]}
|
@@ -920,21 +1127,23 @@ class PostsControllerTest < ActionController::TestCase
|
|
920
1127
|
put :update,
|
921
1128
|
{
|
922
1129
|
id: [3, 9, 2],
|
923
|
-
|
1130
|
+
data: [
|
924
1131
|
{
|
1132
|
+
type: 'posts',
|
925
1133
|
id: 3,
|
926
1134
|
title: 'A great new Post QWERTY',
|
927
1135
|
links: {
|
928
|
-
section: javascript.id,
|
929
|
-
tags: [3, 4]
|
1136
|
+
section: {type: 'sections', id: "#{javascript.id}"},
|
1137
|
+
tags: {type: 'tags', ids: [3, 4]}
|
930
1138
|
}
|
931
1139
|
},
|
932
1140
|
{
|
1141
|
+
type: 'posts',
|
933
1142
|
id: 9,
|
934
1143
|
title: 'A great new Post ASDFG',
|
935
1144
|
links: {
|
936
|
-
section: javascript.id,
|
937
|
-
tags: [3, 4]
|
1145
|
+
section: {type: 'sections', id: "#{javascript.id}"},
|
1146
|
+
tags: {type: 'tags', ids: [3, 4]}
|
938
1147
|
}
|
939
1148
|
}
|
940
1149
|
]}
|
@@ -948,11 +1157,13 @@ class PostsControllerTest < ActionController::TestCase
|
|
948
1157
|
put :update,
|
949
1158
|
{
|
950
1159
|
id: 3,
|
951
|
-
|
1160
|
+
data: {
|
1161
|
+
type: 'posts',
|
1162
|
+
id: '3',
|
952
1163
|
subject: 'A great new Post',
|
953
1164
|
links: {
|
954
|
-
author: 1,
|
955
|
-
tags: [3, 4]
|
1165
|
+
author: {type: 'people', id: '1'},
|
1166
|
+
tags: {type: 'tags', ids: [3, 4]}
|
956
1167
|
}
|
957
1168
|
}
|
958
1169
|
}
|
@@ -967,11 +1178,12 @@ class PostsControllerTest < ActionController::TestCase
|
|
967
1178
|
put :update,
|
968
1179
|
{
|
969
1180
|
id: 3,
|
970
|
-
|
1181
|
+
data: {
|
1182
|
+
type: 'posts',
|
971
1183
|
subject: 'A great new Post',
|
972
1184
|
linked_objects: {
|
973
|
-
author: 1,
|
974
|
-
tags: [3, 4]
|
1185
|
+
author: {type: 'people', id: '1'},
|
1186
|
+
tags: {type: 'tags', ids: [3, 4]}
|
975
1187
|
}
|
976
1188
|
}
|
977
1189
|
}
|
@@ -1010,37 +1222,51 @@ class PostsControllerTest < ActionController::TestCase
|
|
1010
1222
|
def test_show_has_one_relationship
|
1011
1223
|
get :show_association, {post_id: '1', association: 'author'}
|
1012
1224
|
assert_response :success
|
1013
|
-
|
1225
|
+
assert_hash_equals json_response,
|
1226
|
+
{data: {
|
1227
|
+
type: 'people',
|
1228
|
+
id: '1',
|
1229
|
+
self: 'http://test.host/posts/1/links/author',
|
1230
|
+
resource: 'http://test.host/posts/1/author'
|
1231
|
+
}
|
1232
|
+
}
|
1014
1233
|
end
|
1015
1234
|
|
1016
1235
|
def test_show_has_many_relationship
|
1017
1236
|
get :show_association, {post_id: '1', association: 'tags'}
|
1018
1237
|
assert_response :success
|
1019
|
-
|
1238
|
+
assert_hash_equals json_response,
|
1239
|
+
{data: {
|
1240
|
+
type: 'tags',
|
1241
|
+
ids: ['1', '2', '3'],
|
1242
|
+
self: 'http://test.host/posts/1/links/tags',
|
1243
|
+
resource: 'http://test.host/posts/1/tags'
|
1244
|
+
}
|
1245
|
+
}
|
1020
1246
|
end
|
1021
1247
|
end
|
1022
1248
|
|
1023
1249
|
class TagsControllerTest < ActionController::TestCase
|
1024
1250
|
def test_tags_index
|
1025
|
-
get :index, {
|
1251
|
+
get :index, {filter: {id: '6,7,8,9'}, include: 'posts,posts.tags,posts.author.posts'}
|
1026
1252
|
assert_response :success
|
1027
|
-
assert_equal 4, json_response['
|
1028
|
-
assert_equal 2, json_response['linked']
|
1253
|
+
assert_equal 4, json_response['data'].size
|
1254
|
+
assert_equal 2, json_response['linked'].size
|
1029
1255
|
end
|
1030
1256
|
|
1031
1257
|
def test_tags_show_multiple
|
1032
1258
|
get :show, {id: '6,7,8,9'}
|
1033
1259
|
assert_response :success
|
1034
|
-
assert json_response['
|
1035
|
-
assert_equal 4, json_response['
|
1260
|
+
assert json_response['data'].is_a?(Array)
|
1261
|
+
assert_equal 4, json_response['data'].size
|
1036
1262
|
end
|
1037
1263
|
|
1038
1264
|
def test_tags_show_multiple_with_include
|
1039
1265
|
get :show, {id: '6,7,8,9', include: 'posts,posts.tags,posts.author.posts'}
|
1040
1266
|
assert_response :success
|
1041
|
-
assert json_response['
|
1042
|
-
assert_equal 4, json_response['
|
1043
|
-
assert_equal 2, json_response['linked']
|
1267
|
+
assert json_response['data'].is_a?(Array)
|
1268
|
+
assert_equal 4, json_response['data'].size
|
1269
|
+
assert_equal 2, json_response['linked'].size
|
1044
1270
|
end
|
1045
1271
|
|
1046
1272
|
def test_tags_show_multiple_with_nonexistent_ids
|
@@ -1058,22 +1284,21 @@ class ExpenseEntriesControllerTest < ActionController::TestCase
|
|
1058
1284
|
def test_expense_entries_index
|
1059
1285
|
get :index
|
1060
1286
|
assert_response :success
|
1061
|
-
assert json_response['
|
1062
|
-
assert_equal 2, json_response['
|
1287
|
+
assert json_response['data'].is_a?(Array)
|
1288
|
+
assert_equal 2, json_response['data'].size
|
1063
1289
|
end
|
1064
1290
|
|
1065
1291
|
def test_expense_entries_show
|
1066
1292
|
get :show, {id: 1}
|
1067
1293
|
assert_response :success
|
1068
|
-
assert json_response['
|
1294
|
+
assert json_response['data'].is_a?(Hash)
|
1069
1295
|
end
|
1070
1296
|
|
1071
1297
|
def test_expense_entries_show_include
|
1072
1298
|
get :show, {id: 1, include: 'isoCurrency,employee'}
|
1073
1299
|
assert_response :success
|
1074
|
-
assert json_response['
|
1075
|
-
assert_equal
|
1076
|
-
assert_equal 1, json_response['linked']['people'].size
|
1300
|
+
assert json_response['data'].is_a?(Hash)
|
1301
|
+
assert_equal 2, json_response['linked'].size
|
1077
1302
|
end
|
1078
1303
|
|
1079
1304
|
def test_expense_entries_show_bad_include_missing_association
|
@@ -1092,38 +1317,25 @@ class ExpenseEntriesControllerTest < ActionController::TestCase
|
|
1092
1317
|
def test_expense_entries_show_fields
|
1093
1318
|
get :show, {id: 1, include: 'isoCurrency,employee', 'fields' => 'transactionDate'}
|
1094
1319
|
assert_response :success
|
1095
|
-
assert json_response['
|
1096
|
-
assert json_response['
|
1097
|
-
refute json_response['expenseEntries'].has_key?('id')
|
1098
|
-
refute json_response['expenseEntries'].has_key?('links')
|
1099
|
-
assert_equal 1, json_response['linked']['isoCurrencies'].size
|
1100
|
-
assert_equal 1, json_response['linked']['people'].size
|
1320
|
+
assert json_response['data'].is_a?(Hash)
|
1321
|
+
assert json_response['data'].has_key?('transactionDate')
|
1101
1322
|
end
|
1102
1323
|
|
1103
1324
|
def test_expense_entries_show_fields_type
|
1104
1325
|
get :show, {id: 1, include: 'isoCurrency,employee', 'fields' => {'expenseEntries' => 'transactionDate'}}
|
1105
1326
|
assert_response :success
|
1106
|
-
assert json_response['
|
1107
|
-
assert json_response['
|
1108
|
-
|
1109
|
-
refute json_response['expenseEntries'].has_key?('links')
|
1110
|
-
assert_equal 1, json_response['linked']['isoCurrencies'].size
|
1111
|
-
assert_equal 1, json_response['linked']['people'].size
|
1327
|
+
assert json_response['data'].is_a?(Hash)
|
1328
|
+
assert json_response['data'].has_key?('transactionDate')
|
1329
|
+
assert_equal 2, json_response['linked'].size
|
1112
1330
|
end
|
1113
1331
|
|
1114
1332
|
def test_expense_entries_show_fields_type_many
|
1115
1333
|
get :show, {id: 1, include: 'isoCurrency,employee', 'fields' => {'expenseEntries' => 'transactionDate',
|
1116
1334
|
'isoCurrencies' => 'id,name'}}
|
1117
1335
|
assert_response :success
|
1118
|
-
assert json_response['
|
1119
|
-
assert json_response['
|
1120
|
-
|
1121
|
-
refute json_response['expenseEntries'].has_key?('links')
|
1122
|
-
assert_equal 1, json_response['linked']['isoCurrencies'].size
|
1123
|
-
assert_equal 1, json_response['linked']['people'].size
|
1124
|
-
assert json_response['linked']['isoCurrencies'][0].has_key?('id')
|
1125
|
-
assert json_response['linked']['isoCurrencies'][0].has_key?('name')
|
1126
|
-
refute json_response['linked']['isoCurrencies'][0].has_key?('countryName')
|
1336
|
+
assert json_response['data'].is_a?(Hash)
|
1337
|
+
assert json_response['data'].has_key?('transactionDate')
|
1338
|
+
assert_equal 2, json_response['linked'].size
|
1127
1339
|
end
|
1128
1340
|
|
1129
1341
|
def test_create_expense_entries_underscored
|
@@ -1132,12 +1344,13 @@ class ExpenseEntriesControllerTest < ActionController::TestCase
|
|
1132
1344
|
|
1133
1345
|
post :create,
|
1134
1346
|
{
|
1135
|
-
|
1347
|
+
data: {
|
1348
|
+
type: 'expense_entries',
|
1136
1349
|
transaction_date: '2014/04/15',
|
1137
1350
|
cost: 50.58,
|
1138
1351
|
links: {
|
1139
|
-
employee: 3,
|
1140
|
-
iso_currency: 'USD'
|
1352
|
+
employee: {type: 'people', id: '3'},
|
1353
|
+
iso_currency: {type: 'iso_currencies', id: 'USD'}
|
1141
1354
|
}
|
1142
1355
|
},
|
1143
1356
|
include: 'iso_currency',
|
@@ -1145,12 +1358,12 @@ class ExpenseEntriesControllerTest < ActionController::TestCase
|
|
1145
1358
|
}
|
1146
1359
|
|
1147
1360
|
assert_response :created
|
1148
|
-
assert json_response['
|
1149
|
-
assert_equal '3', json_response['
|
1150
|
-
assert_equal 'USD', json_response['
|
1151
|
-
assert_equal 50.58, json_response['
|
1361
|
+
assert json_response['data'].is_a?(Hash)
|
1362
|
+
assert_equal '3', json_response['data']['links']['employee']['id']
|
1363
|
+
assert_equal 'USD', json_response['data']['links']['iso_currency']['id']
|
1364
|
+
assert_equal 50.58, json_response['data']['cost']
|
1152
1365
|
|
1153
|
-
delete :destroy, {id: json_response['
|
1366
|
+
delete :destroy, {id: json_response['data']['id']}
|
1154
1367
|
assert_response :no_content
|
1155
1368
|
end
|
1156
1369
|
|
@@ -1160,12 +1373,13 @@ class ExpenseEntriesControllerTest < ActionController::TestCase
|
|
1160
1373
|
|
1161
1374
|
post :create,
|
1162
1375
|
{
|
1163
|
-
|
1376
|
+
data: {
|
1377
|
+
type: 'expense_entries',
|
1164
1378
|
transactionDate: '2014/04/15',
|
1165
1379
|
cost: 50.58,
|
1166
1380
|
links: {
|
1167
|
-
employee: 3,
|
1168
|
-
isoCurrency: 'USD'
|
1381
|
+
employee: {type: 'people', id: '3'},
|
1382
|
+
isoCurrency: {type: 'iso_currencies', id: 'USD'}
|
1169
1383
|
}
|
1170
1384
|
},
|
1171
1385
|
include: 'isoCurrency',
|
@@ -1173,12 +1387,12 @@ class ExpenseEntriesControllerTest < ActionController::TestCase
|
|
1173
1387
|
}
|
1174
1388
|
|
1175
1389
|
assert_response :created
|
1176
|
-
assert json_response['
|
1177
|
-
assert_equal '3', json_response['
|
1178
|
-
assert_equal 'USD', json_response['
|
1179
|
-
assert_equal 50.58, json_response['
|
1390
|
+
assert json_response['data'].is_a?(Hash)
|
1391
|
+
assert_equal '3', json_response['data']['links']['employee']['id']
|
1392
|
+
assert_equal 'USD', json_response['data']['links']['isoCurrency']['id']
|
1393
|
+
assert_equal 50.58, json_response['data']['cost']
|
1180
1394
|
|
1181
|
-
delete :destroy, {id: json_response['
|
1395
|
+
delete :destroy, {id: json_response['data']['id']}
|
1182
1396
|
assert_response :no_content
|
1183
1397
|
end
|
1184
1398
|
|
@@ -1188,12 +1402,13 @@ class ExpenseEntriesControllerTest < ActionController::TestCase
|
|
1188
1402
|
|
1189
1403
|
post :create,
|
1190
1404
|
{
|
1191
|
-
|
1405
|
+
data: {
|
1406
|
+
type: 'expense_entries',
|
1192
1407
|
'transaction-date' => '2014/04/15',
|
1193
1408
|
cost: 50.58,
|
1194
1409
|
links: {
|
1195
|
-
employee: 3,
|
1196
|
-
'iso-currency' => 'USD'
|
1410
|
+
employee: {type: 'people', id: '3'},
|
1411
|
+
'iso-currency' => {type: 'iso_currencies', id: 'USD'}
|
1197
1412
|
}
|
1198
1413
|
},
|
1199
1414
|
include: 'iso-currency',
|
@@ -1201,12 +1416,12 @@ class ExpenseEntriesControllerTest < ActionController::TestCase
|
|
1201
1416
|
}
|
1202
1417
|
|
1203
1418
|
assert_response :created
|
1204
|
-
assert json_response['
|
1205
|
-
assert_equal '3', json_response['
|
1206
|
-
assert_equal 'USD', json_response['
|
1207
|
-
assert_equal 50.58, json_response['
|
1419
|
+
assert json_response['data'].is_a?(Hash)
|
1420
|
+
assert_equal '3', json_response['data']['links']['employee']['id']
|
1421
|
+
assert_equal 'USD', json_response['data']['links']['iso-currency']['id']
|
1422
|
+
assert_equal 50.58, json_response['data']['cost']
|
1208
1423
|
|
1209
|
-
delete :destroy, {id: json_response['
|
1424
|
+
delete :destroy, {id: json_response['data']['id']}
|
1210
1425
|
assert_response :no_content
|
1211
1426
|
end
|
1212
1427
|
end
|
@@ -1216,116 +1431,88 @@ class IsoCurrenciesControllerTest < ActionController::TestCase
|
|
1216
1431
|
JSONAPI.configuration.json_key_format = :camelized_key
|
1217
1432
|
end
|
1218
1433
|
|
1219
|
-
def test_currencies_index
|
1220
|
-
JSONAPI.configuration.json_key_format = :camelized_key
|
1221
|
-
get :index
|
1222
|
-
assert_response :success
|
1223
|
-
assert_equal 3, json_response['isoCurrencies'].size
|
1224
|
-
end
|
1225
|
-
|
1226
|
-
def test_currencies_json_key_underscored
|
1227
|
-
JSONAPI.configuration.json_key_format = :underscored_key
|
1228
|
-
get :index
|
1229
|
-
assert_response :success
|
1230
|
-
assert_equal 3, json_response['iso_currencies'].size
|
1231
|
-
end
|
1232
|
-
|
1233
|
-
def test_currencies_json_key_dasherized
|
1234
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
1235
|
-
get :index
|
1236
|
-
assert_response :success
|
1237
|
-
assert_equal 3, json_response['iso-currencies'].size
|
1238
|
-
end
|
1239
|
-
|
1240
|
-
def test_currencies_custom_json_key
|
1241
|
-
JSONAPI.configuration.json_key_format = :upper_camelized_key
|
1242
|
-
get :index
|
1243
|
-
assert_response :success
|
1244
|
-
assert_equal 3, json_response['IsoCurrencies'].size
|
1245
|
-
end
|
1246
|
-
|
1247
1434
|
def test_currencies_show
|
1248
1435
|
get :show, {code: 'USD'}
|
1249
1436
|
assert_response :success
|
1250
|
-
assert json_response['
|
1437
|
+
assert json_response['data'].is_a?(Hash)
|
1251
1438
|
end
|
1252
1439
|
|
1253
1440
|
def test_currencies_json_key_underscored_sort
|
1254
1441
|
JSONAPI.configuration.json_key_format = :underscored_key
|
1255
|
-
get :index, {sort: 'country_name'}
|
1442
|
+
get :index, {sort: '+country_name'}
|
1256
1443
|
assert_response :success
|
1257
|
-
assert_equal 3, json_response['
|
1258
|
-
assert_equal 'Canada', json_response['
|
1259
|
-
assert_equal 'Euro Member Countries', json_response['
|
1260
|
-
assert_equal 'United States', json_response['
|
1444
|
+
assert_equal 3, json_response['data'].size
|
1445
|
+
assert_equal 'Canada', json_response['data'][0]['country_name']
|
1446
|
+
assert_equal 'Euro Member Countries', json_response['data'][1]['country_name']
|
1447
|
+
assert_equal 'United States', json_response['data'][2]['country_name']
|
1261
1448
|
|
1262
1449
|
# reverse sort
|
1263
1450
|
get :index, {sort: '-country_name'}
|
1264
1451
|
assert_response :success
|
1265
|
-
assert_equal 3, json_response['
|
1266
|
-
assert_equal 'United States', json_response['
|
1267
|
-
assert_equal 'Euro Member Countries', json_response['
|
1268
|
-
assert_equal 'Canada', json_response['
|
1452
|
+
assert_equal 3, json_response['data'].size
|
1453
|
+
assert_equal 'United States', json_response['data'][0]['country_name']
|
1454
|
+
assert_equal 'Euro Member Countries', json_response['data'][1]['country_name']
|
1455
|
+
assert_equal 'Canada', json_response['data'][2]['country_name']
|
1269
1456
|
end
|
1270
1457
|
|
1271
1458
|
def test_currencies_json_key_dasherized_sort
|
1272
1459
|
JSONAPI.configuration.json_key_format = :dasherized_key
|
1273
|
-
get :index, {sort: 'country-name'}
|
1460
|
+
get :index, {sort: '+country-name'}
|
1274
1461
|
assert_response :success
|
1275
|
-
assert_equal 3, json_response['
|
1276
|
-
assert_equal 'Canada', json_response['
|
1277
|
-
assert_equal 'Euro Member Countries', json_response['
|
1278
|
-
assert_equal 'United States', json_response['
|
1462
|
+
assert_equal 3, json_response['data'].size
|
1463
|
+
assert_equal 'Canada', json_response['data'][0]['country-name']
|
1464
|
+
assert_equal 'Euro Member Countries', json_response['data'][1]['country-name']
|
1465
|
+
assert_equal 'United States', json_response['data'][2]['country-name']
|
1279
1466
|
|
1280
1467
|
# reverse sort
|
1281
1468
|
get :index, {sort: '-country-name'}
|
1282
1469
|
assert_response :success
|
1283
|
-
assert_equal 3, json_response['
|
1284
|
-
assert_equal 'United States', json_response['
|
1285
|
-
assert_equal 'Euro Member Countries', json_response['
|
1286
|
-
assert_equal 'Canada', json_response['
|
1470
|
+
assert_equal 3, json_response['data'].size
|
1471
|
+
assert_equal 'United States', json_response['data'][0]['country-name']
|
1472
|
+
assert_equal 'Euro Member Countries', json_response['data'][1]['country-name']
|
1473
|
+
assert_equal 'Canada', json_response['data'][2]['country-name']
|
1287
1474
|
end
|
1288
1475
|
|
1289
1476
|
def test_currencies_json_key_custom_json_key_sort
|
1290
1477
|
JSONAPI.configuration.json_key_format = :upper_camelized_key
|
1291
|
-
get :index, {sort: 'CountryName'}
|
1478
|
+
get :index, {sort: '+CountryName'}
|
1292
1479
|
assert_response :success
|
1293
|
-
assert_equal 3, json_response['
|
1294
|
-
assert_equal 'Canada', json_response['
|
1295
|
-
assert_equal 'Euro Member Countries', json_response['
|
1296
|
-
assert_equal 'United States', json_response['
|
1480
|
+
assert_equal 3, json_response['data'].size
|
1481
|
+
assert_equal 'Canada', json_response['data'][0]['CountryName']
|
1482
|
+
assert_equal 'Euro Member Countries', json_response['data'][1]['CountryName']
|
1483
|
+
assert_equal 'United States', json_response['data'][2]['CountryName']
|
1297
1484
|
|
1298
1485
|
# reverse sort
|
1299
1486
|
get :index, {sort: '-CountryName'}
|
1300
1487
|
assert_response :success
|
1301
|
-
assert_equal 3, json_response['
|
1302
|
-
assert_equal 'United States', json_response['
|
1303
|
-
assert_equal 'Euro Member Countries', json_response['
|
1304
|
-
assert_equal 'Canada', json_response['
|
1488
|
+
assert_equal 3, json_response['data'].size
|
1489
|
+
assert_equal 'United States', json_response['data'][0]['CountryName']
|
1490
|
+
assert_equal 'Euro Member Countries', json_response['data'][1]['CountryName']
|
1491
|
+
assert_equal 'Canada', json_response['data'][2]['CountryName']
|
1305
1492
|
end
|
1306
1493
|
|
1307
1494
|
def test_currencies_json_key_underscored_filter
|
1308
1495
|
JSONAPI.configuration.json_key_format = :underscored_key
|
1309
|
-
get :index, {country_name: 'Canada'}
|
1496
|
+
get :index, {filter: {country_name: 'Canada'}}
|
1310
1497
|
assert_response :success
|
1311
|
-
assert_equal 1, json_response['
|
1312
|
-
assert_equal 'Canada', json_response['
|
1498
|
+
assert_equal 1, json_response['data'].size
|
1499
|
+
assert_equal 'Canada', json_response['data'][0]['country_name']
|
1313
1500
|
end
|
1314
1501
|
|
1315
1502
|
def test_currencies_json_key_camelized_key_filter
|
1316
1503
|
JSONAPI.configuration.json_key_format = :camelized_key
|
1317
|
-
get :index, {'countryName' => 'Canada'}
|
1504
|
+
get :index, {filter: {'countryName' => 'Canada'}}
|
1318
1505
|
assert_response :success
|
1319
|
-
assert_equal 1, json_response['
|
1320
|
-
assert_equal 'Canada', json_response['
|
1506
|
+
assert_equal 1, json_response['data'].size
|
1507
|
+
assert_equal 'Canada', json_response['data'][0]['countryName']
|
1321
1508
|
end
|
1322
1509
|
|
1323
1510
|
def test_currencies_json_key_custom_json_key_filter
|
1324
1511
|
JSONAPI.configuration.json_key_format = :upper_camelized_key
|
1325
|
-
get :index, {'CountryName' => 'Canada'}
|
1512
|
+
get :index, {filter: {'CountryName' => 'Canada'}}
|
1326
1513
|
assert_response :success
|
1327
|
-
assert_equal 1, json_response['
|
1328
|
-
assert_equal 'Canada', json_response['
|
1514
|
+
assert_equal 1, json_response['data'].size
|
1515
|
+
assert_equal 'Canada', json_response['data'][0]['CountryName']
|
1329
1516
|
end
|
1330
1517
|
end
|
1331
1518
|
|
@@ -1334,7 +1521,8 @@ class PeopleControllerTest < ActionController::TestCase
|
|
1334
1521
|
set_content_type_header!
|
1335
1522
|
post :create,
|
1336
1523
|
{
|
1337
|
-
|
1524
|
+
data: {
|
1525
|
+
type: 'people',
|
1338
1526
|
name: 'Steve Jobs',
|
1339
1527
|
email: 'sj@email.zzz',
|
1340
1528
|
dateJoined: DateTime.parse('2014-1-30 4:20:00 UTC +00:00')
|
@@ -1348,7 +1536,8 @@ class PeopleControllerTest < ActionController::TestCase
|
|
1348
1536
|
set_content_type_header!
|
1349
1537
|
post :create,
|
1350
1538
|
{
|
1351
|
-
|
1539
|
+
data: {
|
1540
|
+
type: 'people',
|
1352
1541
|
email: 'sj@email.zzz'
|
1353
1542
|
}
|
1354
1543
|
}
|
@@ -1366,7 +1555,9 @@ class PeopleControllerTest < ActionController::TestCase
|
|
1366
1555
|
put :update,
|
1367
1556
|
{
|
1368
1557
|
id: 3,
|
1369
|
-
|
1558
|
+
data: {
|
1559
|
+
id: '3',
|
1560
|
+
type: 'people',
|
1370
1561
|
name: ''
|
1371
1562
|
}
|
1372
1563
|
}
|
@@ -1385,39 +1576,36 @@ class PeopleControllerTest < ActionController::TestCase
|
|
1385
1576
|
end
|
1386
1577
|
|
1387
1578
|
def test_invalid_filter_value
|
1388
|
-
get :index, {name: 'L'}
|
1579
|
+
get :index, {filter: {name: 'L'}}
|
1389
1580
|
assert_response :bad_request
|
1390
1581
|
end
|
1391
1582
|
|
1392
1583
|
def test_valid_filter_value
|
1393
|
-
get :index, {name: 'Joe Author'}
|
1584
|
+
get :index, {filter: {name: 'Joe Author'}}
|
1394
1585
|
assert_response :success
|
1395
|
-
assert_equal json_response['
|
1396
|
-
assert_equal json_response['
|
1397
|
-
assert_equal json_response['
|
1586
|
+
assert_equal json_response['data'].size, 1
|
1587
|
+
assert_equal json_response['data'][0]['id'], '1'
|
1588
|
+
assert_equal json_response['data'][0]['name'], 'Joe Author'
|
1398
1589
|
end
|
1399
1590
|
end
|
1400
1591
|
|
1401
1592
|
class AuthorsControllerTest < ActionController::TestCase
|
1402
1593
|
def test_get_person_as_author
|
1403
|
-
get :index, {id: '1'}
|
1594
|
+
get :index, {filter: {id: '1'}}
|
1404
1595
|
assert_response :success
|
1405
|
-
assert_equal 1, json_response['
|
1406
|
-
assert_equal '1', json_response['
|
1407
|
-
assert_equal '
|
1408
|
-
assert_equal
|
1409
|
-
assert_equal
|
1410
|
-
assert_equal 3, json_response['authors'][0]['links']['posts'].size
|
1596
|
+
assert_equal 1, json_response['data'].size
|
1597
|
+
assert_equal '1', json_response['data'][0]['id']
|
1598
|
+
assert_equal 'authors', json_response['data'][0]['type']
|
1599
|
+
assert_equal 'Joe Author', json_response['data'][0]['name']
|
1600
|
+
assert_equal nil, json_response['data'][0]['email']
|
1411
1601
|
end
|
1412
1602
|
|
1413
1603
|
def test_get_person_as_author_by_name_filter
|
1414
|
-
get :index, {name: 'thor'}
|
1604
|
+
get :index, {filter: {name: 'thor'}}
|
1415
1605
|
assert_response :success
|
1416
|
-
assert_equal 3, json_response['
|
1417
|
-
assert_equal '1', json_response['
|
1418
|
-
assert_equal 'Joe Author', json_response['
|
1419
|
-
assert_equal 1, json_response['authors'][0]['links'].size
|
1420
|
-
assert_equal 3, json_response['authors'][0]['links']['posts'].size
|
1606
|
+
assert_equal 3, json_response['data'].size
|
1607
|
+
assert_equal '1', json_response['data'][0]['id']
|
1608
|
+
assert_equal 'Joe Author', json_response['data'][0]['name']
|
1421
1609
|
end
|
1422
1610
|
end
|
1423
1611
|
|
@@ -1427,66 +1615,70 @@ class BreedsControllerTest < ActionController::TestCase
|
|
1427
1615
|
def test_poro_index
|
1428
1616
|
get :index
|
1429
1617
|
assert_response :success
|
1430
|
-
assert_equal '0', json_response['
|
1431
|
-
assert_equal 'Persian', json_response['
|
1618
|
+
assert_equal '0', json_response['data'][0]['id']
|
1619
|
+
assert_equal 'Persian', json_response['data'][0]['name']
|
1432
1620
|
end
|
1433
1621
|
|
1434
1622
|
def test_poro_show
|
1435
1623
|
get :show, {id: '0'}
|
1436
1624
|
assert_response :success
|
1437
|
-
assert json_response['
|
1438
|
-
assert_equal '0', json_response['
|
1439
|
-
assert_equal 'Persian', json_response['
|
1625
|
+
assert json_response['data'].is_a?(Hash)
|
1626
|
+
assert_equal '0', json_response['data']['id']
|
1627
|
+
assert_equal 'Persian', json_response['data']['name']
|
1440
1628
|
end
|
1441
1629
|
|
1442
1630
|
def test_poro_show_multiple
|
1443
1631
|
get :show, {id: '0,2'}
|
1444
1632
|
assert_response :success
|
1445
|
-
assert json_response['
|
1446
|
-
assert_equal 2, json_response['
|
1447
|
-
assert_equal '0', json_response['
|
1448
|
-
assert_equal 'Persian', json_response['
|
1449
|
-
assert_equal '2', json_response['
|
1450
|
-
assert_equal 'Sphinx', json_response['
|
1633
|
+
assert json_response['data'].is_a?(Array)
|
1634
|
+
assert_equal 2, json_response['data'].size
|
1635
|
+
assert_equal '0', json_response['data'][0]['id']
|
1636
|
+
assert_equal 'Persian', json_response['data'][0]['name']
|
1637
|
+
assert_equal '2', json_response['data'][1]['id']
|
1638
|
+
assert_equal 'Sphinx', json_response['data'][1]['name']
|
1451
1639
|
end
|
1452
1640
|
|
1453
1641
|
def test_poro_create_simple
|
1454
1642
|
set_content_type_header!
|
1455
1643
|
post :create,
|
1456
1644
|
{
|
1457
|
-
|
1645
|
+
data: {
|
1646
|
+
type: 'breeds',
|
1458
1647
|
name: 'tabby'
|
1459
1648
|
}
|
1460
1649
|
}
|
1461
1650
|
|
1462
1651
|
assert_response :created
|
1463
|
-
assert json_response['
|
1464
|
-
assert_equal 'Tabby', json_response['
|
1652
|
+
assert json_response['data'].is_a?(Hash)
|
1653
|
+
assert_equal 'Tabby', json_response['data']['name']
|
1465
1654
|
end
|
1466
1655
|
|
1467
1656
|
def test_poro_create_update
|
1468
1657
|
set_content_type_header!
|
1469
1658
|
post :create,
|
1470
1659
|
{
|
1471
|
-
|
1660
|
+
data: {
|
1661
|
+
type: 'breeds',
|
1472
1662
|
name: 'CALIC'
|
1473
1663
|
}
|
1474
1664
|
}
|
1475
1665
|
|
1476
1666
|
assert_response :created
|
1477
|
-
assert json_response['
|
1478
|
-
assert_equal 'Calic', json_response['
|
1667
|
+
assert json_response['data'].is_a?(Hash)
|
1668
|
+
assert_equal 'Calic', json_response['data']['name']
|
1479
1669
|
|
1480
1670
|
put :update,
|
1481
1671
|
{
|
1482
|
-
id: json_response['
|
1483
|
-
|
1672
|
+
id: json_response['data']['id'],
|
1673
|
+
data: {
|
1674
|
+
id: json_response['data']['id'],
|
1675
|
+
type: 'breeds',
|
1484
1676
|
name: 'calico'
|
1485
1677
|
}
|
1486
1678
|
}
|
1487
1679
|
assert_response :success
|
1488
|
-
assert json_response['
|
1489
|
-
assert_equal 'Calico', json_response['
|
1680
|
+
assert json_response['data'].is_a?(Hash)
|
1681
|
+
assert_equal 'Calico', json_response['data']['name']
|
1490
1682
|
end
|
1491
1683
|
|
1492
1684
|
def test_poro_delete
|
@@ -1509,63 +1701,52 @@ class Api::V1::PostsControllerTest < ActionController::TestCase
|
|
1509
1701
|
def test_show_post_namespaced
|
1510
1702
|
get :show, {id: '1'}
|
1511
1703
|
assert_response :success
|
1512
|
-
|
1513
|
-
{
|
1514
|
-
posts: {
|
1515
|
-
id: '1',
|
1516
|
-
title: 'New post',
|
1517
|
-
body: 'A body!!!',
|
1518
|
-
subject: 'New post',
|
1519
|
-
links: {
|
1520
|
-
section: nil,
|
1521
|
-
writer: '1',
|
1522
|
-
comments: ['1', '2']
|
1523
|
-
}
|
1524
|
-
}
|
1525
|
-
}, json_response
|
1526
|
-
)
|
1704
|
+
assert_equal 'http://test.host/api/v1/posts/1/links/writer', json_response['data']['links']['writer']['self']
|
1527
1705
|
end
|
1528
1706
|
|
1529
1707
|
def test_show_post_namespaced_include
|
1530
1708
|
get :show, {id: '1', include: 'writer'}
|
1531
1709
|
assert_response :success
|
1532
|
-
assert_equal '1', json_response['
|
1533
|
-
assert_nil json_response['
|
1534
|
-
assert_equal '1', json_response['linked'][
|
1535
|
-
assert_equal '
|
1710
|
+
assert_equal '1', json_response['data']['links']['writer']['id']
|
1711
|
+
assert_nil json_response['data']['links']['tags']
|
1712
|
+
assert_equal '1', json_response['linked'][0]['id']
|
1713
|
+
assert_equal 'writers', json_response['linked'][0]['type']
|
1714
|
+
assert_equal 'joe@xyz.fake', json_response['linked'][0]['email']
|
1536
1715
|
end
|
1537
1716
|
|
1538
1717
|
def test_index_filter_on_association_namespaced
|
1539
|
-
get :index, {writer: '1'}
|
1718
|
+
get :index, {filter: {writer: '1'}}
|
1540
1719
|
assert_response :success
|
1541
|
-
assert_equal 3, json_response['
|
1720
|
+
assert_equal 3, json_response['data'].size
|
1542
1721
|
end
|
1543
1722
|
|
1544
1723
|
def test_sorting_desc_namespaced
|
1545
1724
|
get :index, {sort: '-title'}
|
1546
1725
|
|
1547
1726
|
assert_response :success
|
1548
|
-
assert_equal "Update This Later - Multiple", json_response['
|
1727
|
+
assert_equal "Update This Later - Multiple", json_response['data'][0]['title']
|
1549
1728
|
end
|
1550
1729
|
|
1551
1730
|
def test_create_simple_namespaced
|
1552
1731
|
set_content_type_header!
|
1553
1732
|
post :create,
|
1554
1733
|
{
|
1555
|
-
|
1734
|
+
data: {
|
1735
|
+
type: 'posts',
|
1556
1736
|
title: 'JR - now with Namespacing',
|
1557
1737
|
body: 'JSONAPIResources is the greatest thing since unsliced bread now that it has namespaced resources.',
|
1558
1738
|
links: {
|
1559
|
-
writer: '3'
|
1739
|
+
writer: {type: 'writers', id: '3'}
|
1560
1740
|
}
|
1561
1741
|
}
|
1562
1742
|
}
|
1563
1743
|
|
1564
1744
|
assert_response :created
|
1565
|
-
assert json_response['
|
1566
|
-
assert_equal '3', json_response['
|
1567
|
-
assert_equal 'JR - now with Namespacing', json_response['
|
1568
|
-
assert_equal 'JSONAPIResources is the greatest thing since unsliced bread now that it has namespaced resources.',
|
1745
|
+
assert json_response['data'].is_a?(Hash)
|
1746
|
+
assert_equal '3', json_response['data']['links']['writer']['id']
|
1747
|
+
assert_equal 'JR - now with Namespacing', json_response['data']['title']
|
1748
|
+
assert_equal 'JSONAPIResources is the greatest thing since unsliced bread now that it has namespaced resources.',
|
1749
|
+
json_response['data']['body']
|
1569
1750
|
end
|
1570
1751
|
|
1571
1752
|
end
|
@@ -1574,15 +1755,140 @@ class FactsControllerTest < ActionController::TestCase
|
|
1574
1755
|
def test_type_formatting
|
1575
1756
|
get :show, {id: '1'}
|
1576
1757
|
assert_response :success
|
1577
|
-
assert json_response['
|
1578
|
-
assert_equal 'Jane Author', json_response['
|
1579
|
-
assert_equal 'First man to run across Antartica.', json_response['
|
1580
|
-
assert_equal 23.89/45.6, json_response['
|
1581
|
-
assert_equal 47000.56, json_response['
|
1582
|
-
assert_equal '2013-08-07T20:25:00.000Z', json_response['
|
1583
|
-
assert_equal '1965-06-30', json_response['
|
1584
|
-
assert_equal '2000-01-01T20:00:00Z', json_response['
|
1585
|
-
assert_equal 'abc', json_response['
|
1586
|
-
assert_equal false, json_response['
|
1758
|
+
assert json_response['data'].is_a?(Hash)
|
1759
|
+
assert_equal 'Jane Author', json_response['data']['spouseName']
|
1760
|
+
assert_equal 'First man to run across Antartica.', json_response['data']['bio']
|
1761
|
+
assert_equal 23.89/45.6, json_response['data']['qualityRating']
|
1762
|
+
assert_equal 47000.56, json_response['data']['salary']
|
1763
|
+
assert_equal '2013-08-07T20:25:00.000Z', json_response['data']['dateTimeJoined']
|
1764
|
+
assert_equal '1965-06-30', json_response['data']['birthday']
|
1765
|
+
assert_equal '2000-01-01T20:00:00Z', json_response['data']['bedtime']
|
1766
|
+
assert_equal 'abc', json_response['data']['photo']
|
1767
|
+
assert_equal false, json_response['data']['cool']
|
1768
|
+
end
|
1769
|
+
end
|
1770
|
+
|
1771
|
+
class Api::V2::BooksControllerTest < ActionController::TestCase
|
1772
|
+
def after_teardown
|
1773
|
+
Api::V2::BookResource.paginator :offset
|
1774
|
+
end
|
1775
|
+
|
1776
|
+
def test_books_offset_pagination_no_params
|
1777
|
+
Api::V2::BookResource.paginator :offset
|
1778
|
+
|
1779
|
+
get :index
|
1780
|
+
assert_response :success
|
1781
|
+
assert_equal 10, json_response['data'].size
|
1782
|
+
assert_equal 'Book 0', json_response['data'][0]['title']
|
1783
|
+
end
|
1784
|
+
|
1785
|
+
def test_books_offset_pagination
|
1786
|
+
Api::V2::BookResource.paginator :offset
|
1787
|
+
|
1788
|
+
get :index, {page: {offset: 50, limit: 12}}
|
1789
|
+
assert_response :success
|
1790
|
+
assert_equal 12, json_response['data'].size
|
1791
|
+
assert_equal 'Book 50', json_response['data'][0]['title']
|
1792
|
+
end
|
1793
|
+
|
1794
|
+
def test_books_offset_pagination_bad_page_param
|
1795
|
+
Api::V2::BookResource.paginator :offset
|
1796
|
+
|
1797
|
+
get :index, {page: {offset_bad: 50, limit: 12}}
|
1798
|
+
assert_response :bad_request
|
1799
|
+
assert_match /offset_bad is not an allowed page parameter./, json_response['errors'][0]['detail']
|
1800
|
+
end
|
1801
|
+
|
1802
|
+
def test_books_offset_pagination_bad_param_value_limit_to_large
|
1803
|
+
Api::V2::BookResource.paginator :offset
|
1804
|
+
|
1805
|
+
get :index, {page: {offset: 50, limit: 1000}}
|
1806
|
+
assert_response :bad_request
|
1807
|
+
assert_match /Limit exceeds maximum page size of 20./, json_response['errors'][0]['detail']
|
1808
|
+
end
|
1809
|
+
|
1810
|
+
def test_books_offset_pagination_bad_param_value_limit_too_small
|
1811
|
+
Api::V2::BookResource.paginator :offset
|
1812
|
+
|
1813
|
+
get :index, {page: {offset: 50, limit: -1}}
|
1814
|
+
assert_response :bad_request
|
1815
|
+
assert_match /-1 is not a valid value for limit page parameter./, json_response['errors'][0]['detail']
|
1816
|
+
end
|
1817
|
+
|
1818
|
+
def test_books_offset_pagination_invalid_page_format
|
1819
|
+
Api::V2::BookResource.paginator :offset
|
1820
|
+
|
1821
|
+
get :index, {page: 50}
|
1822
|
+
assert_response :bad_request
|
1823
|
+
assert_match /Invalid Page Object./, json_response['errors'][0]['detail']
|
1824
|
+
end
|
1825
|
+
|
1826
|
+
def test_books_paged_pagination_no_params
|
1827
|
+
Api::V2::BookResource.paginator :paged
|
1828
|
+
|
1829
|
+
get :index
|
1830
|
+
assert_response :success
|
1831
|
+
assert_equal 10, json_response['data'].size
|
1832
|
+
assert_equal 'Book 0', json_response['data'][0]['title']
|
1833
|
+
end
|
1834
|
+
|
1835
|
+
def test_books_paged_pagination_no_page
|
1836
|
+
Api::V2::BookResource.paginator :paged
|
1837
|
+
|
1838
|
+
get :index, {page: {size: 12}}
|
1839
|
+
assert_response :success
|
1840
|
+
assert_equal 12, json_response['data'].size
|
1841
|
+
assert_equal 'Book 0', json_response['data'][0]['title']
|
1842
|
+
end
|
1843
|
+
|
1844
|
+
def test_books_paged_pagination
|
1845
|
+
Api::V2::BookResource.paginator :paged
|
1846
|
+
|
1847
|
+
get :index, {page: {number: 3, size: 12}}
|
1848
|
+
assert_response :success
|
1849
|
+
assert_equal 12, json_response['data'].size
|
1850
|
+
assert_equal 'Book 24', json_response['data'][0]['title']
|
1851
|
+
end
|
1852
|
+
|
1853
|
+
def test_books_paged_pagination_bad_page_param
|
1854
|
+
Api::V2::BookResource.paginator :paged
|
1855
|
+
|
1856
|
+
get :index, {page: {number_bad: 50, size: 12}}
|
1857
|
+
assert_response :bad_request
|
1858
|
+
assert_match /number_bad is not an allowed page parameter./, json_response['errors'][0]['detail']
|
1859
|
+
end
|
1860
|
+
|
1861
|
+
def test_books_paged_pagination_bad_param_value_limit_to_large
|
1862
|
+
Api::V2::BookResource.paginator :paged
|
1863
|
+
|
1864
|
+
get :index, {page: {number: 50, size: 1000}}
|
1865
|
+
assert_response :bad_request
|
1866
|
+
assert_match /size exceeds maximum page size of 20./, json_response['errors'][0]['detail']
|
1867
|
+
end
|
1868
|
+
|
1869
|
+
def test_books_paged_pagination_bad_param_value_limit_too_small
|
1870
|
+
Api::V2::BookResource.paginator :paged
|
1871
|
+
|
1872
|
+
get :index, {page: {number: 50, size: -1}}
|
1873
|
+
assert_response :bad_request
|
1874
|
+
assert_match /-1 is not a valid value for size page parameter./, json_response['errors'][0]['detail']
|
1875
|
+
end
|
1876
|
+
|
1877
|
+
def test_books_paged_pagination_invalid_page_format_interpret_int_text
|
1878
|
+
Api::V2::BookResource.paginator :paged
|
1879
|
+
|
1880
|
+
get :index, {page: 'qwerty'}
|
1881
|
+
assert_response :success
|
1882
|
+
assert_equal 10, json_response['data'].size
|
1883
|
+
assert_equal 'Book 0', json_response['data'][0]['title']
|
1884
|
+
end
|
1885
|
+
|
1886
|
+
def test_books_paged_pagination_invalid_page_format_interpret_int
|
1887
|
+
Api::V2::BookResource.paginator :paged
|
1888
|
+
|
1889
|
+
get :index, {page: 3}
|
1890
|
+
assert_response :success
|
1891
|
+
assert_equal 10, json_response['data'].size
|
1892
|
+
assert_equal 'Book 20', json_response['data'][0]['title']
|
1587
1893
|
end
|
1588
1894
|
end
|