rails_ops 1.4.3 → 1.4.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dcb574a4ebd4148a9db8bc6ae9e129b015140175352dccb01b0f9eb6e53a4afd
4
- data.tar.gz: 31322cd290160be87eee75fe5ca3604d7611344f4b77faff2681364a34b166f5
3
+ metadata.gz: 9c18eddf15b9f713101e8cd2e783c01bffb0c664ea1e76b497c6a4ae0ff07eae
4
+ data.tar.gz: 4f4d8e61f2d3de18e6215417016de13251625c2fa238b78a37bf52c629cb2ede
5
5
  SHA512:
6
- metadata.gz: 81e0839e7d210cc6011868a3ea69bf5dd2714aabe96137ee6109468a00ff69400ccfe6fcc5a52a93c772dad15e3638bd0944ffc073f18f010ebd33f648cae1b1
7
- data.tar.gz: 1bbc3608339025bd703a5a74a192056f462a5fb756f76531f570cedf754b0d5009d2e69319afc940a1dfc57e38a67fbf1a4fae8f62fb702fc35cb378adcc7825
6
+ metadata.gz: 88f1d0f750f1bd794962984fa2d4e8fb37c71456e00ef8a7b795cc5fc08a748e57f1757b7bd61e8a7db9e2b76a42bae6e4ab3047568a36288a15c6cde2953aad
7
+ data.tar.gz: 11432ac0dd217407e7f3209b9201d7d408746db1d4c7d813dec706ce42b3c893551f5bfeda81e454dd8daaa459811ab01e71239e33af26c0bbfe5f6eedf022ad
data/.gitignore CHANGED
@@ -16,3 +16,4 @@
16
16
  /test/dummy/log/
17
17
  /test/tmp/
18
18
  /gemfiles/*.lock
19
+ /.idea
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.4.4 (2023-07-10)
4
+
5
+ * Adapt method `sub_op` to catch `<op-class>.validation_errors` and re-throw
6
+ them as `RailsOps::Exceptions::SubOpValidationFailed`.
7
+
3
8
  ## 1.4.3 (2023-03-27)
4
9
 
5
10
  * Extend the `operation` generator to accept additional flags to skip the
@@ -32,7 +37,8 @@
32
37
 
33
38
  ### Upgrading
34
39
 
35
- Please see #33 for more information on this change. If all of your operations
40
+ Please see [#33](https://github.com/sitrox/rails_ops/issues/33) for more information
41
+ on this change. If all of your operations
36
42
  follow the standard naming conventions (e.g. `Operations::User::Update` for
37
43
  updating a model named `User`), no changes will be necessary. If you don't, you
38
44
  may need to manually specify a `param_key` when using nested model operations
data/Rakefile CHANGED
@@ -24,6 +24,7 @@ task :gemspec do
24
24
  spec.add_development_dependency 'colorize'
25
25
  spec.add_development_dependency 'rubocop', '1.45.1'
26
26
  spec.add_development_dependency 'sprockets-rails'
27
+ spec.add_development_dependency 'simplecov'
27
28
  spec.add_dependency 'active_type', '>= 1.3.0'
28
29
  spec.add_dependency 'minitest'
29
30
  spec.add_dependency 'rails'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.3
1
+ 1.4.4
@@ -52,16 +52,16 @@ class OperationGenerator < Rails::Generators::NamedBase
52
52
 
53
53
  operations_path += @underscored_name.to_s
54
54
 
55
- if !@excluded_actions.include?(:show)
55
+ unless @excluded_actions.include?(:show)
56
56
  template 'load.erb', "#{operations_path}/load.rb"
57
57
  end
58
- if !@excluded_actions.include?(:create)
58
+ unless @excluded_actions.include?(:create)
59
59
  template 'create.erb', "#{operations_path}/create.rb"
60
60
  end
61
- if !@excluded_actions.include?(:update)
61
+ unless @excluded_actions.include?(:update)
62
62
  template 'update.erb', "#{operations_path}/update.rb"
63
63
  end
64
- if !@excluded_actions.include?(:destroy)
64
+ unless @excluded_actions.include?(:destroy)
65
65
  template 'destroy.erb', "#{operations_path}/destroy.rb"
66
66
  end
67
67
  end
@@ -10,7 +10,7 @@ class RailsOps::Hookup::DSLValidator
10
10
  def validate!
11
11
  # Check infinity loop
12
12
  if target_hooks.any? { |name, targets| recursion?(targets, name) }
13
- fail StandardError::SystemStackError.new, "Infinite loop detected in hooks configuration: #{inspect_trace}."
13
+ fail SystemStackError.new, "Infinite loop detected in hooks configuration: #{inspect_trace}."
14
14
  end
15
15
  end
16
16
 
@@ -23,7 +23,7 @@ class RailsOps::Hookup
23
23
  unless @config_loaded
24
24
  @config_loaded = true
25
25
 
26
- if File.exist?(CONFIG_PATH)
26
+ if File.exist?(Rails.root.join(CONFIG_PATH))
27
27
  load Rails.root.join(CONFIG_PATH)
28
28
  else
29
29
  Rails.logger.debug "RailsOps could not find hookup #{CONFIG_PATH}, using empty hookup configuration."
@@ -11,6 +11,8 @@ module RailsOps::Mixins::SubOps
11
11
  def sub_op(op, params = {})
12
12
  new_context = context.spawn(self)
13
13
  return op.new(new_context, params)
14
+ rescue *op.validation_errors => e
15
+ fail RailsOps::Exceptions::SubOpValidationFailed, e
14
16
  end
15
17
 
16
18
  # Operation-equivalent of controller method 'run!': Instantiates and runs the
@@ -149,7 +149,7 @@ class RailsOps::Operation
149
149
 
150
150
  # Fails with an exception if the operation has not been performed yet.
151
151
  def check_performed!
152
- fail 'Operation has not yet been perfomed.' unless performed?
152
+ fail 'Operation has not yet been performed.' unless performed?
153
153
  end
154
154
 
155
155
  protected
data/rails_ops.gemspec CHANGED
@@ -1,18 +1,18 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: rails_ops 1.4.3 ruby lib
2
+ # stub: rails_ops 1.4.4 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "rails_ops".freeze
6
- s.version = "1.4.3"
6
+ s.version = "1.4.4"
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib".freeze]
10
10
  s.authors = ["Sitrox".freeze]
11
- s.date = "2023-03-27"
12
- s.files = [".github/workflows/rubocop.yml".freeze, ".github/workflows/ruby.yml".freeze, ".gitignore".freeze, ".releaser_config".freeze, ".rubocop.yml".freeze, "Appraisals".freeze, "CHANGELOG.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "gemfiles/rails_6.0.gemfile".freeze, "gemfiles/rails_6.1.gemfile".freeze, "gemfiles/rails_7.0.gemfile".freeze, "lib/generators/operation/USAGE".freeze, "lib/generators/operation/operation_generator.rb".freeze, "lib/generators/operation/templates/controller.erb".freeze, "lib/generators/operation/templates/controller_wrapper.erb".freeze, "lib/generators/operation/templates/create.erb".freeze, "lib/generators/operation/templates/destroy.erb".freeze, "lib/generators/operation/templates/load.erb".freeze, "lib/generators/operation/templates/update.erb".freeze, "lib/generators/operation/templates/view.erb".freeze, "lib/rails_ops.rb".freeze, "lib/rails_ops/authorization_backend/abstract.rb".freeze, "lib/rails_ops/authorization_backend/can_can_can.rb".freeze, "lib/rails_ops/configuration.rb".freeze, "lib/rails_ops/context.rb".freeze, "lib/rails_ops/controller_mixin.rb".freeze, "lib/rails_ops/exceptions.rb".freeze, "lib/rails_ops/hooked_job.rb".freeze, "lib/rails_ops/hookup.rb".freeze, "lib/rails_ops/hookup/dsl.rb".freeze, "lib/rails_ops/hookup/dsl_validator.rb".freeze, "lib/rails_ops/hookup/hook.rb".freeze, "lib/rails_ops/log_subscriber.rb".freeze, "lib/rails_ops/mixins.rb".freeze, "lib/rails_ops/mixins/authorization.rb".freeze, "lib/rails_ops/mixins/log_settings.rb".freeze, "lib/rails_ops/mixins/model.rb".freeze, "lib/rails_ops/mixins/model/authorization.rb".freeze, "lib/rails_ops/mixins/model/nesting.rb".freeze, "lib/rails_ops/mixins/param_authorization.rb".freeze, "lib/rails_ops/mixins/policies.rb".freeze, "lib/rails_ops/mixins/require_context.rb".freeze, "lib/rails_ops/mixins/routes.rb".freeze, "lib/rails_ops/mixins/schema_validation.rb".freeze, "lib/rails_ops/mixins/sub_ops.rb".freeze, "lib/rails_ops/model_mixins.rb".freeze, "lib/rails_ops/model_mixins/ar_extension.rb".freeze, "lib/rails_ops/model_mixins/marshalling.rb".freeze, "lib/rails_ops/model_mixins/parent_op.rb".freeze, "lib/rails_ops/model_mixins/sti_fixes.rb".freeze, "lib/rails_ops/model_mixins/virtual_attributes.rb".freeze, "lib/rails_ops/model_mixins/virtual_attributes/virtual_column_wrapper.rb".freeze, "lib/rails_ops/model_mixins/virtual_has_one.rb".freeze, "lib/rails_ops/model_mixins/virtual_model_name.rb".freeze, "lib/rails_ops/operation.rb".freeze, "lib/rails_ops/operation/model.rb".freeze, "lib/rails_ops/operation/model/create.rb".freeze, "lib/rails_ops/operation/model/destroy.rb".freeze, "lib/rails_ops/operation/model/load.rb".freeze, "lib/rails_ops/operation/model/update.rb".freeze, "lib/rails_ops/profiler.rb".freeze, "lib/rails_ops/profiler/node.rb".freeze, "lib/rails_ops/railtie.rb".freeze, "lib/rails_ops/scoped_env.rb".freeze, "lib/rails_ops/virtual_model.rb".freeze, "rails_ops.gemspec".freeze, "test/db/models.rb".freeze, "test/db/schema.rb".freeze, "test/dummy/Rakefile".freeze, "test/dummy/app/assets/config/manifest.js".freeze, "test/dummy/app/assets/images/.keep".freeze, "test/dummy/app/assets/javascripts/application.js".freeze, "test/dummy/app/assets/javascripts/cable.js".freeze, "test/dummy/app/assets/javascripts/channels/.keep".freeze, "test/dummy/app/assets/stylesheets/application.css".freeze, "test/dummy/app/channels/application_cable/channel.rb".freeze, "test/dummy/app/channels/application_cable/connection.rb".freeze, "test/dummy/app/controllers/application_controller.rb".freeze, "test/dummy/app/controllers/concerns/.keep".freeze, "test/dummy/app/helpers/application_helper.rb".freeze, "test/dummy/app/jobs/application_job.rb".freeze, "test/dummy/app/mailers/application_mailer.rb".freeze, "test/dummy/app/models/animal.rb".freeze, "test/dummy/app/models/application_record.rb".freeze, "test/dummy/app/models/bird.rb".freeze, "test/dummy/app/models/cat.rb".freeze, "test/dummy/app/models/computer.rb".freeze, "test/dummy/app/models/concerns/.keep".freeze, "test/dummy/app/models/cpu.rb".freeze, "test/dummy/app/models/dog.rb".freeze, "test/dummy/app/models/flower.rb".freeze, "test/dummy/app/models/group.rb".freeze, "test/dummy/app/models/mainboard.rb".freeze, "test/dummy/app/models/nightingale.rb".freeze, "test/dummy/app/models/phoenix.rb".freeze, "test/dummy/app/models/user.rb".freeze, "test/dummy/app/views/layouts/application.html.erb".freeze, "test/dummy/app/views/layouts/mailer.html.erb".freeze, "test/dummy/app/views/layouts/mailer.text.erb".freeze, "test/dummy/bin/bundle".freeze, "test/dummy/bin/rails".freeze, "test/dummy/bin/rake".freeze, "test/dummy/bin/setup".freeze, "test/dummy/bin/update".freeze, "test/dummy/bin/yarn".freeze, "test/dummy/config.ru".freeze, "test/dummy/config/application.rb".freeze, "test/dummy/config/boot.rb".freeze, "test/dummy/config/cable.yml".freeze, "test/dummy/config/database.yml".freeze, "test/dummy/config/environment.rb".freeze, "test/dummy/config/environments/development.rb".freeze, "test/dummy/config/environments/production.rb".freeze, "test/dummy/config/environments/test.rb".freeze, "test/dummy/config/initializers/application_controller_renderer.rb".freeze, "test/dummy/config/initializers/assets.rb".freeze, "test/dummy/config/initializers/backtrace_silencers.rb".freeze, "test/dummy/config/initializers/cookies_serializer.rb".freeze, "test/dummy/config/initializers/filter_parameter_logging.rb".freeze, "test/dummy/config/initializers/inflections.rb".freeze, "test/dummy/config/initializers/mime_types.rb".freeze, "test/dummy/config/initializers/rails_ops.rb".freeze, "test/dummy/config/initializers/wrap_parameters.rb".freeze, "test/dummy/config/locales/en.yml".freeze, "test/dummy/config/puma.rb".freeze, "test/dummy/config/routes.rb".freeze, "test/dummy/config/secrets.yml".freeze, "test/dummy/config/spring.rb".freeze, "test/dummy/db/schema.rb".freeze, "test/dummy/lib/assets/.keep".freeze, "test/dummy/log/.keep".freeze, "test/dummy/package.json".freeze, "test/dummy/public/404.html".freeze, "test/dummy/public/422.html".freeze, "test/dummy/public/500.html".freeze, "test/dummy/public/apple-touch-icon-precomposed.png".freeze, "test/dummy/public/apple-touch-icon.png".freeze, "test/dummy/public/favicon.ico".freeze, "test/dummy/tmp/.keep".freeze, "test/test_helper.rb".freeze, "test/unit/rails_ops/generators/operation_generator_test.rb".freeze, "test/unit/rails_ops/mixins/model/deep_nesting_test.rb".freeze, "test/unit/rails_ops/mixins/param_authorization_test.rb".freeze, "test/unit/rails_ops/mixins/policies_test.rb".freeze, "test/unit/rails_ops/operation/model/create_test.rb".freeze, "test/unit/rails_ops/operation/model/load_test.rb".freeze, "test/unit/rails_ops/operation/model/sti_test.rb".freeze, "test/unit/rails_ops/operation/model/update_test.rb".freeze, "test/unit/rails_ops/operation/model_test.rb".freeze, "test/unit/rails_ops/operation/update_auth_test.rb".freeze, "test/unit/rails_ops/operation/update_lazy_auth_test.rb".freeze, "test/unit/rails_ops/operation_test.rb".freeze]
11
+ s.date = "2023-07-10"
12
+ s.files = [".github/workflows/rubocop.yml".freeze, ".github/workflows/ruby.yml".freeze, ".gitignore".freeze, ".releaser_config".freeze, ".rubocop.yml".freeze, "Appraisals".freeze, "CHANGELOG.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "gemfiles/rails_6.0.gemfile".freeze, "gemfiles/rails_6.1.gemfile".freeze, "gemfiles/rails_7.0.gemfile".freeze, "lib/generators/operation/USAGE".freeze, "lib/generators/operation/operation_generator.rb".freeze, "lib/generators/operation/templates/controller.erb".freeze, "lib/generators/operation/templates/controller_wrapper.erb".freeze, "lib/generators/operation/templates/create.erb".freeze, "lib/generators/operation/templates/destroy.erb".freeze, "lib/generators/operation/templates/load.erb".freeze, "lib/generators/operation/templates/update.erb".freeze, "lib/generators/operation/templates/view.erb".freeze, "lib/rails_ops.rb".freeze, "lib/rails_ops/authorization_backend/abstract.rb".freeze, "lib/rails_ops/authorization_backend/can_can_can.rb".freeze, "lib/rails_ops/configuration.rb".freeze, "lib/rails_ops/context.rb".freeze, "lib/rails_ops/controller_mixin.rb".freeze, "lib/rails_ops/exceptions.rb".freeze, "lib/rails_ops/hooked_job.rb".freeze, "lib/rails_ops/hookup.rb".freeze, "lib/rails_ops/hookup/dsl.rb".freeze, "lib/rails_ops/hookup/dsl_validator.rb".freeze, "lib/rails_ops/hookup/hook.rb".freeze, "lib/rails_ops/log_subscriber.rb".freeze, "lib/rails_ops/mixins.rb".freeze, "lib/rails_ops/mixins/authorization.rb".freeze, "lib/rails_ops/mixins/log_settings.rb".freeze, "lib/rails_ops/mixins/model.rb".freeze, "lib/rails_ops/mixins/model/authorization.rb".freeze, "lib/rails_ops/mixins/model/nesting.rb".freeze, "lib/rails_ops/mixins/param_authorization.rb".freeze, "lib/rails_ops/mixins/policies.rb".freeze, "lib/rails_ops/mixins/require_context.rb".freeze, "lib/rails_ops/mixins/routes.rb".freeze, "lib/rails_ops/mixins/schema_validation.rb".freeze, "lib/rails_ops/mixins/sub_ops.rb".freeze, "lib/rails_ops/model_mixins.rb".freeze, "lib/rails_ops/model_mixins/ar_extension.rb".freeze, "lib/rails_ops/model_mixins/marshalling.rb".freeze, "lib/rails_ops/model_mixins/parent_op.rb".freeze, "lib/rails_ops/model_mixins/sti_fixes.rb".freeze, "lib/rails_ops/model_mixins/virtual_attributes.rb".freeze, "lib/rails_ops/model_mixins/virtual_attributes/virtual_column_wrapper.rb".freeze, "lib/rails_ops/model_mixins/virtual_has_one.rb".freeze, "lib/rails_ops/model_mixins/virtual_model_name.rb".freeze, "lib/rails_ops/operation.rb".freeze, "lib/rails_ops/operation/model.rb".freeze, "lib/rails_ops/operation/model/create.rb".freeze, "lib/rails_ops/operation/model/destroy.rb".freeze, "lib/rails_ops/operation/model/load.rb".freeze, "lib/rails_ops/operation/model/update.rb".freeze, "lib/rails_ops/profiler.rb".freeze, "lib/rails_ops/profiler/node.rb".freeze, "lib/rails_ops/railtie.rb".freeze, "lib/rails_ops/scoped_env.rb".freeze, "lib/rails_ops/virtual_model.rb".freeze, "rails_ops.gemspec".freeze, "test/db/models.rb".freeze, "test/db/schema.rb".freeze, "test/dummy/Rakefile".freeze, "test/dummy/app/assets/config/manifest.js".freeze, "test/dummy/app/assets/images/.keep".freeze, "test/dummy/app/assets/javascripts/application.js".freeze, "test/dummy/app/assets/javascripts/cable.js".freeze, "test/dummy/app/assets/javascripts/channels/.keep".freeze, "test/dummy/app/assets/stylesheets/application.css".freeze, "test/dummy/app/channels/application_cable/channel.rb".freeze, "test/dummy/app/channels/application_cable/connection.rb".freeze, "test/dummy/app/controllers/application_controller.rb".freeze, "test/dummy/app/controllers/concerns/.keep".freeze, "test/dummy/app/controllers/group_controller.rb".freeze, "test/dummy/app/helpers/application_helper.rb".freeze, "test/dummy/app/jobs/application_job.rb".freeze, "test/dummy/app/mailers/application_mailer.rb".freeze, "test/dummy/app/models/ability.rb".freeze, "test/dummy/app/models/animal.rb".freeze, "test/dummy/app/models/application_record.rb".freeze, "test/dummy/app/models/bird.rb".freeze, "test/dummy/app/models/cat.rb".freeze, "test/dummy/app/models/computer.rb".freeze, "test/dummy/app/models/concerns/.keep".freeze, "test/dummy/app/models/cpu.rb".freeze, "test/dummy/app/models/dog.rb".freeze, "test/dummy/app/models/flower.rb".freeze, "test/dummy/app/models/group.rb".freeze, "test/dummy/app/models/mainboard.rb".freeze, "test/dummy/app/models/nightingale.rb".freeze, "test/dummy/app/models/phoenix.rb".freeze, "test/dummy/app/models/user.rb".freeze, "test/dummy/app/views/layouts/application.html.erb".freeze, "test/dummy/app/views/layouts/mailer.html.erb".freeze, "test/dummy/app/views/layouts/mailer.text.erb".freeze, "test/dummy/bin/bundle".freeze, "test/dummy/bin/rails".freeze, "test/dummy/bin/rake".freeze, "test/dummy/bin/setup".freeze, "test/dummy/bin/update".freeze, "test/dummy/bin/yarn".freeze, "test/dummy/config.ru".freeze, "test/dummy/config/application.rb".freeze, "test/dummy/config/boot.rb".freeze, "test/dummy/config/cable.yml".freeze, "test/dummy/config/database.yml".freeze, "test/dummy/config/environment.rb".freeze, "test/dummy/config/environments/development.rb".freeze, "test/dummy/config/environments/production.rb".freeze, "test/dummy/config/environments/test.rb".freeze, "test/dummy/config/hookup.rb".freeze, "test/dummy/config/initializers/application_controller_renderer.rb".freeze, "test/dummy/config/initializers/assets.rb".freeze, "test/dummy/config/initializers/backtrace_silencers.rb".freeze, "test/dummy/config/initializers/cookies_serializer.rb".freeze, "test/dummy/config/initializers/filter_parameter_logging.rb".freeze, "test/dummy/config/initializers/inflections.rb".freeze, "test/dummy/config/initializers/mime_types.rb".freeze, "test/dummy/config/initializers/rails_ops.rb".freeze, "test/dummy/config/initializers/wrap_parameters.rb".freeze, "test/dummy/config/locales/en.yml".freeze, "test/dummy/config/puma.rb".freeze, "test/dummy/config/routes.rb".freeze, "test/dummy/config/secrets.yml".freeze, "test/dummy/config/spring.rb".freeze, "test/dummy/db/schema.rb".freeze, "test/dummy/lib/assets/.keep".freeze, "test/dummy/log/.keep".freeze, "test/dummy/package.json".freeze, "test/dummy/public/404.html".freeze, "test/dummy/public/422.html".freeze, "test/dummy/public/500.html".freeze, "test/dummy/public/apple-touch-icon-precomposed.png".freeze, "test/dummy/public/apple-touch-icon.png".freeze, "test/dummy/public/favicon.ico".freeze, "test/dummy/tmp/.keep".freeze, "test/test_helper.rb".freeze, "test/unit/rails_ops/generators/operation_generator_test.rb".freeze, "test/unit/rails_ops/hookup_test.rb".freeze, "test/unit/rails_ops/mixins/controller_test.rb".freeze, "test/unit/rails_ops/mixins/model/deep_nesting_test.rb".freeze, "test/unit/rails_ops/mixins/model/marshalling_test.rb".freeze, "test/unit/rails_ops/mixins/param_authorization_test.rb".freeze, "test/unit/rails_ops/mixins/policies_test.rb".freeze, "test/unit/rails_ops/operation/auth_test.rb".freeze, "test/unit/rails_ops/operation/model/create_test.rb".freeze, "test/unit/rails_ops/operation/model/destroy_test.rb".freeze, "test/unit/rails_ops/operation/model/load_test.rb".freeze, "test/unit/rails_ops/operation/model/sti_test.rb".freeze, "test/unit/rails_ops/operation/model/update_test.rb".freeze, "test/unit/rails_ops/operation/model_test.rb".freeze, "test/unit/rails_ops/operation/update_lazy_auth_test.rb".freeze, "test/unit/rails_ops/operation_test.rb".freeze, "test/unit/rails_ops/profiler_test.rb".freeze]
13
13
  s.rubygems_version = "3.4.6".freeze
14
14
  s.summary = "An operations service layer for rails projects.".freeze
15
- s.test_files = ["test/db/models.rb".freeze, "test/db/schema.rb".freeze, "test/dummy/Rakefile".freeze, "test/dummy/app/assets/config/manifest.js".freeze, "test/dummy/app/assets/images/.keep".freeze, "test/dummy/app/assets/javascripts/application.js".freeze, "test/dummy/app/assets/javascripts/cable.js".freeze, "test/dummy/app/assets/javascripts/channels/.keep".freeze, "test/dummy/app/assets/stylesheets/application.css".freeze, "test/dummy/app/channels/application_cable/channel.rb".freeze, "test/dummy/app/channels/application_cable/connection.rb".freeze, "test/dummy/app/controllers/application_controller.rb".freeze, "test/dummy/app/controllers/concerns/.keep".freeze, "test/dummy/app/helpers/application_helper.rb".freeze, "test/dummy/app/jobs/application_job.rb".freeze, "test/dummy/app/mailers/application_mailer.rb".freeze, "test/dummy/app/models/animal.rb".freeze, "test/dummy/app/models/application_record.rb".freeze, "test/dummy/app/models/bird.rb".freeze, "test/dummy/app/models/cat.rb".freeze, "test/dummy/app/models/computer.rb".freeze, "test/dummy/app/models/concerns/.keep".freeze, "test/dummy/app/models/cpu.rb".freeze, "test/dummy/app/models/dog.rb".freeze, "test/dummy/app/models/flower.rb".freeze, "test/dummy/app/models/group.rb".freeze, "test/dummy/app/models/mainboard.rb".freeze, "test/dummy/app/models/nightingale.rb".freeze, "test/dummy/app/models/phoenix.rb".freeze, "test/dummy/app/models/user.rb".freeze, "test/dummy/app/views/layouts/application.html.erb".freeze, "test/dummy/app/views/layouts/mailer.html.erb".freeze, "test/dummy/app/views/layouts/mailer.text.erb".freeze, "test/dummy/bin/bundle".freeze, "test/dummy/bin/rails".freeze, "test/dummy/bin/rake".freeze, "test/dummy/bin/setup".freeze, "test/dummy/bin/update".freeze, "test/dummy/bin/yarn".freeze, "test/dummy/config.ru".freeze, "test/dummy/config/application.rb".freeze, "test/dummy/config/boot.rb".freeze, "test/dummy/config/cable.yml".freeze, "test/dummy/config/database.yml".freeze, "test/dummy/config/environment.rb".freeze, "test/dummy/config/environments/development.rb".freeze, "test/dummy/config/environments/production.rb".freeze, "test/dummy/config/environments/test.rb".freeze, "test/dummy/config/initializers/application_controller_renderer.rb".freeze, "test/dummy/config/initializers/assets.rb".freeze, "test/dummy/config/initializers/backtrace_silencers.rb".freeze, "test/dummy/config/initializers/cookies_serializer.rb".freeze, "test/dummy/config/initializers/filter_parameter_logging.rb".freeze, "test/dummy/config/initializers/inflections.rb".freeze, "test/dummy/config/initializers/mime_types.rb".freeze, "test/dummy/config/initializers/rails_ops.rb".freeze, "test/dummy/config/initializers/wrap_parameters.rb".freeze, "test/dummy/config/locales/en.yml".freeze, "test/dummy/config/puma.rb".freeze, "test/dummy/config/routes.rb".freeze, "test/dummy/config/secrets.yml".freeze, "test/dummy/config/spring.rb".freeze, "test/dummy/db/schema.rb".freeze, "test/dummy/lib/assets/.keep".freeze, "test/dummy/log/.keep".freeze, "test/dummy/package.json".freeze, "test/dummy/public/404.html".freeze, "test/dummy/public/422.html".freeze, "test/dummy/public/500.html".freeze, "test/dummy/public/apple-touch-icon-precomposed.png".freeze, "test/dummy/public/apple-touch-icon.png".freeze, "test/dummy/public/favicon.ico".freeze, "test/dummy/tmp/.keep".freeze, "test/test_helper.rb".freeze, "test/unit/rails_ops/generators/operation_generator_test.rb".freeze, "test/unit/rails_ops/mixins/model/deep_nesting_test.rb".freeze, "test/unit/rails_ops/mixins/param_authorization_test.rb".freeze, "test/unit/rails_ops/mixins/policies_test.rb".freeze, "test/unit/rails_ops/operation/model/create_test.rb".freeze, "test/unit/rails_ops/operation/model/load_test.rb".freeze, "test/unit/rails_ops/operation/model/sti_test.rb".freeze, "test/unit/rails_ops/operation/model/update_test.rb".freeze, "test/unit/rails_ops/operation/model_test.rb".freeze, "test/unit/rails_ops/operation/update_auth_test.rb".freeze, "test/unit/rails_ops/operation/update_lazy_auth_test.rb".freeze, "test/unit/rails_ops/operation_test.rb".freeze]
15
+ s.test_files = ["test/db/models.rb".freeze, "test/db/schema.rb".freeze, "test/dummy/Rakefile".freeze, "test/dummy/app/assets/config/manifest.js".freeze, "test/dummy/app/assets/images/.keep".freeze, "test/dummy/app/assets/javascripts/application.js".freeze, "test/dummy/app/assets/javascripts/cable.js".freeze, "test/dummy/app/assets/javascripts/channels/.keep".freeze, "test/dummy/app/assets/stylesheets/application.css".freeze, "test/dummy/app/channels/application_cable/channel.rb".freeze, "test/dummy/app/channels/application_cable/connection.rb".freeze, "test/dummy/app/controllers/application_controller.rb".freeze, "test/dummy/app/controllers/concerns/.keep".freeze, "test/dummy/app/controllers/group_controller.rb".freeze, "test/dummy/app/helpers/application_helper.rb".freeze, "test/dummy/app/jobs/application_job.rb".freeze, "test/dummy/app/mailers/application_mailer.rb".freeze, "test/dummy/app/models/ability.rb".freeze, "test/dummy/app/models/animal.rb".freeze, "test/dummy/app/models/application_record.rb".freeze, "test/dummy/app/models/bird.rb".freeze, "test/dummy/app/models/cat.rb".freeze, "test/dummy/app/models/computer.rb".freeze, "test/dummy/app/models/concerns/.keep".freeze, "test/dummy/app/models/cpu.rb".freeze, "test/dummy/app/models/dog.rb".freeze, "test/dummy/app/models/flower.rb".freeze, "test/dummy/app/models/group.rb".freeze, "test/dummy/app/models/mainboard.rb".freeze, "test/dummy/app/models/nightingale.rb".freeze, "test/dummy/app/models/phoenix.rb".freeze, "test/dummy/app/models/user.rb".freeze, "test/dummy/app/views/layouts/application.html.erb".freeze, "test/dummy/app/views/layouts/mailer.html.erb".freeze, "test/dummy/app/views/layouts/mailer.text.erb".freeze, "test/dummy/bin/bundle".freeze, "test/dummy/bin/rails".freeze, "test/dummy/bin/rake".freeze, "test/dummy/bin/setup".freeze, "test/dummy/bin/update".freeze, "test/dummy/bin/yarn".freeze, "test/dummy/config.ru".freeze, "test/dummy/config/application.rb".freeze, "test/dummy/config/boot.rb".freeze, "test/dummy/config/cable.yml".freeze, "test/dummy/config/database.yml".freeze, "test/dummy/config/environment.rb".freeze, "test/dummy/config/environments/development.rb".freeze, "test/dummy/config/environments/production.rb".freeze, "test/dummy/config/environments/test.rb".freeze, "test/dummy/config/hookup.rb".freeze, "test/dummy/config/initializers/application_controller_renderer.rb".freeze, "test/dummy/config/initializers/assets.rb".freeze, "test/dummy/config/initializers/backtrace_silencers.rb".freeze, "test/dummy/config/initializers/cookies_serializer.rb".freeze, "test/dummy/config/initializers/filter_parameter_logging.rb".freeze, "test/dummy/config/initializers/inflections.rb".freeze, "test/dummy/config/initializers/mime_types.rb".freeze, "test/dummy/config/initializers/rails_ops.rb".freeze, "test/dummy/config/initializers/wrap_parameters.rb".freeze, "test/dummy/config/locales/en.yml".freeze, "test/dummy/config/puma.rb".freeze, "test/dummy/config/routes.rb".freeze, "test/dummy/config/secrets.yml".freeze, "test/dummy/config/spring.rb".freeze, "test/dummy/db/schema.rb".freeze, "test/dummy/lib/assets/.keep".freeze, "test/dummy/log/.keep".freeze, "test/dummy/package.json".freeze, "test/dummy/public/404.html".freeze, "test/dummy/public/422.html".freeze, "test/dummy/public/500.html".freeze, "test/dummy/public/apple-touch-icon-precomposed.png".freeze, "test/dummy/public/apple-touch-icon.png".freeze, "test/dummy/public/favicon.ico".freeze, "test/dummy/tmp/.keep".freeze, "test/test_helper.rb".freeze, "test/unit/rails_ops/generators/operation_generator_test.rb".freeze, "test/unit/rails_ops/hookup_test.rb".freeze, "test/unit/rails_ops/mixins/controller_test.rb".freeze, "test/unit/rails_ops/mixins/model/deep_nesting_test.rb".freeze, "test/unit/rails_ops/mixins/model/marshalling_test.rb".freeze, "test/unit/rails_ops/mixins/param_authorization_test.rb".freeze, "test/unit/rails_ops/mixins/policies_test.rb".freeze, "test/unit/rails_ops/operation/auth_test.rb".freeze, "test/unit/rails_ops/operation/model/create_test.rb".freeze, "test/unit/rails_ops/operation/model/destroy_test.rb".freeze, "test/unit/rails_ops/operation/model/load_test.rb".freeze, "test/unit/rails_ops/operation/model/sti_test.rb".freeze, "test/unit/rails_ops/operation/model/update_test.rb".freeze, "test/unit/rails_ops/operation/model_test.rb".freeze, "test/unit/rails_ops/operation/update_lazy_auth_test.rb".freeze, "test/unit/rails_ops/operation_test.rb".freeze, "test/unit/rails_ops/profiler_test.rb".freeze]
16
16
 
17
17
  s.specification_version = 4
18
18
 
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
25
25
  s.add_development_dependency(%q<colorize>.freeze, [">= 0"])
26
26
  s.add_development_dependency(%q<rubocop>.freeze, ["= 1.45.1"])
27
27
  s.add_development_dependency(%q<sprockets-rails>.freeze, [">= 0"])
28
+ s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
28
29
  s.add_runtime_dependency(%q<active_type>.freeze, [">= 1.3.0"])
29
30
  s.add_runtime_dependency(%q<minitest>.freeze, [">= 0"])
30
31
  s.add_runtime_dependency(%q<rails>.freeze, [">= 0"])
@@ -0,0 +1,28 @@
1
+ class GroupController < ApplicationController
2
+ attr_reader :current_user
3
+ skip_before_action :verify_authenticity_token
4
+
5
+ def initialize
6
+ super
7
+ @current_user = Class.new
8
+ end
9
+
10
+ def show
11
+ cls = Class.new(RailsOps::Operation::Model::Load) do
12
+ model Group
13
+ end
14
+
15
+ op cls, id: params[:id]
16
+ render json: model
17
+ end
18
+
19
+ def update
20
+ cls = Class.new(RailsOps::Operation::Model::Update) do
21
+ model Group
22
+ end
23
+
24
+ op cls, id: params[:id], group: {name: params[:name]}
25
+ run!
26
+ render json: model
27
+ end
28
+ end
@@ -0,0 +1,7 @@
1
+ class Ability
2
+ include CanCan::Ability
3
+
4
+ def initialize(_user)
5
+ can :manage, :all
6
+ end
7
+ end
@@ -1 +1,5 @@
1
- class Animal < ApplicationRecord; end
1
+ class Animal < ApplicationRecord
2
+ has_many :dogs
3
+ belongs_to :bird, optional: true
4
+ belongs_to :phoenix, optional: true, validate: false, autosave: false
5
+ end
@@ -1 +1,3 @@
1
- class Bird < Animal; end
1
+ class Bird < Animal
2
+ has_one :phoenix, inverse_of: :bird
3
+ end
@@ -1 +1,3 @@
1
- class Phoenix < Bird; end
1
+ class Phoenix < Bird
2
+ belongs_to :bird, optional: true, autosave: false, inverse_of: :phoenix, validate: true
3
+ end
@@ -51,4 +51,6 @@ Rails.application.configure do
51
51
  # Use an evented file watcher to asynchronously detect changes in source code,
52
52
  # routes, locales, etc. This feature depends on the listen gem.
53
53
  # config.file_watcher = ActiveSupport::EventedFileUpdateChecker
54
+
55
+ config.hosts = ['www.example.com']
54
56
  end
@@ -88,4 +88,6 @@ Rails.application.configure do
88
88
 
89
89
  # Do not dump schema after migrations.
90
90
  config.active_record.dump_schema_after_migration = false
91
+
92
+ config.hosts = ['www.example.com']
91
93
  end
@@ -0,0 +1,5 @@
1
+ RailsOps.hookup.draw do
2
+ run 'RailsOps::HookupTest::HookupTarget' do
3
+ on 'RailsOps::HookupTest::HookupStarter'
4
+ end
5
+ end
@@ -1,3 +1,4 @@
1
1
  Rails.application.routes.draw do
2
2
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
3
+ resources :group, only: [:show, :update]
3
4
  end
data/test/test_helper.rb CHANGED
@@ -1,3 +1,8 @@
1
+ require 'simplecov'
2
+ SimpleCov.start do
3
+ add_filter '/test/'
4
+ end
5
+
1
6
  require File.expand_path('../test/dummy/config/environment.rb', __dir__)
2
7
  # ActiveRecord::Migrator.migrations_paths = [File.expand_path("../../test/dummy/db/migrate", __FILE__)]
3
8
  require 'rails/test_help'
@@ -0,0 +1,82 @@
1
+ require 'test_helper'
2
+
3
+ class RailsOps::HookupTest < ActiveSupport::TestCase
4
+ include TestHelper
5
+
6
+ class RailsOps::HookupTest::HookupStarter < RailsOps::Operation::Model::Create
7
+ model ::Group
8
+ end
9
+
10
+ class RailsOps::HookupTest::HookupTarget < RailsOps::Operation
11
+ def perform
12
+ Group.find_by(name: 'hookup_test_group').update({ color: 'blue' })
13
+ end
14
+ end
15
+
16
+ def test_hooked_op
17
+ group = RailsOps::HookupTest::HookupStarter.run!(group: { name: 'hookup_test_group' }).model
18
+ group.reload
19
+ assert_equal 'blue', group.color
20
+ end
21
+
22
+ def test_recursive_hookup_raises
23
+ RailsOps.hookup.instance_variable_set(:@drawn, false)
24
+ RailsOps.hookup.instance_variable_set(:@config_loaded, false)
25
+ assert_raises SystemStackError do
26
+ RailsOps.hookup.draw do
27
+ run 'RailsOps::HookupTest::HookupTarget' do
28
+ on 'RailsOps::HookupTest::HookupStarter'
29
+ end
30
+
31
+ run 'RailsOps::HookupTest::HookupStarter' do
32
+ on 'RailsOps::HookupTest::HookupTarget'
33
+ end
34
+ end
35
+ end
36
+ RailsOps.hookup.load_config
37
+ end
38
+
39
+ def test_dont_draw_twice
40
+ assert_raises_with_message RuntimeError, "Hooks can't be drawn twice." do
41
+ RailsOps.hookup.draw do
42
+ run 'RailsOps::HookupTest::HookupTarget' do
43
+ on 'RailsOps::HookupTest::HookupStarter'
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ def test_missing_hookup_op
50
+ RailsOps.hookup.load_config
51
+ RailsOps.hookup.instance_variable_set(:@drawn, false)
52
+ RailsOps.hookup.draw do
53
+ run 'RailsOps::HookupTest::HookupIllusiveTarget' do
54
+ on 'RailsOps::HookupTest::HookupStarter'
55
+ end
56
+ end
57
+
58
+ assert_raises_with_message RuntimeError, 'Could not find hook target operation RailsOps::HookupTest::HookupIllusiveTarget.' do
59
+ RailsOps::HookupTest::HookupStarter.run!(group: { name: 'group' })
60
+ end
61
+
62
+ RailsOps.hookup.instance_variable_set(:@drawn, false)
63
+ RailsOps.hookup.instance_variable_set(:@config_loaded, false)
64
+ RailsOps.hookup.load_config
65
+ end
66
+
67
+ def test_missing_config_file
68
+ orig_path = RailsOps::Hookup::CONFIG_PATH
69
+ RailsOps::Hookup.const_set(:CONFIG_PATH, '/def/doesnt/exist')
70
+ RailsOps.hookup.instance_variable_set(:@drawn, false)
71
+ RailsOps.hookup.instance_variable_set(:@config_loaded, false)
72
+ assert_nothing_raised do
73
+ RailsOps.hookup.load_config
74
+ end
75
+ assert_equal({}, RailsOps.hookup.hooks)
76
+
77
+ RailsOps::Hookup.const_set(:CONFIG_PATH, orig_path)
78
+ RailsOps.hookup.instance_variable_set(:@drawn, false)
79
+ RailsOps.hookup.instance_variable_set(:@config_loaded, false)
80
+ RailsOps.hookup.load_config
81
+ end
82
+ end
@@ -0,0 +1,21 @@
1
+ require 'test_helper'
2
+ require 'cancancan'
3
+
4
+ class RailsOps::Mixins::ControllerTest < ActionDispatch::IntegrationTest
5
+ include TestHelper
6
+
7
+ def test_controller_op
8
+ group = Group.create(name: 'group')
9
+ get group_url(group), as: :json
10
+ assert_equal 'group', JSON.parse(@response.body)['name']
11
+ end
12
+
13
+ def test_controller_op_run
14
+ group = Group.create(name: 'group')
15
+ patch group_url(group), params: { name: 'group2' }, as: :json
16
+ assert_equal 'group2', JSON.parse(@response.body)['name']
17
+
18
+ group.reload
19
+ assert_equal 'group2', group.name
20
+ end
21
+ end
@@ -92,6 +92,67 @@ class RailsOps::Mixins::Model::DeepNestingTest < ActiveSupport::TestCase
92
92
  assert_equal 'CPU', model.mainboard.cpu.name
93
93
  end
94
94
 
95
+ def test_without_asoc
96
+ assert_raises_with_message RuntimeError, 'Association cat could not be found for Animal.' do
97
+ Class.new(RailsOps::Operation::Model::Create) do
98
+ model Animal
99
+
100
+ nest_model_op :cat, Class.new(RailsOps::Operation::Model::Create) do
101
+ model Cat
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ def test_wrong_asoc_type
108
+ assert_raises_with_message RuntimeError,
109
+ 'Method nest_model_op only supports :belongs_to associations, but association dogs of model Animal is a has_many association.' do
110
+ Class.new(RailsOps::Operation::Model::Create) do
111
+ model Animal
112
+
113
+ nest_model_op :dogs, Class.new(RailsOps::Operation::Model::Create) do
114
+ model Dog
115
+ end
116
+ end
117
+ end
118
+ end
119
+
120
+ def test_autosave_on
121
+ assert_raises_with_message RuntimeError, 'Association bird of Animal has :autosave turned on. This is not supported by nest_model_op.' do
122
+ Class.new(RailsOps::Operation::Model::Create) do
123
+ model Animal
124
+
125
+ nest_model_op :bird, Class.new(RailsOps::Operation::Model::Create) do
126
+ model Bird
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ def test_validation_off
133
+ assert_raises_with_message RuntimeError, 'Association phoenix of Animal has :validate turned off. This is not supported by nest_model_op.' do
134
+ Class.new(RailsOps::Operation::Model::Create) do
135
+ model Animal
136
+
137
+ nest_model_op :phoenix, Class.new(RailsOps::Operation::Model::Create) do
138
+ model Phoenix
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ def test_inverse_autosave_on
145
+ assert_raises_with_message RuntimeError, 'Association phoenix of Bird has :autosave turned on. This is not supported by nest_model_op.' do
146
+ Class.new(RailsOps::Operation::Model::Create) do
147
+ model Phoenix
148
+
149
+ nest_model_op :bird, Class.new(RailsOps::Operation::Model::Create) do
150
+ model Bird
151
+ end
152
+ end
153
+ end
154
+ end
155
+
95
156
  def test_create_computer_level_1_validation_error
96
157
  op = COMPUTER_CREATION_OP.new(
97
158
  computer: {
@@ -197,7 +258,6 @@ class RailsOps::Mixins::Model::DeepNestingTest < ActiveSupport::TestCase
197
258
  )
198
259
 
199
260
  refute update_op.run
200
- assert_equal :name, update_op.model.mainboard.errors.first.attribute
201
- assert_equal :blank, update_op.model.mainboard.errors.first.type
261
+ assert update_op.model.mainboard.errors.added?(:name, :blank)
202
262
  end
203
263
  end
@@ -0,0 +1,36 @@
1
+ require 'test_helper'
2
+
3
+ class RailsOps::Mixins::Model::MarshallingTest < ActiveSupport::TestCase
4
+ include TestHelper
5
+
6
+ class RailsOps::Mixins::Model::MarshallingTest::ParentOp < RailsOps::Operation::Model::Create
7
+ model Group
8
+ attr_reader :loaded_child_class
9
+ attr_reader :loaded_child_parent_op
10
+
11
+ def perform
12
+ sub_op = run_sub! RailsOps::Mixins::Model::MarshallingTest::ChildOp
13
+
14
+ dump_res = Marshal.dump(sub_op)
15
+ # rubocop:disable Security/MarshalLoad
16
+ load_res = Marshal.load(dump_res)
17
+ # rubocop:enable Security/MarshalLoad
18
+
19
+ @loaded_child_class = load_res.class
20
+ @loaded_child_parent_op = load_res.model.parent_op
21
+ end
22
+ end
23
+
24
+ class RailsOps::Mixins::Model::MarshallingTest::ChildOp < RailsOps::Operation::Model::Create
25
+ model Group
26
+ def perform; end
27
+ end
28
+
29
+ def test_marshal_dump_and_load
30
+ assert_nothing_raised do
31
+ op_res = RailsOps::Mixins::Model::MarshallingTest::ParentOp.run!
32
+ assert_equal RailsOps::Mixins::Model::MarshallingTest::ChildOp, op_res.loaded_child_class
33
+ assert_nil op_res.loaded_child_parent_op
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,120 @@
1
+ require 'test_helper'
2
+ require 'rails_ops/authorization_backend/can_can_can'
3
+ require 'cancancan'
4
+
5
+ class RailsOps::Operation::AuthTest < ActiveSupport::TestCase
6
+ include TestHelper
7
+
8
+ LOAD_OP = Class.new(RailsOps::Operation::Model::Load) do
9
+ model ::Group
10
+ end
11
+
12
+ LOAD_OP_WITHOUT_AUTH = Class.new(RailsOps::Operation::Model::Load) do
13
+ model ::Group
14
+ without_authorization
15
+ end
16
+
17
+ UPDATE_OP = Class.new(RailsOps::Operation::Model::Update) do
18
+ model ::Group
19
+ end
20
+
21
+ CREATE_OP = Class.new(RailsOps::Operation::Model::Create) do
22
+ model ::Group
23
+ end
24
+
25
+ DESTROY_OP = Class.new(RailsOps::Operation::Model::Destroy) do
26
+ model ::Group
27
+ end
28
+
29
+ ABILITY = Class.new do
30
+ include CanCan::Ability
31
+
32
+ def initialize(read: false, update: false, create: false, destroy: false)
33
+ super()
34
+
35
+ can :read, Group if read
36
+ can :update, Group if update
37
+ can :create, Group if create
38
+ can :destroy, Group if destroy
39
+ end
40
+ end
41
+
42
+ setup do
43
+ Group.create!(id: 1, name: 'Group')
44
+ RailsOps.config.authorization_backend = 'RailsOps::AuthorizationBackend::CanCanCan'
45
+ end
46
+
47
+ def test_unpermitted_read
48
+ ctx = RailsOps::Context.new(ability: ABILITY.new)
49
+ assert_raises CanCan::AccessDenied do
50
+ LOAD_OP.new(ctx, id: 1)
51
+ end
52
+ end
53
+
54
+ def test_unpermitted_read_without_auth
55
+ ctx = RailsOps::Context.new(ability: ABILITY.new)
56
+ assert_nothing_raised do
57
+ LOAD_OP_WITHOUT_AUTH.new(ctx, id: 1)
58
+ end
59
+ end
60
+
61
+ def test_permitted_read
62
+ ctx = RailsOps::Context.new(ability: ABILITY.new(read: true))
63
+ assert_nothing_raised do
64
+ res = LOAD_OP.new(ctx, id: 1)
65
+ assert_equal 'Group', res.model.name
66
+ end
67
+ end
68
+
69
+ def test_unpermitted_update
70
+ ctx = RailsOps::Context.new(ability: ABILITY.new(read: true))
71
+ assert_raises CanCan::AccessDenied do
72
+ op = UPDATE_OP.new(ctx, id: 1, group: { name: 'Group2' })
73
+ res = op.run!
74
+ assert_equal 'Group', res.model.name
75
+ end
76
+ end
77
+
78
+ def test_permitted_update
79
+ ctx = RailsOps::Context.new(ability: ABILITY.new(read: true, update: true))
80
+ assert_nothing_raised do
81
+ op = UPDATE_OP.new(ctx, id: 1, group: { name: 'Group2' })
82
+ res = op.run!
83
+ assert_equal 'Group2', res.model.name
84
+ end
85
+ end
86
+
87
+ def test_unpermitted_create
88
+ ctx = RailsOps::Context.new(ability: ABILITY.new(read: true))
89
+ assert_raises CanCan::AccessDenied do
90
+ op = CREATE_OP.new(ctx, id: 2, group: { name: 'Group2' })
91
+ op.run!
92
+ end
93
+ end
94
+
95
+ def test_permitted_create
96
+ ctx = RailsOps::Context.new(ability: ABILITY.new(read: true, create: true))
97
+ assert_nothing_raised do
98
+ op = CREATE_OP.new(ctx, id: 2, group: { name: 'Group2' })
99
+ op.run!
100
+ res = LOAD_OP.new(id: 2)
101
+ assert_equal 'Group2', res.model.name
102
+ end
103
+ end
104
+
105
+ def test_unpermitted_destroy
106
+ ctx = RailsOps::Context.new(ability: ABILITY.new(read: true))
107
+ assert_raises CanCan::AccessDenied do
108
+ op = DESTROY_OP.new(ctx, id: 1)
109
+ op.run!
110
+ end
111
+ end
112
+
113
+ def test_permitted_destroy
114
+ ctx = RailsOps::Context.new(ability: ABILITY.new(read: true, destroy: true))
115
+ assert_nothing_raised do
116
+ op = DESTROY_OP.new(ctx, id: 1)
117
+ op.run!
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,31 @@
1
+ class RailsOps::Operation::Model::DestroyTest < ActiveSupport::TestCase
2
+ include TestHelper
3
+
4
+ BASIC_OP = Class.new(RailsOps::Operation::Model::Destroy) do
5
+ model Group
6
+ end
7
+
8
+ def test_basic
9
+ g = Group.create
10
+ op = BASIC_OP.new(id: g.id)
11
+ assert_equal g, op.model
12
+ assert_equal Group, op.model.class
13
+ op.run!
14
+ assert op.model.destroyed?
15
+ end
16
+
17
+ def test_not_deletable
18
+ g = Group.create
19
+ cls = Class.new(RailsOps::Operation::Model::Destroy) do
20
+ model Group, 'NotDeletableGroup' do
21
+ def deleteable?
22
+ false
23
+ end
24
+ end
25
+ end
26
+ op = cls.new(id: g.id)
27
+ assert_raises RailsOps::Exceptions::ModelNotDeleteable do
28
+ op.run!
29
+ end
30
+ end
31
+ end
@@ -51,4 +51,13 @@ class RailsOps::Operation::Model::LoadTest < ActiveSupport::TestCase
51
51
  g = Group.create(name: 'g1')
52
52
  assert_equal g, cls.new(name: 'g1').model
53
53
  end
54
+
55
+ def test_too_many_authorization_actions
56
+ assert_raises_with_message ArgumentError, 'Too many arguments' do
57
+ Class.new(RailsOps::Operation::Model::Load) do
58
+ model Group
59
+ model_authorization_action :read, :update
60
+ end
61
+ end
62
+ end
54
63
  end
@@ -47,6 +47,21 @@ class RailsOps::Operation::ModelTest < ActiveSupport::TestCase
47
47
  assert_equal 'Example', cls.model.virtual_model_name
48
48
  end
49
49
 
50
+ def test_virtual_model_write_attribute
51
+ cls = Class.new(RailsOps::Operation::Model) do
52
+ model RailsOps::VirtualModel, 'Example' do
53
+ attribute :name, default: 'name'
54
+ end
55
+ end
56
+
57
+ assert_equal 'name', cls.model.new.read_attribute(:name)
58
+ assert_nothing_raised do
59
+ obj = cls.model.new
60
+ obj.write_attribute(:name, 'name2')
61
+ assert_equal 'name2', obj.read_attribute(:name)
62
+ end
63
+ end
64
+
50
65
  def test_default_model_class
51
66
  cls = Class.new(RailsOps::Operation::Model) do
52
67
  model do
@@ -64,4 +79,13 @@ class RailsOps::Operation::ModelTest < ActiveSupport::TestCase
64
79
  end
65
80
  end
66
81
  end
82
+
83
+ def test_lazy_model
84
+ cls = Class.new(RailsOps::Operation::Model::Create) do
85
+ lazy_model 'Group'
86
+ end
87
+
88
+ assert_not cls.model.class < Group
89
+ assert cls.new.model.class < Group
90
+ end
67
91
  end
@@ -40,6 +40,16 @@ class RailsOps::OperationTest < ActiveSupport::TestCase
40
40
  assert BASIC_OP.new.run!.done
41
41
  end
42
42
 
43
+ def test_run_without_perform
44
+ cls = Class.new(RailsOps::Operation)
45
+ assert_nothing_raised do
46
+ cls.new
47
+ end
48
+ assert_raises NotImplementedError do
49
+ cls.run!
50
+ end
51
+ end
52
+
43
53
  def test_non_validation_error
44
54
  assert_raises_with_message RuntimeError, 'Standard exception' do
45
55
  BASIC_OP.run(exception: 'Standard exception')
@@ -146,6 +156,17 @@ class RailsOps::OperationTest < ActiveSupport::TestCase
146
156
  assert op.performed?
147
157
  end
148
158
 
159
+ def test_check_performed
160
+ op = BASIC_OP.new
161
+ assert_raises_with_message RuntimeError, 'Operation has not yet been performed.' do
162
+ op.check_performed!
163
+ end
164
+ op.run!
165
+ assert_nothing_raised do
166
+ op.check_performed!
167
+ end
168
+ end
169
+
149
170
  def test_inspect
150
171
  assert_equal 'RailsOps::OperationTest::BASIC_OP ({"foo"=>:bar})',
151
172
  BASIC_OP.new(foo: :bar).inspect
@@ -155,4 +176,104 @@ class RailsOps::OperationTest < ActiveSupport::TestCase
155
176
  assert_equal 'RailsOps::OperationTest::BASIC_OP ({1=>2})',
156
177
  BASIC_OP.new(1 => 2).inspect
157
178
  end
179
+
180
+ def test_with_rollback_on_exception
181
+ op = Class.new(RailsOps::Operation) do
182
+ def perform
183
+ with_rollback_on_exception do
184
+ fail 'Rollback please'
185
+ end
186
+ end
187
+ end.new
188
+ assert_raises RailsOps::Exceptions::RollbackRequired do
189
+ op.run
190
+ end
191
+ end
192
+
193
+ def test_op_with_schema3(use_default: false)
194
+ op = Class.new(RailsOps::Operation) do
195
+ schema_block = proc do
196
+ int! :id
197
+ hsh! :hash do
198
+ int? :number
199
+ int! :required_number
200
+ end
201
+ end
202
+ if use_default
203
+ schema(&schema_block)
204
+ else
205
+ schema3(&schema_block)
206
+ end
207
+ end
208
+
209
+ assert_nothing_raised do
210
+ op.new(id: 1, hash: { required_number: 1 })
211
+ end
212
+ assert_raises Schemacop::Exceptions::ValidationError do
213
+ op.new(id: 1, hash: {})
214
+ end
215
+ end
216
+
217
+ def test_op_with_schema2(use_default: false)
218
+ op = Class.new(RailsOps::Operation) do
219
+ schema_block = proc do
220
+ req :id, :integer
221
+ req :hash, :hash do
222
+ opt :number, :integer
223
+ req :required_number, :integer
224
+ end
225
+ end
226
+
227
+ if use_default
228
+ schema(&schema_block)
229
+ else
230
+ schema2(&schema_block)
231
+ end
232
+ end
233
+
234
+ assert_nothing_raised do
235
+ op.new(id: 1, hash: { required_number: 1 })
236
+ end
237
+ assert_raises Schemacop::Exceptions::ValidationError do
238
+ op.new(id: 1, hash: {})
239
+ end
240
+ end
241
+
242
+ def test_op_with_schema_default
243
+ RailsOps.config.default_schemacop_version = 3
244
+ test_op_with_schema3(use_default: true)
245
+
246
+ RailsOps.config.default_schemacop_version = 2
247
+ test_op_with_schema2(use_default: true)
248
+
249
+ RailsOps.config.default_schemacop_version = -50
250
+ assert_raises_with_message RuntimeError, 'Schemacop schema versions supported are 2 and 3.' do
251
+ test_op_with_schema3(use_default: true)
252
+ end
253
+ RailsOps.config.default_schemacop_version = 3
254
+ end
255
+
256
+ def test_require_context
257
+ op = Class.new(RailsOps::Operation) do
258
+ require_context :user, :session
259
+ end
260
+
261
+ ctx = RailsOps::Context.new(user: Class.new, session: Class.new)
262
+ assert_raises_with_message RailsOps::Exceptions::MissingContextAttribute, 'This operation requires the context attribute :user to be present.' do
263
+ op.new
264
+ end
265
+ assert_nothing_raised do
266
+ op.new(ctx, foo: :bar)
267
+ end
268
+ end
269
+
270
+ def test_run_through_context
271
+ op = Class.new(RailsOps::Operation) do
272
+ def perform; end
273
+ end
274
+ ctx = RailsOps::Context.new(user: Class.new, session: Class.new)
275
+ assert_nothing_raised do
276
+ ctx.run! op, foo: :bar
277
+ end
278
+ end
158
279
  end
@@ -0,0 +1,11 @@
1
+ class RailsOps::ProfilerTest < ActiveSupport::TestCase
2
+ include TestHelper
3
+
4
+ def test_time
5
+ assert_output(/Test - 1\d\.\dms elapsed./) do
6
+ RailsOps::Profiler.time 'Test' do
7
+ sleep 0.010
8
+ end
9
+ end
10
+ end
11
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_ops
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.3
4
+ version: 1.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sitrox
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-27 00:00:00.000000000 Z
11
+ date: 2023-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: appraisal
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: simplecov
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: active_type
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -301,9 +315,11 @@ files:
301
315
  - test/dummy/app/channels/application_cable/connection.rb
302
316
  - test/dummy/app/controllers/application_controller.rb
303
317
  - test/dummy/app/controllers/concerns/.keep
318
+ - test/dummy/app/controllers/group_controller.rb
304
319
  - test/dummy/app/helpers/application_helper.rb
305
320
  - test/dummy/app/jobs/application_job.rb
306
321
  - test/dummy/app/mailers/application_mailer.rb
322
+ - test/dummy/app/models/ability.rb
307
323
  - test/dummy/app/models/animal.rb
308
324
  - test/dummy/app/models/application_record.rb
309
325
  - test/dummy/app/models/bird.rb
@@ -336,6 +352,7 @@ files:
336
352
  - test/dummy/config/environments/development.rb
337
353
  - test/dummy/config/environments/production.rb
338
354
  - test/dummy/config/environments/test.rb
355
+ - test/dummy/config/hookup.rb
339
356
  - test/dummy/config/initializers/application_controller_renderer.rb
340
357
  - test/dummy/config/initializers/assets.rb
341
358
  - test/dummy/config/initializers/backtrace_silencers.rb
@@ -363,17 +380,22 @@ files:
363
380
  - test/dummy/tmp/.keep
364
381
  - test/test_helper.rb
365
382
  - test/unit/rails_ops/generators/operation_generator_test.rb
383
+ - test/unit/rails_ops/hookup_test.rb
384
+ - test/unit/rails_ops/mixins/controller_test.rb
366
385
  - test/unit/rails_ops/mixins/model/deep_nesting_test.rb
386
+ - test/unit/rails_ops/mixins/model/marshalling_test.rb
367
387
  - test/unit/rails_ops/mixins/param_authorization_test.rb
368
388
  - test/unit/rails_ops/mixins/policies_test.rb
389
+ - test/unit/rails_ops/operation/auth_test.rb
369
390
  - test/unit/rails_ops/operation/model/create_test.rb
391
+ - test/unit/rails_ops/operation/model/destroy_test.rb
370
392
  - test/unit/rails_ops/operation/model/load_test.rb
371
393
  - test/unit/rails_ops/operation/model/sti_test.rb
372
394
  - test/unit/rails_ops/operation/model/update_test.rb
373
395
  - test/unit/rails_ops/operation/model_test.rb
374
- - test/unit/rails_ops/operation/update_auth_test.rb
375
396
  - test/unit/rails_ops/operation/update_lazy_auth_test.rb
376
397
  - test/unit/rails_ops/operation_test.rb
398
+ - test/unit/rails_ops/profiler_test.rb
377
399
  homepage:
378
400
  licenses: []
379
401
  metadata: {}
@@ -392,7 +414,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
392
414
  - !ruby/object:Gem::Version
393
415
  version: '0'
394
416
  requirements: []
395
- rubygems_version: 3.4.6
417
+ rubygems_version: 3.4.10
396
418
  signing_key:
397
419
  specification_version: 4
398
420
  summary: An operations service layer for rails projects.
@@ -410,9 +432,11 @@ test_files:
410
432
  - test/dummy/app/channels/application_cable/connection.rb
411
433
  - test/dummy/app/controllers/application_controller.rb
412
434
  - test/dummy/app/controllers/concerns/.keep
435
+ - test/dummy/app/controllers/group_controller.rb
413
436
  - test/dummy/app/helpers/application_helper.rb
414
437
  - test/dummy/app/jobs/application_job.rb
415
438
  - test/dummy/app/mailers/application_mailer.rb
439
+ - test/dummy/app/models/ability.rb
416
440
  - test/dummy/app/models/animal.rb
417
441
  - test/dummy/app/models/application_record.rb
418
442
  - test/dummy/app/models/bird.rb
@@ -445,6 +469,7 @@ test_files:
445
469
  - test/dummy/config/environments/development.rb
446
470
  - test/dummy/config/environments/production.rb
447
471
  - test/dummy/config/environments/test.rb
472
+ - test/dummy/config/hookup.rb
448
473
  - test/dummy/config/initializers/application_controller_renderer.rb
449
474
  - test/dummy/config/initializers/assets.rb
450
475
  - test/dummy/config/initializers/backtrace_silencers.rb
@@ -472,14 +497,19 @@ test_files:
472
497
  - test/dummy/tmp/.keep
473
498
  - test/test_helper.rb
474
499
  - test/unit/rails_ops/generators/operation_generator_test.rb
500
+ - test/unit/rails_ops/hookup_test.rb
501
+ - test/unit/rails_ops/mixins/controller_test.rb
475
502
  - test/unit/rails_ops/mixins/model/deep_nesting_test.rb
503
+ - test/unit/rails_ops/mixins/model/marshalling_test.rb
476
504
  - test/unit/rails_ops/mixins/param_authorization_test.rb
477
505
  - test/unit/rails_ops/mixins/policies_test.rb
506
+ - test/unit/rails_ops/operation/auth_test.rb
478
507
  - test/unit/rails_ops/operation/model/create_test.rb
508
+ - test/unit/rails_ops/operation/model/destroy_test.rb
479
509
  - test/unit/rails_ops/operation/model/load_test.rb
480
510
  - test/unit/rails_ops/operation/model/sti_test.rb
481
511
  - test/unit/rails_ops/operation/model/update_test.rb
482
512
  - test/unit/rails_ops/operation/model_test.rb
483
- - test/unit/rails_ops/operation/update_auth_test.rb
484
513
  - test/unit/rails_ops/operation/update_lazy_auth_test.rb
485
514
  - test/unit/rails_ops/operation_test.rb
515
+ - test/unit/rails_ops/profiler_test.rb
@@ -1,64 +0,0 @@
1
- require 'test_helper'
2
- require 'rails_ops/authorization_backend/can_can_can'
3
- require 'cancancan'
4
-
5
- class RailsOps::Operation::UpdateLazyAuthTest < ActiveSupport::TestCase
6
- include TestHelper
7
-
8
- BASIC_OP = Class.new(RailsOps::Operation::Model::Update) do
9
- model ::Group
10
-
11
- model_authorization_action :update
12
-
13
- def perform
14
- fail osparams.exception if osparams.exception
15
- @done = true
16
- end
17
- end
18
-
19
- ABILITY = Class.new do
20
- include CanCan::Ability
21
-
22
- def initialize(read: false, update: false)
23
- super()
24
-
25
- can :read, Group if read
26
- can :update, Group if update
27
- end
28
- end
29
-
30
- setup do
31
- Group.create!(id: 1, name: 'Group')
32
- RailsOps.config.authorization_backend = 'RailsOps::AuthorizationBackend::CanCanCan'
33
- end
34
-
35
- def test_unpermitted_read
36
- ctx = RailsOps::Context.new(ability: ABILITY.new(read: true))
37
- assert_raises CanCan::AccessDenied do
38
- BASIC_OP.new(ctx, id: 1)
39
- end
40
- end
41
-
42
- def test_permitted_read
43
- ctx = RailsOps::Context.new(ability: ABILITY.new(read: true))
44
- assert_nothing_raised do
45
- BASIC_OP.new(ctx, id: 1)
46
- end
47
- end
48
-
49
- def test_unpermitted_update
50
- ctx = RailsOps::Context.new(ability: ABILITY.new(read: true))
51
- op = BASIC_OP.new(ctx, id: 1)
52
- assert_raises CanCan::AccessDenied do
53
- op.run!
54
- end
55
- end
56
-
57
- def test_permitted_update
58
- ctx = RailsOps::Context.new(ability: ABILITY.new(read: true, update: true))
59
- op = BASIC_OP.new(ctx, id: 1)
60
- assert_nothing_raised do
61
- op.run!
62
- end
63
- end
64
- end