rails_ops 1.4.2 → 1.4.4

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +17 -2
  4. data/README.md +12 -2
  5. data/Rakefile +1 -0
  6. data/VERSION +1 -1
  7. data/lib/generators/operation/operation_generator.rb +54 -7
  8. data/lib/generators/operation/templates/controller.erb +34 -23
  9. data/lib/generators/operation/templates/controller_wrapper.erb +14 -0
  10. data/lib/rails_ops/hookup/dsl_validator.rb +1 -1
  11. data/lib/rails_ops/hookup.rb +1 -1
  12. data/lib/rails_ops/mixins/sub_ops.rb +2 -0
  13. data/lib/rails_ops/operation.rb +1 -1
  14. data/rails_ops.gemspec +6 -5
  15. data/test/dummy/app/controllers/group_controller.rb +28 -0
  16. data/test/dummy/app/models/ability.rb +7 -0
  17. data/test/dummy/app/models/animal.rb +5 -1
  18. data/test/dummy/app/models/bird.rb +3 -1
  19. data/test/dummy/app/models/phoenix.rb +3 -1
  20. data/test/dummy/config/environments/development.rb +2 -0
  21. data/test/dummy/config/environments/production.rb +2 -0
  22. data/test/dummy/config/hookup.rb +5 -0
  23. data/test/dummy/config/routes.rb +1 -0
  24. data/test/test_helper.rb +5 -0
  25. data/test/unit/rails_ops/generators/operation_generator_test.rb +98 -0
  26. data/test/unit/rails_ops/hookup_test.rb +82 -0
  27. data/test/unit/rails_ops/mixins/controller_test.rb +21 -0
  28. data/test/unit/rails_ops/mixins/model/deep_nesting_test.rb +62 -2
  29. data/test/unit/rails_ops/mixins/model/marshalling_test.rb +36 -0
  30. data/test/unit/rails_ops/operation/auth_test.rb +120 -0
  31. data/test/unit/rails_ops/operation/model/destroy_test.rb +31 -0
  32. data/test/unit/rails_ops/operation/model/load_test.rb +9 -0
  33. data/test/unit/rails_ops/operation/model_test.rb +24 -0
  34. data/test/unit/rails_ops/operation_test.rb +121 -0
  35. data/test/unit/rails_ops/profiler_test.rb +11 -0
  36. metadata +36 -5
  37. data/test/unit/rails_ops/operation/update_auth_test.rb +0 -64
@@ -32,6 +32,104 @@ class OperationGeneratorTest < Rails::Generators::TestCase
32
32
  assert_routes
33
33
  end
34
34
 
35
+ def test_no_index_action
36
+ run_generator ['User', '--skip-index']
37
+
38
+ # Check that the index view is not created
39
+ assert_no_file 'app/views/users/index.html.haml'
40
+
41
+ # Check that the index route is not created
42
+ assert_file 'config/routes.rb' do |routes|
43
+ assert_match(/resources :users, except: \[:index\]/, routes)
44
+ end
45
+
46
+ # Check that the controller action is not created
47
+ assert_file 'app/controllers/users_controller.rb' do |controller|
48
+ assert_no_match(/def index/, controller)
49
+ end
50
+ end
51
+
52
+ def test_no_show_action
53
+ run_generator ['User', '--skip-show']
54
+
55
+ # Check that the show view is not created
56
+ assert_no_file 'app/views/users/show.html.haml'
57
+
58
+ # Check that the show route is not created
59
+ assert_file 'config/routes.rb' do |routes|
60
+ assert_match(/resources :users, except: \[:show\]/, routes)
61
+ end
62
+
63
+ # Check that the controller action is not created
64
+ assert_file 'app/controllers/users_controller.rb' do |controller|
65
+ assert_no_match(/def show/, controller)
66
+ end
67
+
68
+ # Check that the load operation is not created
69
+ assert_no_file 'app/operations/users/load.rb'
70
+ end
71
+
72
+ def test_no_create_action
73
+ run_generator ['User', '--skip-create']
74
+
75
+ # Check that the new and create view are not created
76
+ assert_no_file 'app/views/users/new.html.haml'
77
+ assert_no_file 'app/views/users/create.html.haml'
78
+
79
+ # Check that the new, create route is not created
80
+ assert_file 'config/routes.rb' do |routes|
81
+ assert_match(/resources :users, except: \[:new, :create\]/, routes)
82
+ end
83
+
84
+ # Check that the controller actions are not created
85
+ assert_file 'app/controllers/users_controller.rb' do |controller|
86
+ assert_no_match(/def new/, controller)
87
+ assert_no_match(/def create/, controller)
88
+ end
89
+
90
+ # Check that the load operation is not created
91
+ assert_no_file 'app/operations/users/create.rb'
92
+ end
93
+
94
+ def test_no_update_action
95
+ run_generator ['User', '--skip-update']
96
+
97
+ # Check that the edit and update view are not created
98
+ assert_no_file 'app/views/users/edit.html.haml'
99
+ assert_no_file 'app/views/users/update.html.haml'
100
+
101
+ # Check that the edit, update route is not created
102
+ assert_file 'config/routes.rb' do |routes|
103
+ assert_match(/resources :users, except: \[:edit, :update\]/, routes)
104
+ end
105
+
106
+ # Check that the controller actions are not created
107
+ assert_file 'app/controllers/users_controller.rb' do |controller|
108
+ assert_no_match(/def edit/, controller)
109
+ assert_no_match(/def update/, controller)
110
+ end
111
+
112
+ # Check that the load operation is not created
113
+ assert_no_file 'app/operations/users/update.rb'
114
+ end
115
+
116
+ def test_no_destory_action
117
+ run_generator ['User', '--skip-destroy']
118
+
119
+ # Check that the destroy view is not created
120
+ assert_no_file 'app/views/users/destroy.html.haml'
121
+
122
+ # Check that the destroy route is not created
123
+ assert_file 'config/routes.rb' do |routes|
124
+ assert_match(/resources :users, except: \[:destroy\]/, routes)
125
+ end
126
+
127
+ # Check that the controller action is not created
128
+ assert_file 'app/controllers/users_controller.rb' do |controller|
129
+ assert_no_match(/def destroy/, controller)
130
+ end
131
+ end
132
+
35
133
  def test_no_views
36
134
  run_generator ['User', '--skip-views']
37
135
 
@@ -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