approval_cycle 0.1.0.pre → 0.1.1.pre
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/README.md +35 -15
- data/app/models/approval_cycle/setup.rb +6 -3
- data/app/models/concerns/approval_cycle/approvable.rb +5 -5
- data/app/models/concerns/enums/approval_cycle/approval.rb +9 -1
- data/db/migrate/20240723091231_create_approval_cycle_setups.rb +3 -3
- data/lib/approval_cycle/configuration.rb +16 -1
- data/lib/approval_cycle/version.rb +1 -1
- data/lib/generators/approval_cycle/install/templates/approval_cycle.rb +13 -1
- data/lib/generators/approval_cycle/setup_types_generator.rb +49 -5
- data/lib/tasks/approval_cycle_tasks.rake +17 -17
- data/spec/dummy/app/models/dummy_request.rb +1 -0
- data/spec/dummy/config/initializers/approval_cycle.rb +24 -1
- data/spec/dummy/db/migrate/{20250731094005_create_approval_cycle_setups.rb → 20250731123034_create_approval_cycle_setups.rb} +3 -3
- data/spec/dummy/db/schema.rb +4 -5
- data/spec/dummy/log/development.log +121 -0
- data/spec/dummy/log/test.log +55486 -0
- data/spec/features/configurable_approval_statuses_demo_spec.rb +76 -0
- data/spec/lib/approval_cycle/configuration_spec.rb +81 -0
- data/spec/models/approval_cycle/approval_spec.rb +38 -9
- data/spec/models/approval_cycle/setup_spec.rb +2 -0
- data/spec/services/approval_cycle/setup_updater_spec.rb +5 -3
- metadata +19 -18
- data/db/migrate/20240723091230_enable_pg_trgm_extention.rb +0 -9
- data/spec/dummy/db/migrate/20250731094004_enable_pg_trgm_extention.rb +0 -9
- /data/spec/dummy/db/migrate/{20250731094006_create_approval_cycle_approvers.rb → 20250731123035_create_approval_cycle_approvers.rb} +0 -0
- /data/spec/dummy/db/migrate/{20250731094007_create_approval_cycle_watchers.rb → 20250731123036_create_approval_cycle_watchers.rb} +0 -0
- /data/spec/dummy/db/migrate/{20250731094008_create_approval_cycle_action_takers.rb → 20250731123037_create_approval_cycle_action_takers.rb} +0 -0
- /data/spec/dummy/db/migrate/{20250731094009_create_approval_cycle_object_activities.rb → 20250731123038_create_approval_cycle_object_activities.rb} +0 -0
- /data/spec/dummy/db/migrate/{20250731094010_create_approval_cycle_approvals.rb → 20250731123039_create_approval_cycle_approvals.rb} +0 -0
- /data/spec/dummy/db/migrate/{20250731094101_add_approval_cycle_to_configured_types.rb → 20250731123227_add_approval_cycle_to_configured_types.rb} +0 -0
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
# Demonstration of configurable approval statuses
|
4
|
+
RSpec.describe 'Configurable Approval Statuses Demo', type: :model do
|
5
|
+
describe 'Configured approval statuses' do
|
6
|
+
it 'uses the configured custom statuses for dummy_request' do
|
7
|
+
# Since we have custom statuses configured in the dummy app initializer
|
8
|
+
expected_statuses = %w[pending approved rejected cancelled on_hold auto_approved skipped_after_rejection skipped_after_withdrawal]
|
9
|
+
actual_statuses = ApprovalCycle::Approval.statuses.keys
|
10
|
+
|
11
|
+
expect(actual_statuses).to match_array(expected_statuses)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'Custom approval statuses configuration' do
|
16
|
+
it 'allows configuration to be set' do
|
17
|
+
# This demonstrates how a user would configure custom statuses for dummy_request
|
18
|
+
custom_config = ApprovalCycle::Configuration.new
|
19
|
+
custom_config.approval_statuses = {
|
20
|
+
pending: 'pending',
|
21
|
+
approved: 'approved',
|
22
|
+
rejected: 'rejected',
|
23
|
+
cancelled: 'cancelled',
|
24
|
+
on_hold: 'on_hold'
|
25
|
+
}
|
26
|
+
|
27
|
+
expect(custom_config.approval_statuses.keys).to contain_exactly(
|
28
|
+
:pending, :approved, :rejected, :cancelled, :on_hold
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'provides access to custom statuses via configuration for dummy_request' do
|
33
|
+
# This shows how the enum accesses the configuration for dummy_request workflow
|
34
|
+
ApprovalCycle.configure do |config|
|
35
|
+
config.approval_cycle_setup_types = { dummy_request: 0 }
|
36
|
+
config.approval_statuses = {
|
37
|
+
pending: 'pending',
|
38
|
+
approved: 'approved',
|
39
|
+
rejected: 'rejected',
|
40
|
+
cancelled: 'cancelled',
|
41
|
+
on_hold: 'on_hold'
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
# The configuration is available and can be accessed
|
46
|
+
expect(ApprovalCycle.configuration.approval_statuses).to include(
|
47
|
+
pending: 'pending',
|
48
|
+
approved: 'approved',
|
49
|
+
rejected: 'rejected',
|
50
|
+
cancelled: 'cancelled',
|
51
|
+
on_hold: 'on_hold'
|
52
|
+
)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe 'Fallback behavior' do
|
57
|
+
it 'uses fallback statuses when configuration is nil' do
|
58
|
+
# Simulate the enum fallback behavior
|
59
|
+
config_statuses = nil
|
60
|
+
fallback_statuses = {
|
61
|
+
pending: 'pending',
|
62
|
+
rejected: 'rejected',
|
63
|
+
approved: 'approved',
|
64
|
+
skipped: 'skipped',
|
65
|
+
auto_approved: 'auto_approved',
|
66
|
+
skipped_after_rejection: 'skipped_after_rejection',
|
67
|
+
skipped_after_withdrawal: 'skipped_after_withdrawal'
|
68
|
+
}
|
69
|
+
|
70
|
+
# This is what happens in the enum definition
|
71
|
+
used_statuses = config_statuses || fallback_statuses
|
72
|
+
|
73
|
+
expect(used_statuses).to eq(fallback_statuses)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
module ApprovalCycle
|
4
|
+
RSpec.describe Configuration do
|
5
|
+
let(:config) { Configuration.new }
|
6
|
+
|
7
|
+
describe '#approval_statuses' do
|
8
|
+
it 'has default approval statuses' do
|
9
|
+
expect(config.approval_statuses).to eq({
|
10
|
+
pending: 'pending',
|
11
|
+
rejected: 'rejected',
|
12
|
+
approved: 'approved',
|
13
|
+
skipped: 'skipped',
|
14
|
+
auto_approved: 'auto_approved',
|
15
|
+
skipped_after_rejection: 'skipped_after_rejection',
|
16
|
+
skipped_after_withdrawal: 'skipped_after_withdrawal'
|
17
|
+
})
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'allows custom approval statuses to be set' do
|
21
|
+
custom_statuses = {
|
22
|
+
pending: 'pending',
|
23
|
+
approved: 'approved',
|
24
|
+
rejected: 'rejected',
|
25
|
+
cancelled: 'cancelled'
|
26
|
+
}
|
27
|
+
|
28
|
+
config.approval_statuses = custom_statuses
|
29
|
+
expect(config.approval_statuses).to eq(custom_statuses)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#approval_cycle_setup_types' do
|
34
|
+
it 'starts with empty setup types' do
|
35
|
+
expect(config.approval_cycle_setup_types).to eq({})
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'allows setup types to be set' do
|
39
|
+
setup_types = { dummy_request: 0 }
|
40
|
+
config.approval_cycle_setup_types = setup_types
|
41
|
+
expect(config.approval_cycle_setup_types).to eq(setup_types)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
RSpec.describe 'ApprovalCycle.configure' do
|
47
|
+
around do |example|
|
48
|
+
original_config = ApprovalCycle.configuration
|
49
|
+
example.run
|
50
|
+
ApprovalCycle.configuration = original_config
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'allows configuration of approval statuses' do
|
54
|
+
ApprovalCycle.configure do |config|
|
55
|
+
config.approval_statuses = {
|
56
|
+
pending: 'pending',
|
57
|
+
approved: 'approved',
|
58
|
+
rejected: 'rejected',
|
59
|
+
cancelled: 'cancelled'
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
expect(ApprovalCycle.configuration.approval_statuses).to eq({
|
64
|
+
pending: 'pending',
|
65
|
+
approved: 'approved',
|
66
|
+
rejected: 'rejected',
|
67
|
+
cancelled: 'cancelled'
|
68
|
+
})
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'allows configuration of setup types' do
|
72
|
+
ApprovalCycle.configure do |config|
|
73
|
+
config.approval_cycle_setup_types = { dummy_request: 0 }
|
74
|
+
end
|
75
|
+
|
76
|
+
expect(ApprovalCycle.configuration.approval_cycle_setup_types).to eq({
|
77
|
+
dummy_request: 0
|
78
|
+
})
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -10,8 +10,8 @@ module ApprovalCycle
|
|
10
10
|
let(:fourth_user) { users.fourth }
|
11
11
|
let(:user) { create(:dummy_user) }
|
12
12
|
let(:approver) { create(:approver, user_id: user.id, user_type: 'DummyUser', approval_cycle_setup: setup, order: 10) }
|
13
|
-
let(:approvers) { [
|
14
|
-
let(:setup) { create(:setup, level: company, approval_cycle_setup_type: :dummy_request, modifier: user, approval_cycle_approvers_attributes: approvers, approval_cycle_watchers_attributes: [
|
13
|
+
let(:approvers) { [{ user_id: first_user.id, order: 0, user_type: 'DummyUser' }, { user_id: second_user.id, order: 1, user_type: 'DummyUser' }, { user_id: third_user.id, order: 2, user_type: 'DummyUser' }] }
|
14
|
+
let(:setup) { create(:setup, level: company, approval_cycle_setup_type: :dummy_request, modifier: user, approval_cycle_approvers_attributes: approvers, approval_cycle_watchers_attributes: [{ user_id: user.id, user_type: 'DummyUser', action: 'both' }], approval_cycle_action_takers_attributes: [{ user_id: user.id, user_type: 'DummyUser' }]) }
|
15
15
|
let(:second_setup) { create(:setup, level: company, modifier: user, approval_cycle_setup_type: :dummy_request) }
|
16
16
|
let(:dummy_request) { create(:dummy_request, approval_cycle_setup: setup, approval_cycle_status: :pending, modifier: user) }
|
17
17
|
let(:subject) { create(:approval, approval_cycle_approver: approver, approvable: dummy_request) }
|
@@ -28,7 +28,36 @@ module ApprovalCycle
|
|
28
28
|
end
|
29
29
|
|
30
30
|
describe 'Enums' do
|
31
|
-
it { should define_enum_for(:status).with_values({ pending: 'pending', rejected: 'rejected',
|
31
|
+
it { should define_enum_for(:status).with_values({ pending: 'pending', approved: 'approved', rejected: 'rejected', cancelled: 'cancelled', on_hold: 'on_hold', auto_approved: 'auto_approved', skipped_after_rejection: 'skipped_after_rejection', skipped_after_withdrawal: 'skipped_after_withdrawal' }).backed_by_column_of_type(:string).with_prefix(true) }
|
32
|
+
|
33
|
+
context 'with custom approval statuses' do
|
34
|
+
around do |example|
|
35
|
+
original_config = ApprovalCycle.configuration
|
36
|
+
ApprovalCycle.configuration = ApprovalCycle::Configuration.new
|
37
|
+
ApprovalCycle.configure do |config|
|
38
|
+
config.approval_cycle_setup_types = { dummy_request: 0 }
|
39
|
+
config.approval_statuses = {
|
40
|
+
pending: 'pending',
|
41
|
+
approved: 'approved',
|
42
|
+
rejected: 'rejected',
|
43
|
+
cancelled: 'cancelled'
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
example.run
|
48
|
+
|
49
|
+
ApprovalCycle.configuration = original_config
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'allows custom statuses to be configured' do
|
53
|
+
expect(ApprovalCycle.configuration.approval_statuses).to eq({
|
54
|
+
pending: 'pending',
|
55
|
+
approved: 'approved',
|
56
|
+
rejected: 'rejected',
|
57
|
+
cancelled: 'cancelled'
|
58
|
+
})
|
59
|
+
end
|
60
|
+
end
|
32
61
|
end
|
33
62
|
|
34
63
|
describe '#update_next_approval_received_at' do
|
@@ -69,7 +98,7 @@ module ApprovalCycle
|
|
69
98
|
context 'when current approval is first approval' do
|
70
99
|
it 'does not update next approval received_at' do
|
71
100
|
expect(current_approval.count).to eq(1)
|
72
|
-
expect(current_approval.pluck(:status)).to eq([
|
101
|
+
expect(current_approval.pluck(:status)).to eq(['rejected'])
|
73
102
|
end
|
74
103
|
end
|
75
104
|
end
|
@@ -89,7 +118,7 @@ module ApprovalCycle
|
|
89
118
|
end
|
90
119
|
|
91
120
|
it 'creates all other approvals with NIL received_at and status' do
|
92
|
-
expect(Approval.last(2).pluck(:approval_cycle_approver_id, :received_at, :status)).to match_array(awaiting_approvals.map { |approver| [
|
121
|
+
expect(Approval.last(2).pluck(:approval_cycle_approver_id, :received_at, :status)).to match_array(awaiting_approvals.map { |approver| [approver.id, nil, 'pending'] })
|
93
122
|
end
|
94
123
|
end
|
95
124
|
end
|
@@ -100,7 +129,7 @@ module ApprovalCycle
|
|
100
129
|
|
101
130
|
context 'when created_by is approver' do
|
102
131
|
context 'when approver is first and only approver' do
|
103
|
-
let(:approvers) { [
|
132
|
+
let(:approvers) { [{ user_id: user.id, order: 0, user_type: 'DummyUser' }] }
|
104
133
|
|
105
134
|
it 'approves request' do
|
106
135
|
expect(request_status).to eq('approved')
|
@@ -109,7 +138,7 @@ module ApprovalCycle
|
|
109
138
|
end
|
110
139
|
|
111
140
|
context 'when approver is last approver' do
|
112
|
-
let(:approvers) { [
|
141
|
+
let(:approvers) { [{ user_id: first_user.id, order: 0, user_type: 'DummyUser' }, { user_id: user.id, order: 1, user_type: 'DummyUser' }] }
|
113
142
|
|
114
143
|
before { Approval.first.approve! }
|
115
144
|
|
@@ -120,7 +149,7 @@ module ApprovalCycle
|
|
120
149
|
end
|
121
150
|
|
122
151
|
context 'when approver is not last approver' do
|
123
|
-
let(:approvers) { [
|
152
|
+
let(:approvers) { [{ user_id: first_user.id, order: 0, user_type: 'DummyUser' }, { user_id: user.id, order: 1, user_type: 'DummyUser' }, { user_id: third_user.id, order: 2, user_type: 'DummyUser' }] }
|
124
153
|
|
125
154
|
before { Approval.first.approve! }
|
126
155
|
|
@@ -133,7 +162,7 @@ module ApprovalCycle
|
|
133
162
|
end
|
134
163
|
|
135
164
|
context 'when created_by is not approver' do
|
136
|
-
let(:approvers) { [
|
165
|
+
let(:approvers) { [{ user_id: first_user.id, order: 0, user_type: 'DummyUser' }] }
|
137
166
|
|
138
167
|
it 'does not auto approve' do
|
139
168
|
expect(request_status).to eq('pending')
|
@@ -1,6 +1,8 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
1
3
|
module ApprovalCycle
|
2
|
-
RSpec.describe SetupUpdater, type: :service do
|
3
|
-
describe '#call' do
|
4
|
+
RSpec.describe SetupUpdater, type: :service do # rubocop:disable Metrics/BlockLength
|
5
|
+
describe '#call' do # rubocop:disable Metrics/BlockLength
|
4
6
|
let(:company) { create(:company) }
|
5
7
|
let(:user) { create(:dummy_user) }
|
6
8
|
let(:setup_attrs) { { approval_cycle_approvers_attributes: [ { user_id: user.id, order: 0, user_type: 'DummyUser' } ], approval_cycle_watchers_attributes: [ { user_id: user.id, action: 'both', user_type: 'DummyUser' } ], approval_cycle_action_takers_attributes: [ { user_id: user.id, user_type: 'DummyUser' } ] } }
|
@@ -14,7 +16,7 @@ module ApprovalCycle
|
|
14
16
|
|
15
17
|
before { dummy_request }
|
16
18
|
|
17
|
-
context 'with valid params' do
|
19
|
+
context 'with valid params' do # rubocop:disable Metrics/BlockLength
|
18
20
|
context 'when apply_to_versions is false' do
|
19
21
|
let(:params) { update_params }
|
20
22
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: approval_cycle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Farah Assaf
|
@@ -163,7 +163,6 @@ files:
|
|
163
163
|
- app/services/approval_cycle/setup_updater.rb
|
164
164
|
- app/views/layouts/approval_cycle/application.html.erb
|
165
165
|
- config/routes.rb
|
166
|
-
- db/migrate/20240723091230_enable_pg_trgm_extention.rb
|
167
166
|
- db/migrate/20240723091231_create_approval_cycle_setups.rb
|
168
167
|
- db/migrate/20240723142036_create_approval_cycle_approvers.rb
|
169
168
|
- db/migrate/20240806080650_create_approval_cycle_watchers.rb
|
@@ -222,14 +221,13 @@ files:
|
|
222
221
|
- spec/dummy/db/migrate/20241028115559_create_companies.rb
|
223
222
|
- spec/dummy/db/migrate/20241028115633_create_dummy_users.rb
|
224
223
|
- spec/dummy/db/migrate/20241030055459_create_dummy_requests.rb
|
225
|
-
- spec/dummy/db/migrate/
|
226
|
-
- spec/dummy/db/migrate/
|
227
|
-
- spec/dummy/db/migrate/
|
228
|
-
- spec/dummy/db/migrate/
|
229
|
-
- spec/dummy/db/migrate/
|
230
|
-
- spec/dummy/db/migrate/
|
231
|
-
- spec/dummy/db/migrate/
|
232
|
-
- spec/dummy/db/migrate/20250731094101_add_approval_cycle_to_configured_types.rb
|
224
|
+
- spec/dummy/db/migrate/20250731123034_create_approval_cycle_setups.rb
|
225
|
+
- spec/dummy/db/migrate/20250731123035_create_approval_cycle_approvers.rb
|
226
|
+
- spec/dummy/db/migrate/20250731123036_create_approval_cycle_watchers.rb
|
227
|
+
- spec/dummy/db/migrate/20250731123037_create_approval_cycle_action_takers.rb
|
228
|
+
- spec/dummy/db/migrate/20250731123038_create_approval_cycle_object_activities.rb
|
229
|
+
- spec/dummy/db/migrate/20250731123039_create_approval_cycle_approvals.rb
|
230
|
+
- spec/dummy/db/migrate/20250731123227_add_approval_cycle_to_configured_types.rb
|
233
231
|
- spec/dummy/db/schema.rb
|
234
232
|
- spec/dummy/log/development.log
|
235
233
|
- spec/dummy/log/teast.log
|
@@ -252,6 +250,8 @@ files:
|
|
252
250
|
- spec/factories/dummy_users.rb
|
253
251
|
- spec/factories/setups.rb
|
254
252
|
- spec/factories/watchers.rb
|
253
|
+
- spec/features/configurable_approval_statuses_demo_spec.rb
|
254
|
+
- spec/lib/approval_cycle/configuration_spec.rb
|
255
255
|
- spec/models/approval_cycle/action_taker_spec.rb
|
256
256
|
- spec/models/approval_cycle/approval_spec.rb
|
257
257
|
- spec/models/approval_cycle/approver_spec.rb
|
@@ -334,14 +334,13 @@ test_files:
|
|
334
334
|
- spec/dummy/db/migrate/20241028115559_create_companies.rb
|
335
335
|
- spec/dummy/db/migrate/20241028115633_create_dummy_users.rb
|
336
336
|
- spec/dummy/db/migrate/20241030055459_create_dummy_requests.rb
|
337
|
-
- spec/dummy/db/migrate/
|
338
|
-
- spec/dummy/db/migrate/
|
339
|
-
- spec/dummy/db/migrate/
|
340
|
-
- spec/dummy/db/migrate/
|
341
|
-
- spec/dummy/db/migrate/
|
342
|
-
- spec/dummy/db/migrate/
|
343
|
-
- spec/dummy/db/migrate/
|
344
|
-
- spec/dummy/db/migrate/20250731094101_add_approval_cycle_to_configured_types.rb
|
337
|
+
- spec/dummy/db/migrate/20250731123034_create_approval_cycle_setups.rb
|
338
|
+
- spec/dummy/db/migrate/20250731123035_create_approval_cycle_approvers.rb
|
339
|
+
- spec/dummy/db/migrate/20250731123036_create_approval_cycle_watchers.rb
|
340
|
+
- spec/dummy/db/migrate/20250731123037_create_approval_cycle_action_takers.rb
|
341
|
+
- spec/dummy/db/migrate/20250731123038_create_approval_cycle_object_activities.rb
|
342
|
+
- spec/dummy/db/migrate/20250731123039_create_approval_cycle_approvals.rb
|
343
|
+
- spec/dummy/db/migrate/20250731123227_add_approval_cycle_to_configured_types.rb
|
345
344
|
- spec/dummy/db/schema.rb
|
346
345
|
- spec/dummy/log/development.log
|
347
346
|
- spec/dummy/log/teast.log
|
@@ -364,6 +363,8 @@ test_files:
|
|
364
363
|
- spec/factories/dummy_users.rb
|
365
364
|
- spec/factories/setups.rb
|
366
365
|
- spec/factories/watchers.rb
|
366
|
+
- spec/features/configurable_approval_statuses_demo_spec.rb
|
367
|
+
- spec/lib/approval_cycle/configuration_spec.rb
|
367
368
|
- spec/models/approval_cycle/action_taker_spec.rb
|
368
369
|
- spec/models/approval_cycle/approval_spec.rb
|
369
370
|
- spec/models/approval_cycle/approver_spec.rb
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|