skipping a question

This commit is contained in:
Jared Cosulich 2017-04-20 10:29:11 -04:00
parent 85d5252301
commit 36d061fca2
6 changed files with 44 additions and 13 deletions

View file

@ -14,15 +14,20 @@ class AttemptsController < ApplicationController
end end
attempt.save_response( 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 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_message = ["We've registered your response of \"#{attempt.response}\"."]
response_count = Attempt.for_question(attempt.question).for_school(recipient.school).with_response.count answer_count = Attempt.for_question(attempt.question).for_school(recipient.school).with_answer.count
if response_count > 1 if answer_count > 1
response_message << "#{response_count} people have responded to this question so far. To see all responses visit:" response_message << "#{answer_count} people have responded to this question so far. To see all responses visit:"
else 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:' 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 end

View file

@ -16,8 +16,9 @@ class Attempt < ApplicationRecord
scope :for_student, -> (student) { where(student_id: student.id) } scope :for_student, -> (student) { where(student_id: student.id) }
scope :for_category, -> (category) { joins(:question).merge(Question.for_category(category)) } scope :for_category, -> (category) { joins(:question).merge(Question.for_category(category)) }
scope :for_school, -> (school) { joins(:recipient).merge(Recipient.for_school(school)) } 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_answer, -> { 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_no_answer, -> { where('answer_index is null and open_response_id is null')}
scope :not_yet_responded, -> { where(responded_at: nil) }
def messages def messages
if student.present? if student.present?
@ -30,7 +31,7 @@ class Attempt < ApplicationRecord
[ [
#question.text, #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 end
@ -81,7 +82,7 @@ class Attempt < ApplicationRecord
def update_counts def update_counts
recipient.update_attributes( recipient.update_attributes(
attempts_count: recipient.attempts.count, attempts_count: recipient.attempts.count,
responses_count: recipient.attempts.with_response.count responses_count: recipient.attempts.with_answer.count
) )
end end

View file

@ -37,7 +37,7 @@ class Question < ApplicationRecord
end end
def aggregated_responses_for_school(school) 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? return unless school_responses.present?
response_answer_total = school_responses.inject(0) { |total, response| total + response.answer_index } response_answer_total = school_responses.inject(0) { |total, response| total + response.answer_index }

View file

@ -83,7 +83,7 @@ class RecipientSchedule < ApplicationRecord
def attempt_question(send_message: true, question: next_question) def attempt_question(send_message: true, question: next_question)
return if recipient.opted_out? 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? return if question.nil? && unanswered_attempt.nil?

View file

@ -58,7 +58,7 @@ RSpec.describe AttemptsController, type: :controller do
end end
it 'creates the first attempt with response for the question' do 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 end
it "updates the last attempt by recipient phone number" do it "updates the last attempt by recipient phone number" do
@ -86,7 +86,7 @@ RSpec.describe AttemptsController, type: :controller do
end end
it 'updates the second attempt with response for the school' do 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 end
it "updates the attempt from the second recipient" do 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.') expect(response.body).to eq('Thank you, you have been opted out of these messages and will no longer receive them.')
end end
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
end end

View file

@ -98,7 +98,7 @@ RSpec.describe Attempt, type: :model do
# expect(FakeSMS.messages.first.body).to eq("Question 0:1") # expect(FakeSMS.messages.first.body).to eq("Question 0:1")
expect(FakeSMS.messages.last.to).to eq('111111111') 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 end
it 'should update sent_at' do it 'should update sent_at' do