Skip to content

Commit 7e53d51

Browse files
authored
Merge pull request #19 from dxw/feature/233-user-can-complete-a-submission
(233) User can complete a submission
2 parents f56e9bc + 89c2b88 commit 7e53d51

9 files changed

Lines changed: 148 additions & 1 deletion

File tree

app/controllers/v1/submissions_controller.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,23 @@ def calculate
4545
head :no_content
4646
end
4747

48+
def complete
49+
submission = Submission.find(params[:id])
50+
complete_submission!(submission)
51+
52+
if submission.errors.empty?
53+
head :no_content
54+
else
55+
render jsonapi_errors: submission.errors, status: :bad_request
56+
end
57+
end
58+
4859
private
4960

61+
def complete_submission!(submission)
62+
SubmissionCompletion.new(submission).perform!
63+
end
64+
5065
def create_submission_params
5166
params.require(:submission).permit(:task_id)
5267
end

app/models/submission.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,17 @@ class Submission < ApplicationRecord
1818
event :ready_for_review do
1919
transitions from: %i[pending processing], to: :in_review
2020
end
21+
22+
event :reviewed_and_accepted do
23+
transitions from: :in_review, to: :completed, guard: :all_entries_valid?
24+
25+
error do |e|
26+
errors.add(:aasm_state, message: e.message)
27+
end
28+
end
29+
end
30+
31+
def all_entries_valid?
32+
entries.validated.count == entries.count
2133
end
2234
end
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class SubmissionCompletion
2+
attr_reader :submission
3+
4+
def initialize(submission)
5+
@submission = submission
6+
end
7+
8+
def perform!
9+
submission.reviewed_and_accepted! do
10+
submission.task.completed!
11+
end
12+
13+
submission
14+
end
15+
end

app/models/task.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ class Task < ApplicationRecord
55
state :draft
66
state :unstarted, initial: true
77
state :in_progress
8-
state :in_review
98
state :completed
109
state :cancelled
10+
11+
event :completed do
12+
transitions from: %i[in_progress], to: :completed
13+
end
1114
end
1215

1316
validates :status, presence: true

app/serializable/serializable_submission.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ class SerializableSubmission < JSONAPI::Serializable::Resource
22
type 'submissions'
33

44
belongs_to :framework
5+
belongs_to :task
56
has_many :entries
67
has_many :files
78

config/routes.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
resources :submissions, only: %i[show create update] do
1111
member do
1212
post 'calculate', to: 'submissions#calculate'
13+
post 'complete', to: 'submissions#complete'
1314
end
1415

1516
resources :files, only: %i[create update show], controller: 'submission_files'

spec/factories/submission.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,14 @@
2424
create_list(:errored_submission_entry, 1, submission: submission)
2525
end
2626
end
27+
28+
factory :submission_with_unprocessed_entries do
29+
aasm_state :processing
30+
31+
after(:create) do |submission, _evaluator|
32+
create_list(:validated_submission_entry, 2, submission: submission)
33+
create_list(:submission_entry, 1, submission: submission)
34+
end
35+
end
2736
end
2837
end
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
require 'rails_helper'
2+
3+
RSpec.describe SubmissionCompletion do
4+
describe '#perform' do
5+
let(:complete_submission) { SubmissionCompletion.new(submission) }
6+
let(:task) { FactoryBot.create(:task, status: :in_progress) }
7+
8+
context 'given an "in review" submission' do
9+
context 'with validated entries' do
10+
let(:submission) { FactoryBot.create(:submission_with_validated_entries, aasm_state: 'in_review', task: task) }
11+
12+
it 'transitions the submission to completed' do
13+
complete_submission.perform!
14+
15+
expect(submission).to be_completed
16+
end
17+
18+
it 'transitions the task to completed' do
19+
complete_submission.perform!
20+
21+
expect(task).to be_completed
22+
end
23+
end
24+
25+
context 'with some invalid entries' do
26+
let(:submission) { FactoryBot.create(:submission_with_invalid_entries, task: task) }
27+
28+
it 'leaves the submission in the "in_review" state' do
29+
expect { complete_submission.perform! }.not_to change { submission.aasm_state }
30+
end
31+
32+
it 'leaves the task in the "in_progress" state' do
33+
expect { complete_submission.perform! }.not_to change { task.status }
34+
end
35+
end
36+
end
37+
38+
context 'given a "processing" submission' do
39+
let(:submission) { FactoryBot.create(:submission_with_unprocessed_entries, aasm_state: :processing, task: task) }
40+
41+
it 'leaves the submission in its current state' do
42+
expect { complete_submission.perform! }.not_to change { submission.aasm_state }
43+
end
44+
end
45+
end
46+
end

spec/requests/v1/submissions_spec.rb

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,4 +241,49 @@
241241
expect(response).to have_http_status(:no_content)
242242
end
243243
end
244+
245+
describe 'POST /submissions/:submission_id/complete' do
246+
context 'given a valid submission' do
247+
it 'marks the submission as complete' do
248+
task = FactoryBot.create(:task, status: :in_progress)
249+
250+
submission = FactoryBot.create(
251+
:submission_with_validated_entries,
252+
aasm_state: :in_review,
253+
task: task
254+
)
255+
256+
post "/v1/submissions/#{submission.id}/complete"
257+
258+
expect(response).to be_successful
259+
260+
submission.reload
261+
262+
expect(submission).to be_completed
263+
expect(submission.task).to be_completed
264+
end
265+
end
266+
267+
context 'given an invalid submission' do
268+
it 'returns an error' do
269+
task = FactoryBot.create(:task, status: :in_progress)
270+
271+
submission = FactoryBot.create(
272+
:submission_with_invalid_entries,
273+
aasm_state: :in_review,
274+
task: task
275+
)
276+
277+
post "/v1/submissions/#{submission.id}/complete"
278+
279+
expect(response).to have_http_status(:bad_request)
280+
expect(json['errors'][0]['title']).to eql 'Invalid aasm_state'
281+
282+
submission.reload
283+
284+
expect(submission).to be_in_review
285+
expect(task).to be_in_progress
286+
end
287+
end
288+
end
244289
end

0 commit comments

Comments
 (0)