jsonapi-resources 0.3.3 → 0.4.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 +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
|