cuprum-rails 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +145 -0
  3. data/DEVELOPMENT.md +20 -0
  4. data/README.md +356 -63
  5. data/lib/cuprum/rails/action.rb +32 -16
  6. data/lib/cuprum/rails/actions/create.rb +62 -15
  7. data/lib/cuprum/rails/actions/destroy.rb +23 -7
  8. data/lib/cuprum/rails/actions/edit.rb +23 -7
  9. data/lib/cuprum/rails/actions/index.rb +30 -10
  10. data/lib/cuprum/rails/actions/middleware/associations/cache.rb +112 -0
  11. data/lib/cuprum/rails/actions/middleware/associations/find.rb +23 -0
  12. data/lib/cuprum/rails/actions/middleware/associations/parent.rb +70 -0
  13. data/lib/cuprum/rails/actions/middleware/associations/query.rb +140 -0
  14. data/lib/cuprum/rails/actions/middleware/associations.rb +12 -0
  15. data/lib/cuprum/rails/actions/middleware/log_request.rb +126 -0
  16. data/lib/cuprum/rails/actions/middleware/log_result.rb +51 -0
  17. data/lib/cuprum/rails/actions/middleware/resources/find.rb +44 -0
  18. data/lib/cuprum/rails/actions/middleware/resources/query.rb +91 -0
  19. data/lib/cuprum/rails/actions/middleware/resources.rb +11 -0
  20. data/lib/cuprum/rails/actions/middleware.rb +13 -0
  21. data/lib/cuprum/rails/actions/new.rb +16 -4
  22. data/lib/cuprum/rails/actions/parameter_validation.rb +60 -0
  23. data/lib/cuprum/rails/actions/resource_action.rb +119 -42
  24. data/lib/cuprum/rails/actions/show.rb +23 -7
  25. data/lib/cuprum/rails/actions/update.rb +70 -22
  26. data/lib/cuprum/rails/actions.rb +11 -7
  27. data/lib/cuprum/rails/collection.rb +27 -47
  28. data/lib/cuprum/rails/command.rb +3 -1
  29. data/lib/cuprum/rails/commands/destroy_one.rb +10 -6
  30. data/lib/cuprum/rails/commands/find_many.rb +8 -1
  31. data/lib/cuprum/rails/commands/find_matching.rb +1 -1
  32. data/lib/cuprum/rails/commands/find_one.rb +8 -0
  33. data/lib/cuprum/rails/commands/insert_one.rb +17 -6
  34. data/lib/cuprum/rails/commands/update_one.rb +16 -5
  35. data/lib/cuprum/rails/constraints/parameters_contract.rb +14 -0
  36. data/lib/cuprum/rails/constraints.rb +10 -0
  37. data/lib/cuprum/rails/controller.rb +12 -2
  38. data/lib/cuprum/rails/controllers/action.rb +100 -0
  39. data/lib/cuprum/rails/controllers/class_methods/actions.rb +33 -7
  40. data/lib/cuprum/rails/controllers/class_methods/configuration.rb +36 -0
  41. data/lib/cuprum/rails/controllers/class_methods/middleware.rb +88 -0
  42. data/lib/cuprum/rails/controllers/class_methods/validations.rb +2 -2
  43. data/lib/cuprum/rails/controllers/configuration.rb +41 -1
  44. data/lib/cuprum/rails/controllers/middleware.rb +59 -0
  45. data/lib/cuprum/rails/controllers.rb +2 -0
  46. data/lib/cuprum/rails/errors/invalid_parameters.rb +55 -0
  47. data/lib/cuprum/rails/errors/invalid_statement.rb +11 -0
  48. data/lib/cuprum/rails/errors/missing_parameter.rb +42 -0
  49. data/lib/cuprum/rails/errors/resource_error.rb +46 -0
  50. data/lib/cuprum/rails/errors.rb +6 -1
  51. data/lib/cuprum/rails/map_errors.rb +29 -1
  52. data/lib/cuprum/rails/query.rb +1 -1
  53. data/lib/cuprum/rails/repository.rb +12 -25
  54. data/lib/cuprum/rails/request.rb +149 -60
  55. data/lib/cuprum/rails/resource.rb +119 -85
  56. data/lib/cuprum/rails/responders/base_responder.rb +78 -0
  57. data/lib/cuprum/rails/responders/html/plural_resource.rb +9 -39
  58. data/lib/cuprum/rails/responders/html/rendering.rb +81 -0
  59. data/lib/cuprum/rails/responders/html/resource.rb +107 -0
  60. data/lib/cuprum/rails/responders/html/singular_resource.rb +9 -38
  61. data/lib/cuprum/rails/responders/html.rb +2 -0
  62. data/lib/cuprum/rails/responders/html_responder.rb +8 -52
  63. data/lib/cuprum/rails/responders/json/resource.rb +3 -3
  64. data/lib/cuprum/rails/responders/json_responder.rb +31 -16
  65. data/lib/cuprum/rails/responders/matching.rb +29 -27
  66. data/lib/cuprum/rails/responders/serialization.rb +11 -9
  67. data/lib/cuprum/rails/responders.rb +1 -0
  68. data/lib/cuprum/rails/responses/head_response.rb +24 -0
  69. data/lib/cuprum/rails/responses/html/redirect_back_response.rb +55 -0
  70. data/lib/cuprum/rails/responses/html/redirect_response.rb +19 -4
  71. data/lib/cuprum/rails/responses/html/render_response.rb +17 -5
  72. data/lib/cuprum/rails/responses/html.rb +6 -2
  73. data/lib/cuprum/rails/responses.rb +1 -0
  74. data/lib/cuprum/rails/result.rb +36 -0
  75. data/lib/cuprum/rails/routes.rb +36 -23
  76. data/lib/cuprum/rails/rspec/contract_helpers.rb +57 -0
  77. data/lib/cuprum/rails/rspec/contracts/action_contracts.rb +754 -0
  78. data/lib/cuprum/rails/rspec/contracts/actions/create_contracts.rb +289 -0
  79. data/lib/cuprum/rails/rspec/contracts/actions/destroy_contracts.rb +164 -0
  80. data/lib/cuprum/rails/rspec/contracts/actions/edit_contracts.rb +73 -0
  81. data/lib/cuprum/rails/rspec/contracts/actions/index_contracts.rb +108 -0
  82. data/lib/cuprum/rails/rspec/contracts/actions/new_contracts.rb +111 -0
  83. data/lib/cuprum/rails/rspec/contracts/actions/show_contracts.rb +72 -0
  84. data/lib/cuprum/rails/rspec/contracts/actions/update_contracts.rb +263 -0
  85. data/lib/cuprum/rails/rspec/contracts/actions.rb +8 -0
  86. data/lib/cuprum/rails/rspec/contracts/command_contracts.rb +479 -0
  87. data/lib/cuprum/rails/rspec/contracts/responder_contracts.rb +232 -0
  88. data/lib/cuprum/rails/rspec/contracts/routes_contracts.rb +363 -0
  89. data/lib/cuprum/rails/rspec/contracts/serializers_contracts.rb +70 -0
  90. data/lib/cuprum/rails/rspec/contracts.rb +8 -0
  91. data/lib/cuprum/rails/rspec/matchers/be_a_result_matcher.rb +64 -0
  92. data/lib/cuprum/rails/rspec/matchers.rb +41 -0
  93. data/lib/cuprum/rails/serializers/base_serializer.rb +60 -0
  94. data/lib/cuprum/rails/serializers/context.rb +84 -0
  95. data/lib/cuprum/rails/serializers/json/active_record_serializer.rb +2 -2
  96. data/lib/cuprum/rails/serializers/json/array_serializer.rb +9 -8
  97. data/lib/cuprum/rails/serializers/json/attributes_serializer.rb +95 -172
  98. data/lib/cuprum/rails/serializers/json/error_serializer.rb +2 -2
  99. data/lib/cuprum/rails/serializers/json/hash_serializer.rb +9 -8
  100. data/lib/cuprum/rails/serializers/json/identity_serializer.rb +3 -3
  101. data/lib/cuprum/rails/serializers/json/properties_serializer.rb +252 -0
  102. data/lib/cuprum/rails/serializers/json.rb +2 -1
  103. data/lib/cuprum/rails/serializers.rb +3 -1
  104. data/lib/cuprum/rails/version.rb +1 -1
  105. data/lib/cuprum/rails.rb +19 -16
  106. metadata +73 -131
  107. data/lib/cuprum/rails/controller_action.rb +0 -121
  108. data/lib/cuprum/rails/errors/missing_parameters.rb +0 -33
  109. data/lib/cuprum/rails/errors/missing_primary_key.rb +0 -46
  110. data/lib/cuprum/rails/errors/undefined_permitted_attributes.rb +0 -34
  111. data/lib/cuprum/rails/rspec/command_contract.rb +0 -460
  112. data/lib/cuprum/rails/rspec/define_route_contract.rb +0 -84
  113. data/lib/cuprum/rails/serializers/json/serializer.rb +0 -66
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rspec/sleeping_king_studios/contract'
4
+
5
+ require 'cuprum/rails/rspec/contract_helpers'
6
+ require 'cuprum/rails/rspec/contracts/action_contracts'
7
+ require 'cuprum/rails/rspec/contracts/actions'
8
+
9
+ module Cuprum::Rails::RSpec::Contracts::Actions
10
+ # Namespace for RSpec new contracts, which validate new implementations.
11
+ module NewContracts
12
+ # Contract asserting the action implements the new action interface.
13
+ module ShouldBeANewActionContract
14
+ extend RSpec::SleepingKingStudios::Contract
15
+
16
+ # @method apply(example_group, **options, &block)
17
+ # Adds the contract to the example group.
18
+ #
19
+ # @param example_group [RSpec::Core::ExampleGroup] The example group to
20
+ # which the contract is applied.
21
+ #
22
+ # @option options [Hash<String>] expected_attributes_on_success The
23
+ # expected attributes for the returned object. Defaults to the value
24
+ # of valid_attributes.
25
+ # @option options [Hash<String>] expected_value_on_success The expected
26
+ # value for the passing result. Defaults to a Hash with the created
27
+ # entity.
28
+ # @option options [#to_proc] examples_on_success Extra examples to run
29
+ # for the passing case.
30
+ #
31
+ # @yield Additional examples to run for the passing case.
32
+ contract do |**options, &block|
33
+ include Cuprum::Rails::RSpec::Contracts::ActionContracts
34
+ include Cuprum::Rails::RSpec::Contracts::Actions::NewContracts
35
+
36
+ # :nocov:
37
+ if options[:examples_on_success] && block
38
+ raise ArgumentError, 'provide either :examples_on_success or a block'
39
+ elsif block
40
+ options[:examples_on_success] = block
41
+ end
42
+ # :nocov:
43
+
44
+ include_contract 'should be a resource action'
45
+
46
+ include_contract(
47
+ 'should build the entity',
48
+ expected_attributes: options[:expected_attributes_on_success],
49
+ expected_value: options[:expected_value_on_success],
50
+ &options[:examples_on_success]
51
+ )
52
+ end
53
+ end
54
+
55
+ # Contract asserting the action builds a new entity.
56
+ module ShouldBuildTheEntityContract
57
+ extend RSpec::SleepingKingStudios::Contract
58
+
59
+ # @!method apply(example_group, **options)
60
+ # Adds the contract to the example group.
61
+ #
62
+ # @param example_group [RSpec::Core::ExampleGroup] The example group to
63
+ # which the contract is applied.
64
+ #
65
+ # @option options [Hash<String>] expected_attributes The expected
66
+ # attributes for the returned object.
67
+ # @option options [Hash<String>] expected_value The expected value for
68
+ # the passing result. Defaults to a Hash with the built entity.
69
+ # @option options [Hash<String>] params The parameters used to build the
70
+ # request. Defaults to the id of the entity and the given attributes.
71
+ #
72
+ # @yield Additional examples.
73
+ contract do |**options, &block|
74
+ describe '#call' do
75
+ include Cuprum::Rails::RSpec::ContractHelpers
76
+
77
+ let(:request) do
78
+ Cuprum::Rails::Request.new(params: configured_params)
79
+ end
80
+ let(:configured_params) do
81
+ option_with_default(options[:params], default: {})
82
+ end
83
+ let(:configured_expected_attributes) do
84
+ option_with_default(options[:expected_attributes], default: {})
85
+ end
86
+ let(:configured_expected_entity) do
87
+ configured_resource
88
+ .entity_class
89
+ .new(configured_expected_attributes)
90
+ end
91
+ let(:configured_expected_value) do
92
+ resource_name = configured_resource.singular_name
93
+
94
+ option_with_default(
95
+ options[:expected_value],
96
+ default: { resource_name => configured_expected_entity }
97
+ )
98
+ end
99
+
100
+ it 'should return a passing result' do
101
+ expect(call_action)
102
+ .to be_a_passing_result
103
+ .with_value(configured_expected_value)
104
+ end
105
+
106
+ instance_exec(&block) if block
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rspec/sleeping_king_studios/contract'
4
+
5
+ require 'cuprum/rails/rspec/contract_helpers'
6
+ require 'cuprum/rails/rspec/contracts/action_contracts'
7
+ require 'cuprum/rails/rspec/contracts/actions'
8
+
9
+ module Cuprum::Rails::RSpec::Contracts::Actions
10
+ # Namespace for RSpec show contracts, which validate show implementations.
11
+ module ShowContracts
12
+ # Contract asserting the action implements the show action interface.
13
+ module ShouldBeAShowActionContract
14
+ extend RSpec::SleepingKingStudios::Contract
15
+
16
+ # @method apply(example_group, existing_entity:, **options)
17
+ # Adds the contract to the example group.
18
+ #
19
+ # @param example_group [RSpec::Core::ExampleGroup] The example group to
20
+ # which the contract is applied.
21
+ # @param existing_entity [Object] The existing entity to find.
22
+ #
23
+ # @option options [#to_proc] examples_on_failure Extra examples to run
24
+ # for the failing cases.
25
+ # @option options [#to_proc] examples_on_success Extra examples to run
26
+ # for the passing case.
27
+ # @option options [Hash<String>] expected_value_on_success The expected
28
+ # value for the passing result. Defaults to a Hash with the found
29
+ # entity.
30
+ # @option options [Hash<String>] params The parameters used to build the
31
+ # request. Defaults to the id of the entity.
32
+ # @option options [Object] primary_key_value The value of the primary
33
+ # key for the missing entity.
34
+ #
35
+ # @yield Additional examples to run for the passing case.
36
+
37
+ contract do |existing_entity:, **options, &block|
38
+ include Cuprum::Rails::RSpec::Contracts::ActionContracts
39
+
40
+ # :nocov:
41
+ if options[:examples_on_success] && block
42
+ raise ArgumentError, 'provide either :examples_on_success or a block'
43
+ elsif block
44
+ options[:examples_on_success] = block
45
+ end
46
+ # :nocov:
47
+
48
+ include_contract 'should be a resource action'
49
+
50
+ include_contract(
51
+ 'should require primary key',
52
+ &options[:examples_on_failure]
53
+ )
54
+
55
+ include_contract(
56
+ 'should require existing entity',
57
+ params: options[:params],
58
+ primary_key_value: options[:primary_key_value],
59
+ &options[:examples_on_failure]
60
+ )
61
+
62
+ include_contract(
63
+ 'should find the entity',
64
+ existing_entity: existing_entity,
65
+ expected_value: options[:expected_value_on_success],
66
+ params: options[:params],
67
+ &options[:examples_on_success]
68
+ )
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,263 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rspec/sleeping_king_studios/contract'
4
+
5
+ require 'cuprum/rails/rspec/contract_helpers'
6
+ require 'cuprum/rails/rspec/contracts/action_contracts'
7
+ require 'cuprum/rails/rspec/contracts/actions'
8
+
9
+ module Cuprum::Rails::RSpec::Contracts::Actions
10
+ # Namespace for RSpec update contracts, which validate update implementations.
11
+ module UpdateContracts
12
+ # @private
13
+ def self.parameters(context:, resource:, **options) # rubocop:disable Metrics/MethodLength
14
+ attributes =
15
+ Cuprum::Rails::RSpec::ContractHelpers.option_with_default(
16
+ options[:valid_attributes],
17
+ context: context
18
+ )
19
+ entity =
20
+ Cuprum::Rails::RSpec::ContractHelpers.option_with_default(
21
+ options[:existing_entity],
22
+ context: context
23
+ )
24
+ resource_name = resource.singular_name
25
+
26
+ Cuprum::Rails::RSpec::ContractHelpers.option_with_default(
27
+ options[:params],
28
+ context: context,
29
+ default: {
30
+ 'id' => entity[resource.primary_key],
31
+ resource_name => attributes
32
+ }
33
+ )
34
+ end
35
+
36
+ # Contract asserting the action implements the show action interface.
37
+ module ShouldBeAnUpdateActionContract
38
+ extend RSpec::SleepingKingStudios::Contract
39
+
40
+ # @method apply(example_group, existing_entity:, invalid_attributes:, valid_attributes:, **options)
41
+ # Adds the contract to the example group.
42
+ #
43
+ # @param example_group [RSpec::Core::ExampleGroup] The example group to
44
+ # which the contract is applied.
45
+ # @param existing_entity [Object] The existing entity to update.
46
+ # @param invalid_attributes [Hash<String>] A set of attributes that will
47
+ # fail validation.
48
+ # @param valid_attributes [Hash<String>] A set of attributes that will
49
+ # pass validation.
50
+ #
51
+ # @option options [#to_proc] examples_on_failure Extra examples to run
52
+ # for the failing cases.
53
+ # @option options [#to_proc] examples_on_success Extra examples to run
54
+ # for the passing case.
55
+ # @option options [Hash<String>] expected_value_on_success The expected
56
+ # value for the passing result. Defaults to a Hash with the updated
57
+ # entity.
58
+ # @option options [Hash<String>] expected_attributes The expected
59
+ # attributes for both a failed validation and a returned entity.
60
+ # @option options [Hash<String>] expected_attributes_on_failure The
61
+ # expected attributes for a failed validation. Defaults to the value
62
+ # of invalid_attributes.
63
+ # @option options [Hash<String>] expected_attributes_on_success The
64
+ # expected attributes for the returned object. Defaults to the value
65
+ # of valid_attributes.
66
+ # @option options [Hash<String>] expected_value_on_success The expected
67
+ # value for the passing result. Defaults to a Hash with the updated
68
+ # entity.
69
+ # @option options [Hash<String>] params The parameters used to build the
70
+ # request. Defaults to the id of the entity and the given attributes.
71
+ # @option options [Object] primary_key_value The value of the primary
72
+ # key for the missing entity.
73
+ #
74
+ # @yield Additional examples to run for the passing case.
75
+
76
+ contract do |existing_entity:, invalid_attributes:, valid_attributes:, **options, &block| # rubocop:disable Layout/LineLength
77
+ include Cuprum::Rails::RSpec::Contracts::ActionContracts
78
+ include Cuprum::Rails::RSpec::Contracts::Actions::UpdateContracts
79
+
80
+ # :nocov:
81
+ if options[:examples_on_success] && block
82
+ raise ArgumentError, 'provide either :examples_on_success or a block'
83
+ elsif block
84
+ options[:examples_on_success] = block
85
+ end
86
+ # :nocov:
87
+
88
+ configured_params = lambda do
89
+ Cuprum::Rails::RSpec::Contracts::Actions::UpdateContracts.parameters(
90
+ context: self,
91
+ existing_entity: existing_entity,
92
+ resource: configured_resource,
93
+ valid_attributes: valid_attributes,
94
+ **options
95
+ )
96
+ end
97
+
98
+ should_not_update_the_entity = lambda do
99
+ it 'should not update the entity' do
100
+ entity = existing_entity
101
+ entity = instance_exec(&entity) if entity.is_a?(Proc)
102
+
103
+ expect { call_action }
104
+ .not_to(change { entity.reload.attributes })
105
+ end
106
+
107
+ # :nocov:
108
+ if options[:examples_on_failure]
109
+ instance_exec(&options[:examples_on_failure])
110
+ end
111
+ # :nocov:
112
+ end
113
+
114
+ include_contract 'should be a resource action',
115
+ require_permitted_attributes: true
116
+
117
+ include_contract(
118
+ 'should require primary key',
119
+ params: configured_params,
120
+ &should_not_update_the_entity
121
+ )
122
+
123
+ include_contract(
124
+ 'should require parameters',
125
+ params: configured_params,
126
+ &should_not_update_the_entity
127
+ )
128
+
129
+ include_contract(
130
+ 'should require existing entity',
131
+ params: configured_params,
132
+ primary_key_value: options[:primary_key_value],
133
+ &should_not_update_the_entity
134
+ )
135
+
136
+ include_contract(
137
+ 'should validate attributes',
138
+ existing_entity: existing_entity,
139
+ expected_attributes: options.fetch(
140
+ :expected_attributes,
141
+ options[:expected_attributes_on_failure]
142
+ ),
143
+ invalid_attributes: invalid_attributes,
144
+ params: configured_params,
145
+ &should_not_update_the_entity
146
+ )
147
+
148
+ include_contract(
149
+ 'should update the entity',
150
+ existing_entity: existing_entity,
151
+ expected_attributes: options.fetch(
152
+ :expected_attributes,
153
+ options[:expected_attributes_on_success]
154
+ ),
155
+ expected_value: options[:expected_value_on_success],
156
+ valid_attributes: valid_attributes,
157
+ params: configured_params,
158
+ &options[:examples_on_success]
159
+ )
160
+ end
161
+ end
162
+
163
+ # Contract asserting the action updates the entity.
164
+ module ShouldUpdateTheEntityContract
165
+ extend RSpec::SleepingKingStudios::Contract
166
+
167
+ # @!method apply(example_group, existing_entity:, valid_attributes:, **options)
168
+ # Adds the contract to the example group.
169
+ #
170
+ # @param example_group [RSpec::Core::ExampleGroup] The example group to
171
+ # which the contract is applied.
172
+ # @param existing_entity [Object] The existing entity to find.
173
+ # @param valid_attributes [Hash<String>] A set of attributes that will
174
+ # pass validation.
175
+ #
176
+ # @option options [Hash<String>] expected_attributes The expected
177
+ # attributes for the returned object. Defaults to the value of
178
+ # valid_attributes.
179
+ # @option options [Hash<String>] expected_value The expected value for
180
+ # the passing result. Defaults to a Hash with the created entity.
181
+ # @option options [Hash<String>] params The parameters used to build the
182
+ # request. Defaults to the id of the entity and the given attributes.
183
+ #
184
+ # @yield Additional examples.
185
+ contract do |existing_entity:, valid_attributes:, **options, &block|
186
+ describe '#call' do
187
+ include Cuprum::Rails::RSpec::ContractHelpers
188
+
189
+ context 'with valid parameters' do
190
+ let(:request) do
191
+ Cuprum::Rails::Request.new(params: configured_params)
192
+ end
193
+ let(:configured_params) do
194
+ Cuprum::Rails::RSpec::Contracts::Actions::UpdateContracts
195
+ .parameters(
196
+ context: self,
197
+ existing_entity: existing_entity,
198
+ resource: configured_resource,
199
+ valid_attributes: valid_attributes,
200
+ **options
201
+ )
202
+ end
203
+ let(:configured_existing_entity) do
204
+ option_with_default(existing_entity)
205
+ end
206
+ let(:configured_valid_attributes) do
207
+ option_with_default(valid_attributes)
208
+ end
209
+ let(:configured_expected_attributes) do
210
+ existing_attributes =
211
+ configured_existing_entity
212
+ .attributes
213
+ .tap { |hsh| hsh.delete('updated_at') }
214
+
215
+ option_with_default(
216
+ options[:expected_attributes],
217
+ default: existing_attributes.merge(configured_valid_attributes)
218
+ )
219
+ end
220
+ let(:configured_expected_entity) do
221
+ configured_resource
222
+ .entity_class
223
+ .find(
224
+ configured_existing_entity[configured_resource.primary_key]
225
+ )
226
+ end
227
+ let(:configured_expected_value) do
228
+ resource_name = configured_resource.singular_name
229
+
230
+ option_with_default(
231
+ options[:expected_value],
232
+ default: {
233
+ resource_name => configured_expected_entity
234
+ }
235
+ )
236
+ end
237
+
238
+ it 'should return a passing result' do
239
+ expect(call_action)
240
+ .to be_a_passing_result
241
+ .with_value(configured_expected_value)
242
+ end
243
+
244
+ it 'should update the entity' do
245
+ expect { call_action }
246
+ .to(
247
+ change do
248
+ configured_existing_entity
249
+ .reload
250
+ .attributes
251
+ .tap { |hsh| hsh.delete('updated_at') }
252
+ end
253
+ .to(be >= configured_expected_attributes)
254
+ )
255
+ end
256
+
257
+ instance_exec(&block) if block
258
+ end
259
+ end
260
+ end
261
+ end
262
+ end
263
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cuprum/rails/rspec/contracts'
4
+
5
+ module Cuprum::Rails::RSpec::Contracts
6
+ # Namespace for RSpec action contracts, which validate action implementations.
7
+ module Actions; end
8
+ end