From 36d061fca21927afcf3ea9b669b4088cf85e8243 Mon Sep 17 00:00:00 2001 From: Jared Cosulich Date: Thu, 20 Apr 2017 10:29:11 -0400 Subject: [PATCH] skipping a question --- app/controllers/attempts_controller.rb | 13 ++++++--- app/models/attempt.rb | 9 +++--- app/models/question.rb | 2 +- app/models/recipient_schedule.rb | 2 +- spec/controllers/attempts_controller_spec.rb | 29 ++++++++++++++++++-- spec/models/attempt_spec.rb | 2 +- 6 files changed, 44 insertions(+), 13 deletions(-) diff --git a/app/controllers/attempts_controller.rb b/app/controllers/attempts_controller.rb index f1d5fe4b..ec571f83 100644 --- a/app/controllers/attempts_controller.rb +++ b/app/controllers/attempts_controller.rb @@ -14,15 +14,20 @@ class AttemptsController < ApplicationController end attempt.save_response( - answer_index: twilio_params[:Body].to_i, + answer_index: twilio_params[:Body].to_i > 0 ? twilio_params[:Body].to_i : nil, twilio_details: twilio_params.to_h.to_yaml ) + if (twilio_params[:Body].downcase == 'skip') + render plain: 'Thank you, this question has been skipped.' + return + end + response_message = ["We've registered your response of \"#{attempt.response}\"."] - response_count = Attempt.for_question(attempt.question).for_school(recipient.school).with_response.count - if response_count > 1 - response_message << "#{response_count} people have responded to this question so far. To see all responses visit:" + answer_count = Attempt.for_question(attempt.question).for_school(recipient.school).with_answer.count + if answer_count > 1 + response_message << "#{answer_count} people have responded to this question so far. To see all responses visit:" else response_message << 'You are the first person to respond to this question. Once more people have responded you will be able to see all responses at:' end diff --git a/app/models/attempt.rb b/app/models/attempt.rb index 9f1ae468..c96cfc50 100644 --- a/app/models/attempt.rb +++ b/app/models/attempt.rb @@ -16,8 +16,9 @@ class Attempt < ApplicationRecord scope :for_student, -> (student) { where(student_id: student.id) } scope :for_category, -> (category) { joins(:question).merge(Question.for_category(category)) } scope :for_school, -> (school) { joins(:recipient).merge(Recipient.for_school(school)) } - scope :with_response, -> { where('answer_index is not null or open_response_id is not null')} - scope :with_no_response, -> { where('answer_index is null and open_response_id is null')} + scope :with_answer, -> { where('answer_index is not null or open_response_id is not null')} + scope :with_no_answer, -> { where('answer_index is null and open_response_id is null')} + scope :not_yet_responded, -> { where(responded_at: nil) } def messages if student.present? @@ -30,7 +31,7 @@ class Attempt < ApplicationRecord [ #question.text, - "#{intro}\n\r#{question.text}\n\r#{question.option1}: Reply 1\n\r#{question.option2}: Reply 2\n\r#{question.option3}: Reply 3\n\r#{question.option4}: Reply 4\n\r#{question.option5}: Reply 5\n\rReply 'stop' to stop these messages." + "#{intro}\n\r#{question.text}\n\r#{question.option1}: Reply 1\n\r#{question.option2}: Reply 2\n\r#{question.option3}: Reply 3\n\r#{question.option4}: Reply 4\n\r#{question.option5}: Reply 5\n\rReply 'skip' to skip this question.\n\rReply 'stop' to stop these messages." ] end @@ -81,7 +82,7 @@ class Attempt < ApplicationRecord def update_counts recipient.update_attributes( attempts_count: recipient.attempts.count, - responses_count: recipient.attempts.with_response.count + responses_count: recipient.attempts.with_answer.count ) end diff --git a/app/models/question.rb b/app/models/question.rb index d3a1db17..0fc232cd 100644 --- a/app/models/question.rb +++ b/app/models/question.rb @@ -37,7 +37,7 @@ class Question < ApplicationRecord end def aggregated_responses_for_school(school) - school_responses = attempts.for_school(school).with_response.order(id: :asc) + school_responses = attempts.for_school(school).with_answer.order(id: :asc) return unless school_responses.present? response_answer_total = school_responses.inject(0) { |total, response| total + response.answer_index } diff --git a/app/models/recipient_schedule.rb b/app/models/recipient_schedule.rb index bd95f014..a7c1584f 100644 --- a/app/models/recipient_schedule.rb +++ b/app/models/recipient_schedule.rb @@ -83,7 +83,7 @@ class RecipientSchedule < ApplicationRecord def attempt_question(send_message: true, question: next_question) return if recipient.opted_out? - unanswered_attempt = recipient.attempts.with_no_response.last + unanswered_attempt = recipient.attempts.not_yet_responded.last return if question.nil? && unanswered_attempt.nil? diff --git a/spec/controllers/attempts_controller_spec.rb b/spec/controllers/attempts_controller_spec.rb index 11e517ac..5c9cf2a8 100644 --- a/spec/controllers/attempts_controller_spec.rb +++ b/spec/controllers/attempts_controller_spec.rb @@ -58,7 +58,7 @@ RSpec.describe AttemptsController, type: :controller do end it 'creates the first attempt with response for the question' do - expect(attempt.question.attempts.for_school(school).with_response.count).to eq(1) + expect(attempt.question.attempts.for_school(school).with_answer.count).to eq(1) end it "updates the last attempt by recipient phone number" do @@ -86,7 +86,7 @@ RSpec.describe AttemptsController, type: :controller do end it 'updates the second attempt with response for the school' do - expect(attempt.question.attempts.for_school(school).with_response.count).to eq(2) + expect(attempt.question.attempts.for_school(school).with_answer.count).to eq(2) end it "updates the attempt from the second recipient" do @@ -120,5 +120,30 @@ RSpec.describe AttemptsController, type: :controller do expect(response.body).to eq('Thank you, you have been opted out of these messages and will no longer receive them.') end end + + context 'with skip params' do + let(:twilio_skip_attributes) { + {'MessageSid' => 'ewuefhwieuhfweiuhfewiuhf','AccountSid' => 'wefiuwhefuwehfuwefinwefw','MessagingServiceSid' => 'efwneufhwuefhweiufhiuewhf','From' => '+0000000000','To' => '2223334444','Body' => 'SkIP','NumMedia' => '0'} + } + + it "updates the last attempt by recipient phone number" do + post :twilio, params: twilio_skip_attributes + attempt.reload + expect(attempt.answer_index).to be_nil + expect(attempt.responded_at).to be_present + expect(attempt.twilio_details).to eq(twilio_skip_attributes.with_indifferent_access.to_yaml) + expect(attempt.recipient).to_not be_opted_out + + school_attempts = attempt.question.attempts.for_school(school) + expect(school_attempts.with_answer.count).to eq(0) + expect(school_attempts.with_no_answer.count).to eq(3) + expect(school_attempts.not_yet_responded.count).to eq(2) + end + + it "sends back a message" do + post :twilio, params: twilio_skip_attributes + expect(response.body).to eq('Thank you, this question has been skipped.') + end + end end end diff --git a/spec/models/attempt_spec.rb b/spec/models/attempt_spec.rb index bfd2474f..8c63903d 100644 --- a/spec/models/attempt_spec.rb +++ b/spec/models/attempt_spec.rb @@ -98,7 +98,7 @@ RSpec.describe Attempt, type: :model do # expect(FakeSMS.messages.first.body).to eq("Question 0:1") expect(FakeSMS.messages.last.to).to eq('111111111') - expect(FakeSMS.messages.last.body).to eq("Your child's school, School, would love your opinion on this question:\n\rQuestion 0:1\n\rOption 0:1 A: Reply 1\n\rOption 0:1 B: Reply 2\n\rOption 0:1 C: Reply 3\n\rOption 0:1 D: Reply 4\n\rOption 0:1 E: Reply 5\n\rReply 'stop' to stop these messages.") + expect(FakeSMS.messages.last.body).to eq("Your child's school, School, would love your opinion on this question:\n\rQuestion 0:1\n\rOption 0:1 A: Reply 1\n\rOption 0:1 B: Reply 2\n\rOption 0:1 C: Reply 3\n\rOption 0:1 D: Reply 4\n\rOption 0:1 E: Reply 5\n\rReply 'skip' to skip this question.\n\rReply 'stop' to stop these messages.") end it 'should update sent_at' do