rails_ops 1.4.2 → 1.4.4

Sign up to get free protection for your applications and to get access to all the features.
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