Skip to content

Commit 4344e83

Browse files
authored
Merge pull request #17 from dxw/11-trigger-levy-when-validations-complete
(11) Trigger levy calculation when validations complete (and transition errored to in_review)
2 parents 9ae69d7 + 668685c commit 4344e83

8 files changed

Lines changed: 174 additions & 5 deletions

File tree

Gemfile.lock

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ GEM
258258

259259
PLATFORMS
260260
ruby
261+
x86_64-darwin-17
261262

262263
DEPENDENCIES
263264
aasm
@@ -289,4 +290,4 @@ RUBY VERSION
289290
ruby 2.5.1p57
290291

291292
BUNDLED WITH
292-
1.16.2
293+
1.16.3

app/controllers/v1/submission_entries_controller.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ def update
1818
submission_file = SubmissionFile.find(params[:file_id])
1919
entry = submission_file.entries.find(params[:id])
2020
entry.aasm.current_state = submission_entry_params[:status]
21-
entry.validation_errors = submission_entry_params[:validation_errors] if submission_entry_params[:validation_errors]
21+
entry.validation_errors = submission_entry_params[:validation_errors]
2222

2323
if entry.save
24+
submission_status_update!(submission_file.submission)
2425
head :no_content
2526
else
2627
render jsonapi_errors: entry.errors, status: :bad_request
@@ -36,6 +37,10 @@ def show
3637

3738
private
3839

40+
def submission_status_update!(submission)
41+
SubmissionStatusUpdate.new(submission).perform!
42+
end
43+
3944
def initialize_submission_entry
4045
if params[:file_id].present?
4146
file = SubmissionFile.find(params[:file_id])

app/models/submission.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,9 @@ class Submission < ApplicationRecord
1414
state :in_review
1515
state :completed
1616
state :rejected
17+
18+
event :ready_for_review do
19+
transitions from: %i[pending processing], to: :in_review
20+
end
1721
end
1822
end
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
class SubmissionStatusUpdate
2+
attr_reader :submission
3+
4+
def initialize(submission)
5+
@submission = submission
6+
end
7+
8+
def perform!
9+
return unless submission.entries.any?
10+
11+
trigger_levy_calculation if all_entries_valid?
12+
transition_to_in_review if no_entries_pending? && some_entries_errored?
13+
end
14+
15+
private
16+
17+
def all_entries_valid?
18+
submission.entries.validated.count == submission.entries.count
19+
end
20+
21+
def transition_to_in_review
22+
submission.ready_for_review!
23+
end
24+
25+
def no_entries_pending?
26+
submission.entries.pending.none?
27+
end
28+
29+
def some_entries_errored?
30+
submission.entries.errored.any?
31+
end
32+
33+
def trigger_levy_calculation
34+
AWSLambdaService.new(submission_id: submission.id).trigger
35+
end
36+
end

spec/factories/submission.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,26 @@
33
framework
44
supplier
55
task
6+
7+
factory :submission_with_pending_entries do
8+
after(:create) do |submission, _evaluator|
9+
create_list(:submission_entry, 3, submission: submission)
10+
end
11+
end
12+
13+
factory :submission_with_validated_entries do
14+
after(:create) do |submission, _evaluator|
15+
create_list(:validated_submission_entry, 3, submission: submission)
16+
end
17+
end
18+
19+
factory :submission_with_invalid_entries do
20+
aasm_state :in_review
21+
22+
after(:create) do |submission, _evaluator|
23+
create_list(:validated_submission_entry, 2, submission: submission)
24+
create_list(:errored_submission_entry, 1, submission: submission)
25+
end
26+
end
627
end
728
end

spec/factories/submission_entry.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,15 @@
22
factory :submission_entry do
33
submission
44
submission_file
5-
data {}
6-
source {}
5+
data(test_key: 'some data')
6+
source(sheet: 'InvoicesReceived', row: 1)
7+
8+
factory :validated_submission_entry do
9+
aasm_state :validated
10+
end
11+
12+
factory :errored_submission_entry do
13+
aasm_state :errored
14+
end
715
end
816
end
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
require 'rails_helper'
2+
3+
RSpec.describe SubmissionStatusUpdate do
4+
describe '#perform' do
5+
let(:aws_lambda_service_double) { double(trigger: true) }
6+
let(:submission_status_check) { SubmissionStatusUpdate.new(submission) }
7+
8+
before do
9+
allow(AWSLambdaService).to receive(:new).and_return(aws_lambda_service_double)
10+
end
11+
12+
context 'given a "processing" submission' do
13+
context 'with "pending" entries' do
14+
let(:submission) { FactoryBot.create(:submission_with_pending_entries, aasm_state: :processing) }
15+
16+
it 'leaves the submission in a "processing" state' do
17+
submission_status_check.perform!
18+
19+
expect(submission).to be_processing
20+
end
21+
22+
it 'does not trigger a levy calculation' do
23+
expect(aws_lambda_service_double).not_to receive(:trigger)
24+
25+
submission_status_check.perform!
26+
end
27+
end
28+
29+
context 'with all entries validated' do
30+
let(:submission) { FactoryBot.create(:submission_with_validated_entries, aasm_state: :processing) }
31+
32+
it 'leaves the submission in a "processing" state' do
33+
submission_status_check.perform!
34+
35+
expect(submission).to be_processing
36+
end
37+
38+
it 'triggers a levy calculation' do
39+
expect(aws_lambda_service_double).to receive(:trigger)
40+
41+
submission_status_check.perform!
42+
end
43+
end
44+
45+
context 'with some "pending" entries and some "errored" entries' do
46+
let(:submission) do
47+
FactoryBot.create(:submission_with_pending_entries, aasm_state: :processing).tap do |submission|
48+
create(:errored_submission_entry, submission: submission)
49+
end
50+
end
51+
52+
it 'leaves the submission in a "processing"' do
53+
submission_status_check.perform!
54+
55+
expect(submission).to be_processing
56+
end
57+
58+
it 'does not trigger a levy calculation' do
59+
expect(aws_lambda_service_double).not_to receive(:trigger)
60+
61+
submission_status_check.perform!
62+
end
63+
end
64+
65+
context 'with no "pending" entries remaining, but some having failed validation' do
66+
let(:submission) { FactoryBot.create(:submission_with_invalid_entries, aasm_state: :processing) }
67+
68+
it 'transitions the submission to "in_review"' do
69+
submission_status_check.perform!
70+
71+
expect(submission).to be_in_review
72+
end
73+
74+
it 'does not trigger a levy calculation' do
75+
expect(aws_lambda_service_double).not_to receive(:trigger)
76+
77+
submission_status_check.perform!
78+
end
79+
end
80+
end
81+
end
82+
end

spec/requests/v1/files_spec.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,15 @@
113113
'Accept': 'application/vnd.api+json'
114114
}
115115

116+
expect_submission_status_update_to_be_performed(file.submission)
117+
116118
patch "/v1/files/#{file.id}/entries/#{entry.id}", params: params.to_json, headers: headers
117119

118120
expect(response).to have_http_status(:no_content)
119121
expect(entry.reload).to be_validated
120122
end
121123

122-
it 'updates the given entry\'s validation errors received from DAVE' do
124+
it 'updates the given entry\'s validation errors received from DAVE and performs a status update' do
123125
file = FactoryBot.create(:submission_file)
124126
entry = FactoryBot.create(:submission_entry,
125127
submission_file: file,
@@ -145,6 +147,8 @@
145147
'Accept': 'application/vnd.api+json'
146148
}
147149

150+
expect_submission_status_update_to_be_performed(file.submission)
151+
148152
patch "/v1/files/#{file.id}/entries/#{entry.id}", params: params.to_json, headers: headers
149153

150154
expect(response).to have_http_status(:no_content)
@@ -179,11 +183,19 @@
179183
'Accept': 'application/vnd.api+json'
180184
}
181185

186+
expect_submission_status_update_to_be_performed(file.submission)
187+
182188
patch "/v1/files/#{file.id}/entries/#{entry.id}", params: params.to_json, headers: headers
183189

184190
expect(response).to have_http_status(:no_content)
185191
expect(entry.reload).to be_errored
186192
expect(entry.reload.validation_errors['message']).to eql 'Required value error'
187193
end
188194
end
195+
196+
def expect_submission_status_update_to_be_performed(submission)
197+
status_update_double = double
198+
expect(status_update_double).to receive(:perform!)
199+
expect(SubmissionStatusUpdate).to receive(:new).with(submission).and_return(status_update_double)
200+
end
189201
end

0 commit comments

Comments
 (0)