-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add reply processor to handle the SMS responses
- Loading branch information
Showing
6 changed files
with
194 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
module SMS | ||
class ReplyProcessor | ||
def self.process(message, cookies) | ||
new(message, cookies).process | ||
end | ||
|
||
def initialize(message, cookies) | ||
@message = message | ||
@tracked_question = TrackedQuestion.new(cookies) | ||
end | ||
|
||
def process | ||
return process_initial_response if initial_response? | ||
process_succ_response if tracked_question.present? | ||
end | ||
|
||
private | ||
|
||
attr_reader :message, :tracked_question | ||
|
||
def initial_response? | ||
tracked_question.empty? | ||
end | ||
|
||
def process_initial_response | ||
survey = Survey.first | ||
first_question = survey.first_question | ||
tracked_question.store_or_destroy(first_question) | ||
CreateResponse.for(first_question) | ||
end | ||
|
||
def process_succ_response | ||
previous_question = tracked_question.fetch | ||
Answer.create(attributes_for_answer(previous_question)) | ||
next_question = FindNextQuestion.for(previous_question) | ||
tracked_question.store_or_destroy(next_question) | ||
CreateResponse.for(next_question) | ||
end | ||
|
||
def attributes_for_answer(question) | ||
{ | ||
question_id: question.id, | ||
content: message, | ||
source: Answer.sources.fetch(:sms), | ||
from: 'from' | ||
} | ||
end | ||
|
||
# Think about this case. | ||
def welcome_message_o | ||
survey = Survey.first | ||
Twilio::TwiML::Response.new do |r| | ||
r.Message do |msg| | ||
msg.Body "Thank you for taking the #{survey.title} survey" | ||
end | ||
end.to_xml | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
require 'rails_helper' | ||
|
||
describe SMS::ReplyProcessor do | ||
describe '.process' do | ||
subject { described_class.process(message, cookies) } | ||
|
||
let(:survey) { create(:survey, title: 'bees') } | ||
|
||
let!(:first_question) { create(:question, survey: survey, body: 'first') } | ||
let!(:last_question) { create(:question, survey: survey, body: 'last') } | ||
|
||
context 'when there are no tracked questions' do | ||
let(:message) { 'start' } | ||
let(:cookies) { {} } | ||
|
||
it 'responds with the first question' do | ||
expect(content_for('/Response/Message/Body')) | ||
.to eq("first\n\nReply to this message with your answer") | ||
end | ||
|
||
it 'track the current question' do | ||
subject | ||
expect(cookies[:question]).to include(first_question.id.to_s) | ||
end | ||
end | ||
|
||
context 'when there are a tracked question' do | ||
let(:message) { 'answer for the question' } | ||
let(:cookies) { { question: serialize_question(first_question) } } | ||
|
||
it 'creates an answer' do | ||
expect do | ||
subject | ||
end.to change { Answer.count }.by(1) | ||
end | ||
|
||
context 'when there are questions available' do | ||
it 'responds with the next available question' do | ||
expect(content_for('/Response/Message/Body')) | ||
.to eq("last\n\nReply to this message with your answer") | ||
end | ||
|
||
it 'track the current question' do | ||
subject | ||
expect(cookies[:question]).to include(last_question.id.to_s) | ||
end | ||
end | ||
|
||
context 'when there are no more questions available' do | ||
let(:cookies) { { question: serialize_question(last_question) } } | ||
|
||
it 'responds with the exit message' do | ||
expect(content_for('/Response/Message/Body')) | ||
.to eq('Thanks for your time. Good bye') | ||
end | ||
|
||
it 'untrack the current question' do | ||
subject | ||
expect(cookies[:question]).to be_nil | ||
end | ||
end | ||
end | ||
end | ||
|
||
private | ||
|
||
def content_for(xpath) | ||
document = Nokogiri::XML(subject) | ||
document.at_xpath(xpath).content | ||
end | ||
|
||
def serialize_question(question) | ||
question.serializable_hash.to_yaml | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters