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.
- 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
|