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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +17 -2
- data/README.md +12 -2
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/lib/generators/operation/operation_generator.rb +54 -7
- data/lib/generators/operation/templates/controller.erb +34 -23
- data/lib/generators/operation/templates/controller_wrapper.erb +14 -0
- data/lib/rails_ops/hookup/dsl_validator.rb +1 -1
- data/lib/rails_ops/hookup.rb +1 -1
- data/lib/rails_ops/mixins/sub_ops.rb +2 -0
- data/lib/rails_ops/operation.rb +1 -1
- data/rails_ops.gemspec +6 -5
- data/test/dummy/app/controllers/group_controller.rb +28 -0
- data/test/dummy/app/models/ability.rb +7 -0
- data/test/dummy/app/models/animal.rb +5 -1
- data/test/dummy/app/models/bird.rb +3 -1
- data/test/dummy/app/models/phoenix.rb +3 -1
- data/test/dummy/config/environments/development.rb +2 -0
- data/test/dummy/config/environments/production.rb +2 -0
- data/test/dummy/config/hookup.rb +5 -0
- data/test/dummy/config/routes.rb +1 -0
- data/test/test_helper.rb +5 -0
- data/test/unit/rails_ops/generators/operation_generator_test.rb +98 -0
- data/test/unit/rails_ops/hookup_test.rb +82 -0
- data/test/unit/rails_ops/mixins/controller_test.rb +21 -0
- data/test/unit/rails_ops/mixins/model/deep_nesting_test.rb +62 -2
- data/test/unit/rails_ops/mixins/model/marshalling_test.rb +36 -0
- data/test/unit/rails_ops/operation/auth_test.rb +120 -0
- data/test/unit/rails_ops/operation/model/destroy_test.rb +31 -0
- data/test/unit/rails_ops/operation/model/load_test.rb +9 -0
- data/test/unit/rails_ops/operation/model_test.rb +24 -0
- data/test/unit/rails_ops/operation_test.rb +121 -0
- data/test/unit/rails_ops/profiler_test.rb +11 -0
- metadata +36 -5
- 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
|
-
|
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
|