jsonapi-resources 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +274 -102
- data/jsonapi-resources.gemspec +1 -0
- data/lib/jsonapi-resources.rb +15 -0
- data/lib/jsonapi/active_record_operations_processor.rb +21 -10
- data/lib/jsonapi/acts_as_resource_controller.rb +175 -0
- data/lib/jsonapi/configuration.rb +11 -0
- data/lib/jsonapi/error_codes.rb +7 -4
- data/lib/jsonapi/exceptions.rb +23 -15
- data/lib/jsonapi/formatter.rb +5 -5
- data/lib/jsonapi/include_directives.rb +67 -0
- data/lib/jsonapi/operation.rb +185 -65
- data/lib/jsonapi/operation_result.rb +38 -5
- data/lib/jsonapi/operation_results.rb +33 -0
- data/lib/jsonapi/operations_processor.rb +49 -9
- data/lib/jsonapi/paginator.rb +31 -17
- data/lib/jsonapi/request.rb +347 -163
- data/lib/jsonapi/resource.rb +159 -56
- data/lib/jsonapi/resource_controller.rb +1 -234
- data/lib/jsonapi/resource_serializer.rb +55 -69
- data/lib/jsonapi/resources/version.rb +1 -1
- data/lib/jsonapi/response_document.rb +87 -0
- data/lib/jsonapi/routing_ext.rb +17 -11
- data/test/controllers/controller_test.rb +602 -326
- data/test/fixtures/active_record.rb +96 -6
- data/test/fixtures/line_items.yml +7 -1
- data/test/fixtures/numeros_telefone.yml +3 -0
- data/test/fixtures/purchase_orders.yml +6 -0
- data/test/integration/requests/request_test.rb +129 -60
- data/test/integration/routes/routes_test.rb +17 -17
- data/test/test_helper.rb +23 -5
- data/test/unit/jsonapi_request/jsonapi_request_test.rb +48 -0
- data/test/unit/operation/operations_processor_test.rb +242 -54
- data/test/unit/resource/resource_test.rb +108 -2
- data/test/unit/serializer/include_directives_test.rb +108 -0
- data/test/unit/serializer/response_document_test.rb +61 -0
- data/test/unit/serializer/serializer_test.rb +679 -520
- metadata +26 -2
@@ -18,37 +18,37 @@ class RoutesTest < ActionDispatch::IntegrationTest
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def test_routing_posts_links_author_show
|
21
|
-
assert_routing({path: '/posts/1/
|
21
|
+
assert_routing({path: '/posts/1/relationships/author', method: :get},
|
22
22
|
{controller: 'posts', action: 'show_association', post_id: '1', association: 'author'})
|
23
23
|
end
|
24
24
|
|
25
25
|
def test_routing_posts_links_author_destroy
|
26
|
-
assert_routing({path: '/posts/1/
|
26
|
+
assert_routing({path: '/posts/1/relationships/author', method: :delete},
|
27
27
|
{controller: 'posts', action: 'destroy_association', post_id: '1', association: 'author'})
|
28
28
|
end
|
29
29
|
|
30
30
|
def test_routing_posts_links_author_update
|
31
|
-
assert_routing({path: '/posts/1/
|
31
|
+
assert_routing({path: '/posts/1/relationships/author', method: :patch},
|
32
32
|
{controller: 'posts', action: 'update_association', post_id: '1', association: 'author'})
|
33
33
|
end
|
34
34
|
|
35
35
|
def test_routing_posts_links_tags_show
|
36
|
-
assert_routing({path: '/posts/1/
|
36
|
+
assert_routing({path: '/posts/1/relationships/tags', method: :get},
|
37
37
|
{controller: 'posts', action: 'show_association', post_id: '1', association: 'tags'})
|
38
38
|
end
|
39
39
|
|
40
40
|
def test_routing_posts_links_tags_destroy
|
41
|
-
assert_routing({path: '/posts/1/
|
41
|
+
assert_routing({path: '/posts/1/relationships/tags/1,2', method: :delete},
|
42
42
|
{controller: 'posts', action: 'destroy_association', post_id: '1', keys: '1,2', association: 'tags'})
|
43
43
|
end
|
44
44
|
|
45
45
|
def test_routing_posts_links_tags_create
|
46
|
-
assert_routing({path: '/posts/1/
|
46
|
+
assert_routing({path: '/posts/1/relationships/tags', method: :post},
|
47
47
|
{controller: 'posts', action: 'create_association', post_id: '1', association: 'tags'})
|
48
48
|
end
|
49
49
|
|
50
50
|
def test_routing_posts_links_tags_update_acts_as_set
|
51
|
-
assert_routing({path: '/posts/1/
|
51
|
+
assert_routing({path: '/posts/1/relationships/tags', method: :patch},
|
52
52
|
{controller: 'posts', action: 'update_association', post_id: '1', association: 'tags'})
|
53
53
|
end
|
54
54
|
|
@@ -64,13 +64,13 @@ class RoutesTest < ActionDispatch::IntegrationTest
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def test_routing_v1_posts_links_writer_show
|
67
|
-
assert_routing({path: '/api/v1/posts/1/
|
67
|
+
assert_routing({path: '/api/v1/posts/1/relationships/writer', method: :get},
|
68
68
|
{controller: 'api/v1/posts', action: 'show_association', post_id: '1', association: 'writer'})
|
69
69
|
end
|
70
70
|
|
71
71
|
# V2
|
72
72
|
def test_routing_v2_posts_links_author_show
|
73
|
-
assert_routing({path: '/api/v2/posts/1/
|
73
|
+
assert_routing({path: '/api/v2/posts/1/relationships/author', method: :get},
|
74
74
|
{controller: 'api/v2/posts', action: 'show_association', post_id: '1', association: 'author'})
|
75
75
|
end
|
76
76
|
|
@@ -93,14 +93,14 @@ class RoutesTest < ActionDispatch::IntegrationTest
|
|
93
93
|
|
94
94
|
def test_routing_v4_isoCurrencies_resources
|
95
95
|
assert_routing({path: '/api/v4/isoCurrencies/USD', method: :get},
|
96
|
-
{action: 'show', controller: 'api/v4/iso_currencies',
|
96
|
+
{action: 'show', controller: 'api/v4/iso_currencies', id: 'USD'})
|
97
97
|
end
|
98
98
|
|
99
99
|
def test_routing_v4_expenseEntries_resources
|
100
100
|
assert_routing({path: '/api/v4/expenseEntries/1', method: :get},
|
101
101
|
{action: 'show', controller: 'api/v4/expense_entries', id: '1'})
|
102
102
|
|
103
|
-
assert_routing({path: '/api/v4/expenseEntries/1/
|
103
|
+
assert_routing({path: '/api/v4/expenseEntries/1/relationships/isoCurrency', method: :get},
|
104
104
|
{controller: 'api/v4/expense_entries', action: 'show_association', expense_entry_id: '1', association: 'iso_currency'})
|
105
105
|
end
|
106
106
|
|
@@ -112,14 +112,14 @@ class RoutesTest < ActionDispatch::IntegrationTest
|
|
112
112
|
|
113
113
|
def test_routing_v5_isoCurrencies_resources
|
114
114
|
assert_routing({path: '/api/v5/iso-currencies/USD', method: :get},
|
115
|
-
{action: 'show', controller: 'api/v5/iso_currencies',
|
115
|
+
{action: 'show', controller: 'api/v5/iso_currencies', id: 'USD'})
|
116
116
|
end
|
117
117
|
|
118
118
|
def test_routing_v5_expenseEntries_resources
|
119
119
|
assert_routing({path: '/api/v5/expense-entries/1', method: :get},
|
120
120
|
{action: 'show', controller: 'api/v5/expense_entries', id: '1'})
|
121
121
|
|
122
|
-
assert_routing({path: '/api/v5/expense-entries/1/
|
122
|
+
assert_routing({path: '/api/v5/expense-entries/1/relationships/iso-currency', method: :get},
|
123
123
|
{controller: 'api/v5/expense_entries', action: 'show_association', expense_entry_id: '1', association: 'iso_currency'})
|
124
124
|
end
|
125
125
|
|
@@ -129,14 +129,14 @@ class RoutesTest < ActionDispatch::IntegrationTest
|
|
129
129
|
end
|
130
130
|
|
131
131
|
def test_routing_author_links_posts_create_not_acts_as_set
|
132
|
-
assert_routing({path: '/api/v5/authors/1/
|
132
|
+
assert_routing({path: '/api/v5/authors/1/relationships/posts', method: :post},
|
133
133
|
{controller: 'api/v5/authors', action: 'create_association', author_id: '1', association: 'posts'})
|
134
134
|
end
|
135
135
|
|
136
136
|
#primary_key
|
137
137
|
def test_routing_primary_key_jsonapi_resources
|
138
138
|
assert_routing({path: '/iso_currencies/USD', method: :get},
|
139
|
-
{action: 'show', controller: 'iso_currencies',
|
139
|
+
{action: 'show', controller: 'iso_currencies', id: 'USD'})
|
140
140
|
end
|
141
141
|
|
142
142
|
# ToDo: Refute routing
|
@@ -146,12 +146,12 @@ class RoutesTest < ActionDispatch::IntegrationTest
|
|
146
146
|
# end
|
147
147
|
|
148
148
|
# def test_routing_posts_links_author_except_destroy
|
149
|
-
# assert_routing({ path: '/api/v3/posts/1/
|
149
|
+
# assert_routing({ path: '/api/v3/posts/1/relationships/author', method: :delete },
|
150
150
|
# { controller: 'api/v3/posts', action: 'destroy_association', post_id: '1', association: 'author' })
|
151
151
|
# end
|
152
152
|
#
|
153
153
|
# def test_routing_posts_links_tags_only_create_show
|
154
|
-
# assert_routing({ path: '/api/v3/posts/1/
|
154
|
+
# assert_routing({ path: '/api/v3/posts/1/relationships/tags/1,2', method: :delete },
|
155
155
|
# { controller: 'api/v3/posts', action: 'destroy_association', post_id: '1', keys: '1,2', association: 'tags' })
|
156
156
|
# end
|
157
157
|
|
data/test/test_helper.rb
CHANGED
@@ -57,6 +57,16 @@ if Rails::VERSION::MAJOR >= 4 && Rails::VERSION::MINOR < 1
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
+
def count_queries(&block)
|
61
|
+
@query_count = 0
|
62
|
+
ActiveSupport::Notifications.subscribe('sql.active_record') do
|
63
|
+
@query_count = @query_count + 1
|
64
|
+
end
|
65
|
+
yield block
|
66
|
+
ActiveSupport::Notifications.unsubscribe('sql.active_record')
|
67
|
+
@query_count
|
68
|
+
end
|
69
|
+
|
60
70
|
TestApp.initialize!
|
61
71
|
|
62
72
|
require File.expand_path('../fixtures/active_record', __FILE__)
|
@@ -78,6 +88,7 @@ TestApp.routes.draw do
|
|
78
88
|
jsonapi_resources :moons
|
79
89
|
jsonapi_resources :preferences
|
80
90
|
jsonapi_resources :facts
|
91
|
+
jsonapi_resources :categories
|
81
92
|
|
82
93
|
namespace :api do
|
83
94
|
namespace :v1 do
|
@@ -131,6 +142,8 @@ TestApp.routes.draw do
|
|
131
142
|
|
132
143
|
jsonapi_resources :iso_currencies do
|
133
144
|
end
|
145
|
+
|
146
|
+
jsonapi_resources :books
|
134
147
|
end
|
135
148
|
|
136
149
|
JSONAPI.configuration.route_format = :dasherized_route
|
@@ -160,6 +173,10 @@ TestApp.routes.draw do
|
|
160
173
|
jsonapi_resources :purchase_orders
|
161
174
|
jsonapi_resources :line_items
|
162
175
|
end
|
176
|
+
|
177
|
+
namespace :v8 do
|
178
|
+
jsonapi_resources :numeros_telefone
|
179
|
+
end
|
163
180
|
end
|
164
181
|
end
|
165
182
|
|
@@ -199,7 +216,7 @@ end
|
|
199
216
|
|
200
217
|
class DateWithTimezoneValueFormatter < JSONAPI::ValueFormatter
|
201
218
|
class << self
|
202
|
-
def format(raw_value
|
219
|
+
def format(raw_value)
|
203
220
|
raw_value.in_time_zone('Eastern Time (US & Canada)').to_s
|
204
221
|
end
|
205
222
|
end
|
@@ -207,7 +224,7 @@ end
|
|
207
224
|
|
208
225
|
class DateValueFormatter < JSONAPI::ValueFormatter
|
209
226
|
class << self
|
210
|
-
def format(raw_value
|
227
|
+
def format(raw_value)
|
211
228
|
raw_value.strftime('%m/%d/%Y')
|
212
229
|
end
|
213
230
|
end
|
@@ -215,12 +232,13 @@ end
|
|
215
232
|
|
216
233
|
class TitleValueFormatter < JSONAPI::ValueFormatter
|
217
234
|
class << self
|
218
|
-
def format(raw_value
|
219
|
-
super(raw_value
|
235
|
+
def format(raw_value)
|
236
|
+
super(raw_value).titlecase
|
220
237
|
end
|
221
238
|
|
222
|
-
def unformat(value
|
239
|
+
def unformat(value)
|
223
240
|
value.to_s.downcase
|
224
241
|
end
|
225
242
|
end
|
226
243
|
end
|
244
|
+
|
@@ -1,5 +1,16 @@
|
|
1
1
|
require File.expand_path('../../../test_helper', __FILE__)
|
2
2
|
|
3
|
+
class CatResource < JSONAPI::Resource
|
4
|
+
attribute :id
|
5
|
+
attribute :name
|
6
|
+
attribute :breed
|
7
|
+
|
8
|
+
has_one :mother, class_name: 'Cat'
|
9
|
+
has_one :father, class_name: 'Cat'
|
10
|
+
|
11
|
+
filters :name
|
12
|
+
end
|
13
|
+
|
3
14
|
class JSONAPIRequestTest < ActiveSupport::TestCase
|
4
15
|
def test_parse_includes_underscored
|
5
16
|
params = ActionController::Parameters.new(
|
@@ -149,4 +160,41 @@ class JSONAPIRequestTest < ActiveSupport::TestCase
|
|
149
160
|
refute request.errors.empty?
|
150
161
|
assert_equal 'expense_entries is not a valid resource.', request.errors[0].detail
|
151
162
|
end
|
163
|
+
|
164
|
+
def test_parse_filters_with_valid_filters
|
165
|
+
setup_request
|
166
|
+
@request.parse_filters({name: 'Whiskers'})
|
167
|
+
assert_equal(@request.filters[:name], 'Whiskers')
|
168
|
+
assert_equal(@request.errors, [])
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_parse_filters_with_non_valid_filter
|
172
|
+
setup_request
|
173
|
+
@request.parse_filters({breed: 'Whiskers'}) # breed is not a set filter
|
174
|
+
assert_equal(@request.filters, {})
|
175
|
+
assert_equal(@request.errors.count, 1)
|
176
|
+
assert_equal(@request.errors.first.title, "Filter not allowed")
|
177
|
+
end
|
178
|
+
|
179
|
+
def test_parse_filters_with_no_filters
|
180
|
+
setup_request
|
181
|
+
@request.parse_filters(nil)
|
182
|
+
assert_equal(@request.filters, {})
|
183
|
+
assert_equal(@request.errors, [])
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_parse_filters_with_invalid_filters_param
|
187
|
+
setup_request
|
188
|
+
@request.parse_filters('noeach') # String does not implement #each
|
189
|
+
assert_equal(@request.filters, {})
|
190
|
+
assert_equal(@request.errors.count, 1)
|
191
|
+
assert_equal(@request.errors.first.title, "Invalid filters syntax")
|
192
|
+
end
|
193
|
+
|
194
|
+
private
|
195
|
+
|
196
|
+
def setup_request
|
197
|
+
@request = JSONAPI::Request.new
|
198
|
+
@request.resource_klass = CatResource
|
199
|
+
end
|
152
200
|
end
|
@@ -1,9 +1,5 @@
|
|
1
1
|
require File.expand_path('../../../test_helper', __FILE__)
|
2
2
|
|
3
|
-
require 'jsonapi/operation'
|
4
|
-
require 'jsonapi/operation_result'
|
5
|
-
require 'jsonapi/operations_processor'
|
6
|
-
|
7
3
|
class TestOperationsProcessor < JSONAPI::OperationsProcessor
|
8
4
|
before_operation :log_before_operation
|
9
5
|
|
@@ -68,18 +64,17 @@ class OperationsProcessorTest < Minitest::Test
|
|
68
64
|
count = Planet.count
|
69
65
|
|
70
66
|
operations = [
|
71
|
-
JSONAPI::CreateResourceOperation.new(PlanetResource, {attributes: {'name' => 'earth', 'description' => 'The best planet ever.'}})
|
67
|
+
JSONAPI::CreateResourceOperation.new(PlanetResource, data: {attributes: {'name' => 'earth', 'description' => 'The best planet ever.'}})
|
72
68
|
]
|
73
69
|
|
74
70
|
request = JSONAPI::Request.new
|
75
71
|
request.operations = operations
|
76
72
|
|
77
|
-
|
73
|
+
operation_results = op.process(request)
|
78
74
|
|
79
|
-
assert_kind_of(
|
80
|
-
|
81
|
-
assert_equal(
|
82
|
-
assert_equal(results.size, 1)
|
75
|
+
assert_kind_of(JSONAPI::OperationResults, operation_results)
|
76
|
+
assert_equal(:created, operation_results.results[0].code)
|
77
|
+
assert_equal(operation_results.results.size, 1)
|
83
78
|
assert_equal(Planet.count, count + 1)
|
84
79
|
end
|
85
80
|
|
@@ -89,18 +84,18 @@ class OperationsProcessorTest < Minitest::Test
|
|
89
84
|
count = Planet.count
|
90
85
|
|
91
86
|
operations = [
|
92
|
-
JSONAPI::CreateResourceOperation.new(PlanetResource, {attributes: {'name' => 'earth', 'description' => 'The best planet for life.'}}),
|
93
|
-
JSONAPI::CreateResourceOperation.new(PlanetResource, {attributes: {'name' => 'mars', 'description' => 'The red planet.'}}),
|
94
|
-
JSONAPI::CreateResourceOperation.new(PlanetResource, {attributes: {'name' => 'venus', 'description' => 'A very hot planet.'}})
|
87
|
+
JSONAPI::CreateResourceOperation.new(PlanetResource, data: {attributes: {'name' => 'earth', 'description' => 'The best planet for life.'}}),
|
88
|
+
JSONAPI::CreateResourceOperation.new(PlanetResource, data: {attributes: {'name' => 'mars', 'description' => 'The red planet.'}}),
|
89
|
+
JSONAPI::CreateResourceOperation.new(PlanetResource, data: {attributes: {'name' => 'venus', 'description' => 'A very hot planet.'}})
|
95
90
|
]
|
96
91
|
|
97
92
|
request = JSONAPI::Request.new
|
98
93
|
request.operations = operations
|
99
94
|
|
100
|
-
|
95
|
+
operation_results = op.process(request)
|
101
96
|
|
102
|
-
assert_kind_of(
|
103
|
-
assert_equal(results.size, 3)
|
97
|
+
assert_kind_of(JSONAPI::OperationResults, operation_results)
|
98
|
+
assert_equal(operation_results.results.size, 3)
|
104
99
|
assert_equal(Planet.count, count + 3)
|
105
100
|
end
|
106
101
|
|
@@ -113,42 +108,63 @@ class OperationsProcessorTest < Minitest::Test
|
|
113
108
|
assert_equal(saturn.planet_type_id, planetoid.id)
|
114
109
|
|
115
110
|
operations = [
|
116
|
-
JSONAPI::ReplaceHasOneAssociationOperation.new(
|
111
|
+
JSONAPI::ReplaceHasOneAssociationOperation.new(
|
112
|
+
PlanetResource,
|
113
|
+
{
|
114
|
+
resource_id: saturn.id,
|
115
|
+
association_type: :planet_type,
|
116
|
+
key_value: gas_giant.id
|
117
|
+
}
|
118
|
+
)
|
117
119
|
]
|
118
120
|
|
119
121
|
request = JSONAPI::Request.new
|
120
122
|
request.operations = operations
|
121
123
|
|
122
|
-
|
124
|
+
operation_results = op.process(request)
|
123
125
|
|
124
|
-
assert_kind_of(
|
125
|
-
assert_kind_of(JSONAPI::OperationResult, results[0])
|
126
|
-
assert_equal(:no_content, results[0].code)
|
126
|
+
assert_kind_of(JSONAPI::OperationResults, operation_results)
|
127
|
+
assert_kind_of(JSONAPI::OperationResult, operation_results.results[0])
|
128
|
+
assert_equal(:no_content, operation_results.results[0].code)
|
127
129
|
|
128
130
|
saturn.reload
|
129
131
|
assert_equal(saturn.planet_type_id, gas_giant.id)
|
130
132
|
|
131
133
|
# Remove link
|
132
134
|
operations = [
|
133
|
-
JSONAPI::ReplaceHasOneAssociationOperation.new(
|
135
|
+
JSONAPI::ReplaceHasOneAssociationOperation.new(
|
136
|
+
PlanetResource,
|
137
|
+
{
|
138
|
+
resource_id: saturn.id,
|
139
|
+
association_type: :planet_type,
|
140
|
+
key_value: nil
|
141
|
+
}
|
142
|
+
)
|
134
143
|
]
|
135
144
|
|
136
145
|
request = JSONAPI::Request.new
|
137
146
|
request.operations = operations
|
138
147
|
|
139
|
-
|
148
|
+
op.process(request)
|
140
149
|
saturn.reload
|
141
150
|
assert_equal(saturn.planet_type_id, nil)
|
142
151
|
|
143
152
|
# Reset
|
144
153
|
operations = [
|
145
|
-
JSONAPI::ReplaceHasOneAssociationOperation.new(
|
154
|
+
JSONAPI::ReplaceHasOneAssociationOperation.new(
|
155
|
+
PlanetResource,
|
156
|
+
{
|
157
|
+
resource_id: saturn.id,
|
158
|
+
association_type: :planet_type,
|
159
|
+
key_value: 5
|
160
|
+
}
|
161
|
+
)
|
146
162
|
]
|
147
163
|
|
148
164
|
request = JSONAPI::Request.new
|
149
165
|
request.operations = operations
|
150
166
|
|
151
|
-
|
167
|
+
op.process(request)
|
152
168
|
saturn.reload
|
153
169
|
assert_equal(saturn.planet_type_id, 5)
|
154
170
|
end
|
@@ -169,13 +185,20 @@ class OperationsProcessorTest < Minitest::Test
|
|
169
185
|
betaz.save!
|
170
186
|
|
171
187
|
operations = [
|
172
|
-
JSONAPI::CreateHasManyAssociationOperation.new(
|
188
|
+
JSONAPI::CreateHasManyAssociationOperation.new(
|
189
|
+
PlanetTypeResource,
|
190
|
+
{
|
191
|
+
resource_id: gas_giant.id,
|
192
|
+
association_type: :planets,
|
193
|
+
data: [betax.id, betay.id, betaz.id]
|
194
|
+
}
|
195
|
+
)
|
173
196
|
]
|
174
197
|
|
175
198
|
request = JSONAPI::Request.new
|
176
199
|
request.operations = operations
|
177
200
|
|
178
|
-
|
201
|
+
op.process(request)
|
179
202
|
|
180
203
|
betax.reload
|
181
204
|
betay.reload
|
@@ -210,13 +233,20 @@ class OperationsProcessorTest < Minitest::Test
|
|
210
233
|
betaz.save!
|
211
234
|
|
212
235
|
operations = [
|
213
|
-
JSONAPI::ReplaceHasManyAssociationOperation.new(
|
236
|
+
JSONAPI::ReplaceHasManyAssociationOperation.new(
|
237
|
+
PlanetTypeResource,
|
238
|
+
{
|
239
|
+
resource_id: gas_giant.id,
|
240
|
+
association_type: :planets,
|
241
|
+
data: [betax.id, betay.id, betaz.id]
|
242
|
+
}
|
243
|
+
)
|
214
244
|
]
|
215
245
|
|
216
246
|
request = JSONAPI::Request.new
|
217
247
|
request.operations = operations
|
218
248
|
|
219
|
-
|
249
|
+
op.process(request)
|
220
250
|
|
221
251
|
betax.reload
|
222
252
|
betay.reload
|
@@ -243,19 +273,25 @@ class OperationsProcessorTest < Minitest::Test
|
|
243
273
|
assert_equal(saturn.name, 'Satern')
|
244
274
|
|
245
275
|
operations = [
|
246
|
-
JSONAPI::ReplaceFieldsOperation.new(
|
276
|
+
JSONAPI::ReplaceFieldsOperation.new(
|
277
|
+
PlanetResource,
|
278
|
+
{
|
279
|
+
resource_id: 1,
|
280
|
+
data: {attributes: {'name' => 'saturn'}}
|
281
|
+
}
|
282
|
+
)
|
247
283
|
]
|
248
284
|
|
249
285
|
request = JSONAPI::Request.new
|
250
286
|
request.operations = operations
|
251
287
|
|
252
|
-
|
288
|
+
operation_results = op.process(request)
|
253
289
|
|
254
|
-
assert_kind_of(
|
255
|
-
assert_equal(results.size, 1)
|
290
|
+
assert_kind_of(JSONAPI::OperationResults, operation_results)
|
291
|
+
assert_equal(operation_results.results.size, 1)
|
256
292
|
|
257
|
-
assert_kind_of(JSONAPI::
|
258
|
-
assert_equal(:ok, results[0].code)
|
293
|
+
assert_kind_of(JSONAPI::ResourceOperationResult, operation_results.results[0])
|
294
|
+
assert_equal(:ok, operation_results.results[0].code)
|
259
295
|
|
260
296
|
saturn = Planet.find(1)
|
261
297
|
|
@@ -268,51 +304,203 @@ class OperationsProcessorTest < Minitest::Test
|
|
268
304
|
op = JSONAPI::OperationsProcessor.new
|
269
305
|
|
270
306
|
count = Planet.count
|
271
|
-
|
272
|
-
assert_equal(
|
307
|
+
makemake = Planet.find(2)
|
308
|
+
assert_equal(makemake.name, 'Makemake')
|
273
309
|
|
274
310
|
operations = [
|
275
|
-
JSONAPI::RemoveResourceOperation.new(PlanetResource, 2),
|
311
|
+
JSONAPI::RemoveResourceOperation.new(PlanetResource, resource_id: 2),
|
276
312
|
]
|
277
313
|
|
278
314
|
request = JSONAPI::Request.new
|
279
315
|
request.operations = operations
|
280
316
|
|
281
|
-
|
317
|
+
operation_results = op.process(request)
|
282
318
|
|
283
|
-
assert_kind_of(
|
284
|
-
assert_equal(results.size, 1)
|
319
|
+
assert_kind_of(JSONAPI::OperationResults, operation_results)
|
320
|
+
assert_equal(operation_results.results.size, 1)
|
285
321
|
|
286
|
-
assert_kind_of(JSONAPI::OperationResult, results[0])
|
287
|
-
assert_equal(:no_content, results[0].code)
|
322
|
+
assert_kind_of(JSONAPI::OperationResult, operation_results.results[0])
|
323
|
+
assert_equal(:no_content, operation_results.results[0].code)
|
288
324
|
assert_equal(Planet.count, count - 1)
|
289
325
|
end
|
290
326
|
|
291
327
|
def test_rollback_from_error
|
292
|
-
op =
|
328
|
+
op = ActiveRecordOperationsProcessor.new
|
293
329
|
|
294
330
|
count = Planet.count
|
295
331
|
|
296
332
|
operations = [
|
297
|
-
JSONAPI::RemoveResourceOperation.new(PlanetResource, 3),
|
298
|
-
JSONAPI::RemoveResourceOperation.new(PlanetResource, 4),
|
299
|
-
JSONAPI::RemoveResourceOperation.new(PlanetResource, 4)
|
333
|
+
JSONAPI::RemoveResourceOperation.new(PlanetResource, resource_id: 3),
|
334
|
+
JSONAPI::RemoveResourceOperation.new(PlanetResource, resource_id: 4),
|
335
|
+
JSONAPI::RemoveResourceOperation.new(PlanetResource, resource_id: 4)
|
300
336
|
]
|
301
337
|
|
302
338
|
request = JSONAPI::Request.new
|
303
339
|
request.operations = operations
|
304
340
|
|
305
|
-
|
341
|
+
operation_results = op.process(request)
|
342
|
+
|
343
|
+
assert_kind_of(JSONAPI::OperationResults, operation_results)
|
306
344
|
|
307
345
|
assert_equal(Planet.count, count)
|
308
346
|
|
309
|
-
|
310
|
-
assert_equal(results.size, 3)
|
347
|
+
assert_equal(operation_results.results.size, 3)
|
311
348
|
|
312
|
-
assert_kind_of(JSONAPI::OperationResult, results[0])
|
313
|
-
assert_equal(:no_content, results[0].code)
|
314
|
-
assert_equal(:no_content, results[1].code)
|
315
|
-
assert_equal(404, results[2].code)
|
349
|
+
assert_kind_of(JSONAPI::OperationResult, operation_results.results[0])
|
350
|
+
assert_equal(:no_content, operation_results.results[0].code)
|
351
|
+
assert_equal(:no_content, operation_results.results[1].code)
|
352
|
+
assert_equal(404, operation_results.results[2].code)
|
316
353
|
end
|
317
354
|
|
355
|
+
def test_show_operation
|
356
|
+
op = JSONAPI::OperationsProcessor.new
|
357
|
+
|
358
|
+
operations = [
|
359
|
+
JSONAPI::ShowOperation.new(PlanetResource, {id: '1'})
|
360
|
+
]
|
361
|
+
|
362
|
+
request = JSONAPI::Request.new
|
363
|
+
request.operations = operations
|
364
|
+
|
365
|
+
operation_results = op.process(request)
|
366
|
+
|
367
|
+
assert_kind_of(JSONAPI::OperationResults, operation_results)
|
368
|
+
assert_equal(operation_results.results.size, 1)
|
369
|
+
refute operation_results.has_errors?
|
370
|
+
end
|
371
|
+
|
372
|
+
def test_show_operation_error
|
373
|
+
op = JSONAPI::OperationsProcessor.new
|
374
|
+
|
375
|
+
operations = [
|
376
|
+
JSONAPI::ShowOperation.new(PlanetResource, {id: '145'})
|
377
|
+
]
|
378
|
+
|
379
|
+
request = JSONAPI::Request.new
|
380
|
+
request.operations = operations
|
381
|
+
|
382
|
+
operation_results = op.process(request)
|
383
|
+
|
384
|
+
assert_kind_of(JSONAPI::OperationResults, operation_results)
|
385
|
+
assert_equal(operation_results.results.size, 1)
|
386
|
+
assert operation_results.has_errors?
|
387
|
+
end
|
388
|
+
|
389
|
+
def test_show_association_operation
|
390
|
+
op = JSONAPI::OperationsProcessor.new
|
391
|
+
|
392
|
+
operations = [
|
393
|
+
JSONAPI::ShowAssociationOperation.new(PlanetResource, {parent_key: '1', association_type: :planet_type})
|
394
|
+
]
|
395
|
+
|
396
|
+
request = JSONAPI::Request.new
|
397
|
+
request.operations = operations
|
398
|
+
|
399
|
+
operation_results = op.process(request)
|
400
|
+
|
401
|
+
assert_kind_of(JSONAPI::OperationResults, operation_results)
|
402
|
+
assert_equal(operation_results.results.size, 1)
|
403
|
+
refute operation_results.has_errors?
|
404
|
+
end
|
405
|
+
|
406
|
+
def test_show_association_operation_error
|
407
|
+
op = JSONAPI::OperationsProcessor.new
|
408
|
+
|
409
|
+
operations = [
|
410
|
+
JSONAPI::ShowAssociationOperation.new(PlanetResource, {parent_key: '145', association_type: :planet_type})
|
411
|
+
]
|
412
|
+
|
413
|
+
request = JSONAPI::Request.new
|
414
|
+
request.operations = operations
|
415
|
+
|
416
|
+
operation_results = op.process(request)
|
417
|
+
|
418
|
+
assert_kind_of(JSONAPI::OperationResults, operation_results)
|
419
|
+
assert_equal(operation_results.results.size, 1)
|
420
|
+
assert operation_results.has_errors?
|
421
|
+
end
|
422
|
+
|
423
|
+
def test_show_related_resource_operation
|
424
|
+
op = JSONAPI::OperationsProcessor.new
|
425
|
+
|
426
|
+
operations = [
|
427
|
+
JSONAPI::ShowRelatedResourceOperation.new(PlanetResource,
|
428
|
+
{
|
429
|
+
source_klass: PlanetResource,
|
430
|
+
source_id: '1',
|
431
|
+
association_type: :planet_type})
|
432
|
+
]
|
433
|
+
|
434
|
+
request = JSONAPI::Request.new
|
435
|
+
request.operations = operations
|
436
|
+
|
437
|
+
operation_results = op.process(request)
|
438
|
+
|
439
|
+
assert_kind_of(JSONAPI::OperationResults, operation_results)
|
440
|
+
assert_equal(operation_results.results.size, 1)
|
441
|
+
refute operation_results.has_errors?
|
442
|
+
end
|
443
|
+
|
444
|
+
def test_show_related_resource_operation_error
|
445
|
+
op = JSONAPI::OperationsProcessor.new
|
446
|
+
|
447
|
+
operations = [
|
448
|
+
JSONAPI::ShowRelatedResourceOperation.new(PlanetResource,
|
449
|
+
{
|
450
|
+
source_klass: PlanetResource,
|
451
|
+
source_id: '145',
|
452
|
+
association_type: :planet_type})
|
453
|
+
]
|
454
|
+
|
455
|
+
request = JSONAPI::Request.new
|
456
|
+
request.operations = operations
|
457
|
+
|
458
|
+
operation_results = op.process(request)
|
459
|
+
|
460
|
+
assert_kind_of(JSONAPI::OperationResults, operation_results)
|
461
|
+
assert_equal(operation_results.results.size, 1)
|
462
|
+
assert operation_results.has_errors?
|
463
|
+
end
|
464
|
+
|
465
|
+
def test_show_related_resources_operation
|
466
|
+
op = JSONAPI::OperationsProcessor.new
|
467
|
+
|
468
|
+
operations = [
|
469
|
+
JSONAPI::ShowRelatedResourcesOperation.new(PlanetResource,
|
470
|
+
{
|
471
|
+
source_klass: PlanetResource,
|
472
|
+
source_id: '1',
|
473
|
+
association_type: :moons})
|
474
|
+
]
|
475
|
+
|
476
|
+
request = JSONAPI::Request.new
|
477
|
+
request.operations = operations
|
478
|
+
|
479
|
+
operation_results = op.process(request)
|
480
|
+
|
481
|
+
assert_kind_of(JSONAPI::OperationResults, operation_results)
|
482
|
+
assert_equal(operation_results.results.size, 1)
|
483
|
+
refute operation_results.has_errors?
|
484
|
+
end
|
485
|
+
|
486
|
+
def test_show_related_resources_operation_error
|
487
|
+
op = JSONAPI::OperationsProcessor.new
|
488
|
+
|
489
|
+
operations = [
|
490
|
+
JSONAPI::ShowRelatedResourcesOperation.new(PlanetResource,
|
491
|
+
{
|
492
|
+
source_klass: PlanetResource,
|
493
|
+
source_id: '145',
|
494
|
+
association_type: :moons})
|
495
|
+
]
|
496
|
+
|
497
|
+
request = JSONAPI::Request.new
|
498
|
+
request.operations = operations
|
499
|
+
|
500
|
+
operation_results = op.process(request)
|
501
|
+
|
502
|
+
assert_kind_of(JSONAPI::OperationResults, operation_results)
|
503
|
+
assert_equal(operation_results.results.size, 1)
|
504
|
+
assert operation_results.has_errors?
|
505
|
+
end
|
318
506
|
end
|