iknow_view_models 3.1.6 → 3.2.2

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.
Files changed (91) 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 +13 -12
  20. data/lib/view_model/active_record/association_data.rb +3 -2
  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 +2 -2
  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 +1 -1
  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 +92 -97
  86. data/test/unit/view_model/traversal_context_test.rb +4 -5
  87. data/test/unit/view_model_test.rb +18 -16
  88. metadata +36 -12
  89. data/.travis.yml +0 -31
  90. data/appveyor.yml +0 -22
  91. 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)