iknow_view_models 3.1.8 → 3.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +6 -6
  3. data/.rubocop.yml +18 -0
  4. data/Appraisals +6 -6
  5. data/Gemfile +6 -2
  6. data/Rakefile +5 -5
  7. data/gemfiles/rails_5_2.gemfile +5 -5
  8. data/gemfiles/rails_6_0.gemfile +9 -0
  9. data/iknow_view_models.gemspec +40 -38
  10. data/lib/iknow_view_models.rb +9 -7
  11. data/lib/iknow_view_models/version.rb +1 -1
  12. data/lib/view_model.rb +31 -17
  13. data/lib/view_model/access_control.rb +5 -2
  14. data/lib/view_model/access_control/composed.rb +10 -9
  15. data/lib/view_model/access_control/open.rb +2 -0
  16. data/lib/view_model/access_control/read_only.rb +2 -0
  17. data/lib/view_model/access_control/tree.rb +11 -6
  18. data/lib/view_model/access_control_error.rb +4 -1
  19. data/lib/view_model/active_record.rb +17 -15
  20. data/lib/view_model/active_record/association_data.rb +2 -1
  21. data/lib/view_model/active_record/association_manipulation.rb +6 -4
  22. data/lib/view_model/active_record/cache.rb +114 -34
  23. data/lib/view_model/active_record/cache/cacheable_view.rb +2 -2
  24. data/lib/view_model/active_record/collection_nested_controller.rb +3 -3
  25. data/lib/view_model/active_record/controller.rb +68 -1
  26. data/lib/view_model/active_record/controller_base.rb +4 -1
  27. data/lib/view_model/active_record/nested_controller_base.rb +1 -0
  28. data/lib/view_model/active_record/update_context.rb +8 -6
  29. data/lib/view_model/active_record/update_data.rb +32 -30
  30. data/lib/view_model/active_record/update_operation.rb +17 -13
  31. data/lib/view_model/active_record/visitor.rb +0 -1
  32. data/lib/view_model/after_transaction_runner.rb +0 -1
  33. data/lib/view_model/callbacks.rb +3 -1
  34. data/lib/view_model/controller.rb +13 -3
  35. data/lib/view_model/deserialization_error.rb +15 -12
  36. data/lib/view_model/error.rb +12 -10
  37. data/lib/view_model/error_view.rb +3 -1
  38. data/lib/view_model/migratable_view.rb +78 -0
  39. data/lib/view_model/migration.rb +48 -0
  40. data/lib/view_model/migration/no_path_error.rb +26 -0
  41. data/lib/view_model/migration/one_way_error.rb +24 -0
  42. data/lib/view_model/migration/unspecified_version_error.rb +24 -0
  43. data/lib/view_model/migrator.rb +108 -0
  44. data/lib/view_model/record.rb +15 -14
  45. data/lib/view_model/reference.rb +3 -1
  46. data/lib/view_model/references.rb +8 -5
  47. data/lib/view_model/registry.rb +14 -2
  48. data/lib/view_model/schemas.rb +9 -4
  49. data/lib/view_model/serialization_error.rb +4 -1
  50. data/lib/view_model/serialize_context.rb +4 -4
  51. data/lib/view_model/test_helpers.rb +8 -3
  52. data/lib/view_model/test_helpers/arvm_builder.rb +21 -15
  53. data/lib/view_model/traversal_context.rb +2 -1
  54. data/nix/dependencies.nix +5 -0
  55. data/nix/gem/generate.rb +2 -1
  56. data/shell.nix +8 -3
  57. data/test/.rubocop.yml +14 -0
  58. data/test/helpers/arvm_test_models.rb +12 -9
  59. data/test/helpers/arvm_test_utilities.rb +5 -3
  60. data/test/helpers/controller_test_helpers.rb +55 -32
  61. data/test/helpers/match_enumerator.rb +1 -0
  62. data/test/helpers/query_logging.rb +2 -1
  63. data/test/helpers/test_access_control.rb +5 -3
  64. data/test/helpers/viewmodel_spec_helpers.rb +88 -22
  65. data/test/unit/view_model/access_control_test.rb +144 -144
  66. data/test/unit/view_model/active_record/alias_test.rb +15 -13
  67. data/test/unit/view_model/active_record/belongs_to_test.rb +40 -39
  68. data/test/unit/view_model/active_record/cache_test.rb +68 -31
  69. data/test/unit/view_model/active_record/cloner_test.rb +67 -63
  70. data/test/unit/view_model/active_record/controller_test.rb +113 -65
  71. data/test/unit/view_model/active_record/counter_test.rb +10 -9
  72. data/test/unit/view_model/active_record/customization_test.rb +59 -58
  73. data/test/unit/view_model/active_record/has_many_test.rb +112 -111
  74. data/test/unit/view_model/active_record/has_many_through_poly_test.rb +15 -14
  75. data/test/unit/view_model/active_record/has_many_through_test.rb +33 -38
  76. data/test/unit/view_model/active_record/has_one_test.rb +37 -36
  77. data/test/unit/view_model/active_record/migration_test.rb +161 -0
  78. data/test/unit/view_model/active_record/namespacing_test.rb +19 -17
  79. data/test/unit/view_model/active_record/poly_test.rb +44 -45
  80. data/test/unit/view_model/active_record/shared_test.rb +30 -28
  81. data/test/unit/view_model/active_record/version_test.rb +9 -7
  82. data/test/unit/view_model/active_record_test.rb +72 -72
  83. data/test/unit/view_model/callbacks_test.rb +19 -15
  84. data/test/unit/view_model/controller_test.rb +4 -2
  85. data/test/unit/view_model/record_test.rb +158 -145
  86. data/test/unit/view_model/registry_test.rb +38 -0
  87. data/test/unit/view_model/traversal_context_test.rb +4 -5
  88. data/test/unit/view_model_test.rb +18 -16
  89. metadata +38 -12
  90. data/.travis.yml +0 -31
  91. data/appveyor.yml +0 -22
  92. data/gemfiles/rails_6_0_beta.gemfile +0 -9
@@ -1,14 +1,16 @@
1
- require "minitest/autorun"
2
- require "minitest/unit"
3
- require "minitest/hooks"
1
+ # frozen_string_literal: true
4
2
 
5
- require_relative "../../../helpers/arvm_test_models.rb"
6
- require_relative "../../../helpers/viewmodel_spec_helpers.rb"
3
+ require 'minitest/autorun'
4
+ require 'minitest/unit'
5
+ require 'minitest/hooks'
6
+
7
+ require_relative '../../../helpers/arvm_test_models'
8
+ require_relative '../../../helpers/viewmodel_spec_helpers'
7
9
 
8
10
  # MiniTest::Spec.register_spec_type(/./, Minitest::HooksSpec)
9
11
 
10
- require "view_model"
11
- require "view_model/active_record"
12
+ require 'view_model'
13
+ require 'view_model/active_record'
12
14
 
13
15
  class ViewModel::ActiveRecord
14
16
  class ClonerTest < ActiveSupport::TestCase
@@ -18,7 +20,7 @@ class ViewModel::ActiveRecord
18
20
  let(:viewmodel) { create_viewmodel! }
19
21
  let(:model) { viewmodel.model }
20
22
 
21
- describe "with single model" do
23
+ describe 'with single model' do
22
24
  include ViewModelSpecHelpers::Single
23
25
 
24
26
  def model_attributes
@@ -26,15 +28,15 @@ class ViewModel::ActiveRecord
26
28
  end
27
29
 
28
30
  def new_model
29
- model_class.new(name: "a", nonview: "b")
31
+ model_class.new(name: 'a', nonview: 'b')
30
32
  end
31
33
 
32
- it "persists the test setup" do
34
+ it 'persists the test setup' do
33
35
  assert(viewmodel.model.persisted?)
34
36
  refute(viewmodel.model.new_record?)
35
37
  end
36
38
 
37
- it "can clone the model" do
39
+ it 'can clone the model' do
38
40
  clone_model = Cloner.new.clone(viewmodel)
39
41
  assert(clone_model.new_record?)
40
42
  assert_nil(clone_model.id)
@@ -45,75 +47,75 @@ class ViewModel::ActiveRecord
45
47
  end
46
48
 
47
49
  class IgnoreParentCloner < Cloner
48
- def visit_model_view(node, model)
50
+ def visit_model_view(_node, _model)
49
51
  ignore!
50
52
  end
51
53
  end
52
54
 
53
- it "can ignore a model" do
55
+ it 'can ignore a model' do
54
56
  clone_model = IgnoreParentCloner.new.clone(viewmodel)
55
57
  assert_nil(clone_model)
56
58
  end
57
59
 
58
60
  class IgnoreAllCloner < Cloner
59
- def pre_visit(node, model)
61
+ def pre_visit(_node, _model)
60
62
  ignore!
61
63
  end
62
64
  end
63
65
 
64
- it "can ignore a model in pre-visit" do
66
+ it 'can ignore a model in pre-visit' do
65
67
  clone_model = IgnoreAllCloner.new.clone(viewmodel)
66
68
  assert_nil(clone_model)
67
69
  end
68
70
 
69
71
  class AlterAttributeCloner < Cloner
70
- def visit_model_view(node, model)
71
- model.name = "changed"
72
+ def visit_model_view(_node, model)
73
+ model.name = 'changed'
72
74
  end
73
75
  end
74
76
 
75
- it "can alter a model attribute" do
77
+ it 'can alter a model attribute' do
76
78
  clone_model = AlterAttributeCloner.new.clone(viewmodel)
77
79
  assert(clone_model.new_record?)
78
80
  assert_nil(clone_model.id)
79
- assert_equal("changed", clone_model.name)
80
- refute_equal("changed", model.name)
81
+ assert_equal('changed', clone_model.name)
82
+ refute_equal('changed', model.name)
81
83
  assert_equal(model.nonview, clone_model.nonview)
82
84
  clone_model.save!
83
85
  refute_equal(model, clone_model)
84
86
  end
85
87
 
86
88
  class PostAlterAttributeCloner < Cloner
87
- def end_visit_model_view(node, model)
88
- model.name = "changed"
89
+ def end_visit_model_view(_node, model)
90
+ model.name = 'changed'
89
91
  end
90
92
  end
91
93
 
92
- it "can alter a model attribute post-visit" do
94
+ it 'can alter a model attribute post-visit' do
93
95
  clone_model = PostAlterAttributeCloner.new.clone(viewmodel)
94
96
  assert(clone_model.new_record?)
95
97
  assert_nil(clone_model.id)
96
- assert_equal("changed", clone_model.name)
97
- refute_equal("changed", model.name)
98
+ assert_equal('changed', clone_model.name)
99
+ refute_equal('changed', model.name)
98
100
  assert_equal(model.nonview, clone_model.nonview)
99
101
  clone_model.save!
100
102
  refute_equal(model, clone_model)
101
103
  end
102
104
  end
103
105
 
104
- describe "with a child" do
106
+ describe 'with a child' do
105
107
  def new_child_model
106
- child_model_class.new(name: "b")
108
+ child_model_class.new(name: 'b')
107
109
  end
108
110
 
109
111
  def new_model
110
- model_class.new(name: "a", child: new_child_model)
112
+ model_class.new(name: 'a', child: new_child_model)
111
113
  end
112
114
 
113
115
  module BehavesLikeConstructingAChild
114
116
  extend ActiveSupport::Concern
115
117
  included do
116
- it "persists the test setup" do
118
+ it 'persists the test setup' do
117
119
  assert(viewmodel.model.persisted?)
118
120
  refute(viewmodel.model.new_record?)
119
121
  assert(viewmodel.model.child.persisted?)
@@ -123,7 +125,7 @@ class ViewModel::ActiveRecord
123
125
  end
124
126
 
125
127
  class IgnoreChildAssociationCloner < Cloner
126
- def visit_model_view(node, model)
128
+ def visit_model_view(_node, _model)
127
129
  ignore_association!(:child)
128
130
  end
129
131
  end
@@ -131,7 +133,7 @@ class ViewModel::ActiveRecord
131
133
  module BehavesLikeCloningAChild
132
134
  extend ActiveSupport::Concern
133
135
  included do
134
- it "can clone the model and child" do
136
+ it 'can clone the model and child' do
135
137
  clone_model = Cloner.new.clone(viewmodel)
136
138
 
137
139
  assert(clone_model.new_record?)
@@ -148,7 +150,7 @@ class ViewModel::ActiveRecord
148
150
  refute_equal(model.child, clone_model.child)
149
151
  end
150
152
 
151
- it "can ignore the child association" do
153
+ it 'can ignore the child association' do
152
154
  clone_model = IgnoreChildAssociationCloner.new.clone(viewmodel)
153
155
 
154
156
  assert(clone_model.new_record?)
@@ -160,66 +162,67 @@ class ViewModel::ActiveRecord
160
162
  end
161
163
  end
162
164
 
163
- describe "as belongs_to" do
165
+ describe 'as belongs_to' do
164
166
  include ViewModelSpecHelpers::ParentAndBelongsToChild
165
167
  include BehavesLikeConstructingAChild
166
168
  include BehavesLikeCloningAChild
167
169
  end
168
170
 
169
- describe "as has_one" do
171
+ describe 'as has_one' do
170
172
  include ViewModelSpecHelpers::ParentAndHasOneChild
171
173
  include BehavesLikeConstructingAChild
172
174
  include BehavesLikeCloningAChild
173
175
  end
174
176
 
175
- describe "as belongs_to shared child" do
177
+ describe 'as belongs_to shared child' do
176
178
  include ViewModelSpecHelpers::ParentAndSharedBelongsToChild
177
179
  include BehavesLikeConstructingAChild
178
- it "can clone the model but not the child" do
179
- clone_model = Cloner.new.clone(viewmodel)
180
180
 
181
- assert(clone_model.new_record?)
182
- assert_nil(clone_model.id)
183
- assert_equal(model.name, clone_model.name)
181
+ it 'can clone the model but not the child' do
182
+ clone_model = Cloner.new.clone(viewmodel)
184
183
 
185
- clone_child = clone_model.child
186
- refute(clone_child.new_record?)
187
- assert_equal(model.child, clone_child)
184
+ assert(clone_model.new_record?)
185
+ assert_nil(clone_model.id)
186
+ assert_equal(model.name, clone_model.name)
188
187
 
189
- clone_model.save!
190
- refute_equal(model, clone_model)
191
- assert_equal(model.child, clone_model.child)
192
- end
188
+ clone_child = clone_model.child
189
+ refute(clone_child.new_record?)
190
+ assert_equal(model.child, clone_child)
191
+
192
+ clone_model.save!
193
+ refute_equal(model, clone_model)
194
+ assert_equal(model.child, clone_model.child)
195
+ end
193
196
  end
194
197
  end
195
198
 
196
199
  class IgnoreChildrenAssociationCloner < Cloner
197
- def visit_model_view(node, model)
200
+ def visit_model_view(_node, _model)
198
201
  ignore_association!(:children)
199
202
  end
200
203
  end
201
204
 
202
- describe "with has_many children" do
205
+ describe 'with has_many children' do
203
206
  include ViewModelSpecHelpers::ParentAndHasManyChildren
204
207
  def new_child_models
205
- ["b", "c"].map { |n| child_model_class.new(name: n) }
208
+ ['b', 'c'].map { |n| child_model_class.new(name: n) }
206
209
  end
207
210
 
208
211
  def new_model
209
- model_class.new(name: "a", children: new_child_models)
212
+ model_class.new(name: 'a', children: new_child_models)
210
213
  end
211
214
 
212
- it "persists the test setup" do
215
+ it 'persists the test setup' do
213
216
  assert(viewmodel.model.persisted?)
214
217
  refute(viewmodel.model.new_record?)
215
218
  assert_equal(2, viewmodel.model.children.size)
216
- viewmodel.model.children.each do | child|
219
+ viewmodel.model.children.each do |child|
217
220
  assert(child.persisted?)
218
221
  refute(child.new_record?)
219
222
  end
220
223
  end
221
224
 
222
- it "can clone the model" do
225
+ it 'can clone the model' do
223
226
  clone_model = Cloner.new.clone(viewmodel)
224
227
 
225
228
  assert(clone_model.new_record?)
@@ -244,9 +247,10 @@ class ViewModel::ActiveRecord
244
247
  class IgnoreFirstChildCloner < Cloner
245
248
  def initialize
246
249
  @ignored_first = false
250
+ super
247
251
  end
248
252
 
249
- def visit_child_view(node, model)
253
+ def visit_child_view(_node, _model)
250
254
  unless @ignored_first
251
255
  @ignored_first = true
252
256
  ignore!
@@ -254,7 +258,7 @@ class ViewModel::ActiveRecord
254
258
  end
255
259
  end
256
260
 
257
- it "can ignore subset of children" do
261
+ it 'can ignore subset of children' do
258
262
  clone_model = IgnoreFirstChildCloner.new.clone(viewmodel)
259
263
 
260
264
  assert(clone_model.new_record?)
@@ -265,7 +269,7 @@ class ViewModel::ActiveRecord
265
269
  assert_equal(model.children[1].name, clone_model.children[0].name)
266
270
  end
267
271
 
268
- it "can ignore the children association" do
272
+ it 'can ignore the children association' do
269
273
  clone_model = IgnoreChildrenAssociationCloner.new.clone(viewmodel)
270
274
 
271
275
  assert(clone_model.new_record?)
@@ -276,19 +280,19 @@ class ViewModel::ActiveRecord
276
280
  end
277
281
  end
278
282
 
279
- describe "with has_many_through shared children" do
283
+ describe 'with has_many_through shared children' do
280
284
  include ViewModelSpecHelpers::ParentAndHasManyThroughChildren
281
285
  def new_model_children
282
- ["b", "c"].map.with_index do |n, i|
286
+ ['b', 'c'].map.with_index do |n, i|
283
287
  join_model_class.new(child: child_model_class.new(name: n), position: i)
284
288
  end
285
289
  end
286
290
 
287
291
  def new_model
288
- model_class.new( name: "a", model_children: new_model_children)
292
+ model_class.new(name: 'a', model_children: new_model_children)
289
293
  end
290
294
 
291
- it "persists the test setup" do
295
+ it 'persists the test setup' do
292
296
  assert(viewmodel.model.persisted?)
293
297
  refute(viewmodel.model.new_record?)
294
298
  assert_equal(2, viewmodel.model.model_children.size)
@@ -301,7 +305,7 @@ class ViewModel::ActiveRecord
301
305
  end
302
306
  end
303
307
 
304
- it "can clone the model and join model but not the child" do
308
+ it 'can clone the model and join model but not the child' do
305
309
  clone_model = Cloner.new.clone(viewmodel)
306
310
 
307
311
  assert(clone_model.new_record?)
@@ -325,7 +329,7 @@ class ViewModel::ActiveRecord
325
329
  end
326
330
  end
327
331
 
328
- it "can ignore the children association" do
332
+ it 'can ignore the children association' do
329
333
  clone_model = IgnoreChildrenAssociationCloner.new.clone(viewmodel)
330
334
 
331
335
  assert(clone_model.new_record?)
@@ -1,14 +1,14 @@
1
- # -*- coding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
- require "minitest/autorun"
3
+ require 'minitest/autorun'
4
4
  require 'minitest/unit'
5
5
  require 'minitest/hooks'
6
6
 
7
- require "view_model"
8
- require "view_model/active_record"
7
+ require 'view_model'
8
+ require 'view_model/active_record'
9
9
 
10
- require_relative "../../../helpers/controller_test_helpers.rb"
11
- require_relative "../../../helpers/callback_tracer.rb"
10
+ require_relative '../../../helpers/controller_test_helpers'
11
+ require_relative '../../../helpers/callback_tracer'
12
12
 
13
13
  class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
14
14
  include ARVMTestUtilities
@@ -88,7 +88,7 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
88
88
  super
89
89
  @parent = Parent.create(name: 'p',
90
90
  children: [Child.new(name: 'c1', position: 1.0),
91
- Child.new(name: 'c2', position: 2.0)],
91
+ Child.new(name: 'c2', position: 2.0),],
92
92
  label: Label.new,
93
93
  target: Target.new)
94
94
 
@@ -98,7 +98,7 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
98
98
  end
99
99
 
100
100
  def test_show
101
- parentcontroller = ParentController.new(id: @parent.id)
101
+ parentcontroller = ParentController.new(params: { id: @parent.id })
102
102
  parentcontroller.invoke(:show)
103
103
 
104
104
  assert_equal({ 'data' => @parent_view.to_hash },
@@ -109,8 +109,41 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
109
109
  assert_all_hooks_nested_inside_parent_hook(parentcontroller.hook_trace)
110
110
  end
111
111
 
112
+ def test_migrated_show
113
+ parentcontroller = ParentController.new(
114
+ params: { id: @parent.id },
115
+ headers: { 'X-ViewModel-Versions' => { ParentView.view_name => 1 }.to_json })
116
+
117
+ parentcontroller.invoke(:show)
118
+
119
+ expected_view = @parent_view.to_hash
120
+ .except('name')
121
+ .merge('old_name' => @parent.name,
122
+ ViewModel::VERSION_ATTRIBUTE => 1,
123
+ ViewModel::MIGRATED_ATTRIBUTE => true)
124
+
125
+ assert_equal({ 'data' => expected_view },
126
+ parentcontroller.hash_response)
127
+
128
+ assert_equal(200, parentcontroller.status)
129
+
130
+ assert_all_hooks_nested_inside_parent_hook(parentcontroller.hook_trace)
131
+ end
132
+
133
+ def test_invalid_migration_header
134
+ parentcontroller = ParentController.new(
135
+ params: { id: @parent.id },
136
+ headers: { 'X-ViewModel-Versions' => 'not a json' })
137
+
138
+ parentcontroller.invoke(:show)
139
+ assert_equal(400, parentcontroller.status)
140
+ assert_match(/Invalid JSON/i,
141
+ parentcontroller.hash_response['error']['detail'],
142
+ 'json error propagated')
143
+ end
144
+
112
145
  def test_index
113
- p2 = Parent.create(name: "p2")
146
+ p2 = Parent.create(name: 'p2')
114
147
  p2_view = ParentView.new(p2)
115
148
 
116
149
  parentcontroller = ParentController.new
@@ -119,7 +152,7 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
119
152
  assert_equal(200, parentcontroller.status)
120
153
 
121
154
  assert_equal(parentcontroller.hash_response,
122
- { "data" => [@parent_view.to_hash, p2_view.to_hash] })
155
+ { 'data' => [@parent_view.to_hash, p2_view.to_hash] })
123
156
 
124
157
  assert_all_hooks_nested_inside_parent_hook(parentcontroller.hook_trace)
125
158
  end
@@ -131,10 +164,10 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
131
164
  'label' => { '_type' => 'Label', 'text' => 'l' },
132
165
  'target' => { '_type' => 'Target', 'text' => 't' },
133
166
  'children' => [{ '_type' => 'Child', 'name' => 'c1' },
134
- { '_type' => 'Child', 'name' => 'c2' }]
167
+ { '_type' => 'Child', 'name' => 'c2' },],
135
168
  }
136
169
 
137
- parentcontroller = ParentController.new(data: data)
170
+ parentcontroller = ParentController.new(params: { data: data })
138
171
  parentcontroller.invoke(:create)
139
172
 
140
173
  assert_equal(200, parentcontroller.status)
@@ -148,15 +181,31 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
148
181
  assert_all_hooks_nested_inside_parent_hook(parentcontroller.hook_trace)
149
182
  end
150
183
 
184
+ def test_migrated_create
185
+ data = {
186
+ '_type' => 'Parent',
187
+ '_version' => 1,
188
+ 'old_name' => 'p2',
189
+ }
190
+
191
+ parentcontroller = ParentController.new(params: { data: data, versions: { ParentView.view_name => 1 } })
192
+ parentcontroller.invoke(:create)
193
+
194
+ assert_equal(200, parentcontroller.status)
195
+
196
+ p2 = Parent.where(name: 'p2').first
197
+ assert(p2.present?, 'p2 created')
198
+ end
199
+
151
200
  def test_create_empty
152
- parentcontroller = ParentController.new(data: [])
201
+ parentcontroller = ParentController.new(params: { data: [] })
153
202
  parentcontroller.invoke(:create)
154
203
 
155
204
  assert_equal(400, parentcontroller.status)
156
205
  end
157
206
 
158
207
  def test_create_invalid
159
- parentcontroller = ParentController.new(data: 42)
208
+ parentcontroller = ParentController.new(params: { data: 42 })
160
209
  parentcontroller.invoke(:create)
161
210
 
162
211
  assert_equal(400, parentcontroller.status)
@@ -167,7 +216,7 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
167
216
  '_type' => 'Parent',
168
217
  'name' => 'new' }
169
218
 
170
- parentcontroller = ParentController.new(id: @parent.id, data: data)
219
+ parentcontroller = ParentController.new(params: { id: @parent.id, data: data })
171
220
  parentcontroller.invoke(:create)
172
221
 
173
222
  assert_equal(200, parentcontroller.status)
@@ -182,7 +231,7 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
182
231
  end
183
232
 
184
233
  def test_destroy
185
- parentcontroller = ParentController.new(id: @parent.id)
234
+ parentcontroller = ParentController.new(params: { id: @parent.id })
186
235
  parentcontroller.invoke(:destroy)
187
236
 
188
237
  assert_equal(200, parentcontroller.status)
@@ -196,7 +245,7 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
196
245
  end
197
246
 
198
247
  def test_show_missing
199
- parentcontroller = ParentController.new(id: 9999)
248
+ parentcontroller = ParentController.new(params: { id: 9999 })
200
249
  parentcontroller.invoke(:show)
201
250
 
202
251
  assert_equal(404, parentcontroller.status)
@@ -206,10 +255,10 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
206
255
  'status' => 404,
207
256
  'detail' => "Couldn't find Parent(s) with id(s)=[9999]",
208
257
  'title' => nil,
209
- 'code' => "DeserializationError.NotFound",
210
- 'meta' => { 'nodes' => [{ '_type' => "Parent", 'id' => 9999 }]},
258
+ 'code' => 'DeserializationError.NotFound',
259
+ 'meta' => { 'nodes' => [{ '_type' => 'Parent', 'id' => 9999 }] },
211
260
  'exception' => nil,
212
- 'causes' => nil }},
261
+ 'causes' => nil } },
213
262
  parentcontroller.hash_response)
214
263
  end
215
264
 
@@ -218,7 +267,7 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
218
267
  'children' => [{ '_type' => 'Child',
219
268
  'age' => 42 }] }
220
269
 
221
- parentcontroller = ParentController.new(data: data)
270
+ parentcontroller = ParentController.new(params: { data: data })
222
271
  parentcontroller.invoke(:create)
223
272
 
224
273
  assert_equal({ 'error' => {
@@ -227,13 +276,13 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
227
276
  'status' => 400,
228
277
  'detail' => 'Validation failed: \'age\' must be less than 42',
229
278
  'title' => nil,
230
- 'code' => "DeserializationError.Validation",
231
- 'meta' => { 'nodes' => [{ '_type' => "Child", 'id' => nil }],
279
+ 'code' => 'DeserializationError.Validation',
280
+ 'meta' => { 'nodes' => [{ '_type' => 'Child', 'id' => nil }],
232
281
  'attribute' => 'age',
233
282
  'message' => 'must be less than 42',
234
- 'details' => { 'error' => 'less_than', 'value' => 42, 'count' => 42 }},
283
+ 'details' => { 'error' => 'less_than', 'value' => 42, 'count' => 42 } },
235
284
  'exception' => nil,
236
- 'causes' => nil }},
285
+ 'causes' => nil } },
237
286
  parentcontroller.hash_response)
238
287
  end
239
288
 
@@ -241,17 +290,17 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
241
290
  data = { '_type' => 'Parent',
242
291
  'children' => [{ '_type' => 'Child',
243
292
  'age' => 1 }] }
244
- parentcontroller = ParentController.new(data: data)
293
+ parentcontroller = ParentController.new(params: { data: data })
245
294
  parentcontroller.invoke(:create)
246
295
 
247
296
  assert_equal(400, parentcontroller.status)
248
- assert_match(%r{check constraint}i,
249
- parentcontroller.hash_response["error"]["detail"],
250
- "Database error propagated")
297
+ assert_match(/check constraint/i,
298
+ parentcontroller.hash_response['error']['detail'],
299
+ 'Database error propagated')
251
300
  end
252
301
 
253
302
  def test_destroy_missing
254
- parentcontroller = ParentController.new(id: 9999)
303
+ parentcontroller = ParentController.new(params: { id: 9999 })
255
304
  parentcontroller.invoke(:destroy)
256
305
 
257
306
  assert_equal({ 'error' => {
@@ -260,8 +309,8 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
260
309
  'status' => 404,
261
310
  'detail' => "Couldn't find Parent(s) with id(s)=[9999]",
262
311
  'title' => nil,
263
- 'code' => "DeserializationError.NotFound",
264
- 'meta' => { "nodes" => [{"_type" => "Parent", "id" => 9999 }] },
312
+ 'code' => 'DeserializationError.NotFound',
313
+ 'meta' => { 'nodes' => [{ '_type' => 'Parent', 'id' => 9999 }] },
265
314
  'exception' => nil,
266
315
  'causes' => nil } },
267
316
  parentcontroller.hash_response)
@@ -273,7 +322,7 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
273
322
  def test_nested_collection_index_associated
274
323
  _distractor = Parent.create(name: 'p2', children: [Child.new(name: 'c3', position: 1)])
275
324
 
276
- childcontroller = ChildController.new(parent_id: @parent.id)
325
+ childcontroller = ChildController.new(params: { parent_id: @parent.id })
277
326
  childcontroller.invoke(:index_associated)
278
327
 
279
328
  assert_equal(200, childcontroller.status)
@@ -300,7 +349,7 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
300
349
 
301
350
  def test_nested_collection_append_one
302
351
  data = { '_type' => 'Child', 'name' => 'c3' }
303
- childcontroller = ChildController.new(parent_id: @parent.id, data: data)
352
+ childcontroller = ChildController.new(params: { parent_id: @parent.id, data: data })
304
353
 
305
354
  childcontroller.invoke(:append)
306
355
 
@@ -308,7 +357,7 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
308
357
 
309
358
  @parent.reload
310
359
 
311
- assert_equal(%w{c1 c2 c3}, @parent.children.order(:position).pluck(:name))
360
+ assert_equal(%w[c1 c2 c3], @parent.children.order(:position).pluck(:name))
312
361
  assert_equal({ 'data' => ChildView.new(@parent.children.last).to_hash },
313
362
  childcontroller.hash_response)
314
363
 
@@ -317,17 +366,17 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
317
366
 
318
367
  def test_nested_collection_append_many
319
368
  data = [{ '_type' => 'Child', 'name' => 'c3' },
320
- { '_type' => 'Child', 'name' => 'c4' }]
369
+ { '_type' => 'Child', 'name' => 'c4' },]
321
370
 
322
- childcontroller = ChildController.new(parent_id: @parent.id, data: data)
371
+ childcontroller = ChildController.new(params: { parent_id: @parent.id, data: data })
323
372
  childcontroller.invoke(:append)
324
373
 
325
374
  assert_equal(200, childcontroller.status, childcontroller.hash_response)
326
375
 
327
376
  @parent.reload
328
377
 
329
- assert_equal(%w{c1 c2 c3 c4}, @parent.children.order(:position).pluck(:name))
330
- new_children_hashes = @parent.children.last(2).map{ |c| ChildView.new(c).to_hash }
378
+ assert_equal(%w[c1 c2 c3 c4], @parent.children.order(:position).pluck(:name))
379
+ new_children_hashes = @parent.children.last(2).map { |c| ChildView.new(c).to_hash }
331
380
  assert_equal({ 'data' => new_children_hashes },
332
381
  childcontroller.hash_response)
333
382
 
@@ -339,25 +388,25 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
339
388
  # Parent.children
340
389
  old_children = @parent.children
341
390
 
342
- data = [{'_type' => 'Child', 'name' => 'newc1'},
343
- {'_type' => 'Child', 'name' => 'newc2'}]
391
+ data = [{ '_type' => 'Child', 'name' => 'newc1' },
392
+ { '_type' => 'Child', 'name' => 'newc2' },]
344
393
 
345
- childcontroller = ChildController.new(parent_id: @parent.id, data: data)
394
+ childcontroller = ChildController.new(params: { parent_id: @parent.id, data: data })
346
395
  childcontroller.invoke(:replace)
347
396
 
348
397
  assert_equal(200, childcontroller.status, childcontroller.hash_response)
349
398
 
350
399
  @parent.reload
351
400
 
352
- assert_equal(%w{newc1 newc2}, @parent.children.order(:position).pluck(:name))
401
+ assert_equal(%w[newc1 newc2], @parent.children.order(:position).pluck(:name))
353
402
  assert_predicate(Child.where(id: old_children.map(&:id)), :empty?)
354
403
 
355
404
  assert_all_hooks_nested_inside_parent_hook(childcontroller.hook_trace)
356
405
  end
357
406
 
358
407
  def test_nested_collection_replace_bad_data
359
- data = [{ "name" => "nc" }]
360
- childcontroller = ChildController.new(parent_id: @parent.id, data: data)
408
+ data = [{ 'name' => 'nc' }]
409
+ childcontroller = ChildController.new(params: { parent_id: @parent.id, data: data })
361
410
 
362
411
  childcontroller.invoke(:replace)
363
412
 
@@ -368,14 +417,14 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
368
417
 
369
418
  def test_nested_collection_disassociate_one
370
419
  old_child = @parent.children.first
371
- childcontroller = ChildController.new(parent_id: @parent.id, id: old_child.id)
420
+ childcontroller = ChildController.new(params: { parent_id: @parent.id, id: old_child.id })
372
421
  childcontroller.invoke(:disassociate)
373
422
 
374
423
  assert_equal(200, childcontroller.status, childcontroller.hash_response)
375
424
 
376
425
  @parent.reload
377
426
 
378
- assert_equal(%w{c2}, @parent.children.order(:position).pluck(:name))
427
+ assert_equal(%w[c2], @parent.children.order(:position).pluck(:name))
379
428
  assert_predicate(Child.where(id: old_child.id), :empty?)
380
429
 
381
430
  assert_all_hooks_nested_inside_parent_hook(childcontroller.hook_trace)
@@ -384,7 +433,7 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
384
433
  def test_nested_collection_disassociate_many
385
434
  old_children = @parent.children
386
435
 
387
- childcontroller = ChildController.new(parent_id: @parent.id)
436
+ childcontroller = ChildController.new(params: { parent_id: @parent.id })
388
437
  childcontroller.invoke(:disassociate_all)
389
438
 
390
439
  assert_equal(200, childcontroller.status, childcontroller.hash_response)
@@ -400,14 +449,14 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
400
449
  # direct methods on nested controller
401
450
  def test_nested_collection_destroy
402
451
  old_child = @parent.children.first
403
- childcontroller = ChildController.new(id: old_child.id)
452
+ childcontroller = ChildController.new(params: { id: old_child.id })
404
453
  childcontroller.invoke(:destroy)
405
454
 
406
455
  assert_equal(200, childcontroller.status, childcontroller.hash_response)
407
456
 
408
457
  @parent.reload
409
458
 
410
- assert_equal(%w{c2}, @parent.children.order(:position).pluck(:name))
459
+ assert_equal(%w[c2], @parent.children.order(:position).pluck(:name))
411
460
  assert_predicate(Child.where(id: old_child.id), :empty?)
412
461
  end
413
462
 
@@ -418,7 +467,7 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
418
467
  '_type' => 'Child',
419
468
  'name' => 'new_name' }
420
469
 
421
- childcontroller = ChildController.new(data: data)
470
+ childcontroller = ChildController.new(params: { data: data })
422
471
  childcontroller.invoke(:create)
423
472
 
424
473
  assert_equal(200, childcontroller.status, childcontroller.hash_response)
@@ -430,26 +479,25 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
430
479
  childcontroller.hash_response)
431
480
  end
432
481
 
433
- def test_nested_collection_show
482
+ def test_nested_collection_show
434
483
  old_child = @parent.children.first
435
484
 
436
- childcontroller = ChildController.new(id: old_child.id)
485
+ childcontroller = ChildController.new(params: { id: old_child.id })
437
486
  childcontroller.invoke(:show)
438
487
 
439
488
  assert_equal({ 'data' => ChildView.new(old_child).to_hash },
440
489
  childcontroller.hash_response)
441
490
 
442
491
  assert_equal(200, childcontroller.status)
443
- end
444
-
492
+ end
445
493
 
446
494
  ## Single association
447
495
 
448
496
  def test_nested_singular_replace_from_parent
449
497
  old_label = @parent.label
450
498
 
451
- data = {'_type' => 'Label', 'text' => 'new label'}
452
- labelcontroller = LabelController.new(parent_id: @parent.id, data: data)
499
+ data = { '_type' => 'Label', 'text' => 'new label' }
500
+ labelcontroller = LabelController.new(params: { parent_id: @parent.id, data: data })
453
501
  labelcontroller.invoke(:create_associated)
454
502
 
455
503
  assert_equal(200, labelcontroller.status, labelcontroller.hash_response)
@@ -471,7 +519,7 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
471
519
  def test_nested_singular_show_from_parent
472
520
  old_label = @parent.label
473
521
 
474
- labelcontroller = LabelController.new(parent_id: @parent.id)
522
+ labelcontroller = LabelController.new(params: { parent_id: @parent.id })
475
523
  labelcontroller.invoke(:show_associated)
476
524
 
477
525
  assert_equal(200, labelcontroller.status, labelcontroller.hash_response)
@@ -485,7 +533,7 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
485
533
  def test_nested_singular_destroy_from_parent
486
534
  old_label = @parent.label
487
535
 
488
- labelcontroller = LabelController.new(parent_id: @parent.id)
536
+ labelcontroller = LabelController.new(params: { parent_id: @parent.id })
489
537
  labelcontroller.invoke(:destroy_associated)
490
538
 
491
539
  @parent.reload
@@ -502,8 +550,8 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
502
550
  def test_nested_singular_update_from_parent
503
551
  old_label = @parent.label
504
552
 
505
- data = {'_type' => 'Label', 'id' => old_label.id, 'text' => 'new label'}
506
- labelcontroller = LabelController.new(parent_id: @parent.id, data: data)
553
+ data = { '_type' => 'Label', 'id' => old_label.id, 'text' => 'new label' }
554
+ labelcontroller = LabelController.new(params: { parent_id: @parent.id, data: data })
507
555
  labelcontroller.invoke(:create_associated)
508
556
 
509
557
  assert_equal(200, labelcontroller.status, labelcontroller.hash_response)
@@ -520,7 +568,7 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
520
568
  def test_nested_singular_show_from_id
521
569
  old_label = @parent.label
522
570
 
523
- labelcontroller = LabelController.new(id: old_label.id)
571
+ labelcontroller = LabelController.new(params: { id: old_label.id })
524
572
  labelcontroller.invoke(:show)
525
573
 
526
574
  assert_equal(200, labelcontroller.status, labelcontroller.hash_response)
@@ -534,7 +582,7 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
534
582
  # foreign key violation. Destroy target instead.
535
583
  old_target = @parent.target
536
584
 
537
- targetcontroller = TargetController.new(id: old_target.id)
585
+ targetcontroller = TargetController.new(params: { id: old_target.id })
538
586
  targetcontroller.invoke(:destroy)
539
587
 
540
588
  @parent.reload
@@ -549,8 +597,8 @@ class ViewModel::ActiveRecord::ControllerTest < ActiveSupport::TestCase
549
597
  def test_nested_singular_update
550
598
  old_label = @parent.label
551
599
 
552
- data = {'_type' => 'Label', 'id' => old_label.id, 'text' => 'new label'}
553
- labelcontroller = LabelController.new(data: data)
600
+ data = { '_type' => 'Label', 'id' => old_label.id, 'text' => 'new label' }
601
+ labelcontroller = LabelController.new(params: { data: data })
554
602
  labelcontroller.invoke(:create)
555
603
 
556
604
  assert_equal(200, labelcontroller.status, labelcontroller.hash_response)