From b5188468110fb488739dfede7ca6d245037d16e8 Mon Sep 17 00:00:00 2001 From: Jared Cosulich Date: Wed, 8 Mar 2017 10:35:36 -0500 Subject: [PATCH] working on sending twilio messages --- Gemfile | 3 ++ Gemfile.lock | 6 ++++ app/models/attempt.rb | 16 ++++++++++ app/models/recipient_schedule.rb | 23 +++++++------- config/environments/test.rb | 4 +++ spec/models/attempt_spec.rb | 44 +++++++++++++++++++++++++- spec/models/recipient_schedule_spec.rb | 8 ++--- spec/spec_helper.rb | 24 ++++++++++++++ 8 files changed, 111 insertions(+), 17 deletions(-) diff --git a/Gemfile b/Gemfile index 89ff128c..168898cf 100644 --- a/Gemfile +++ b/Gemfile @@ -50,6 +50,9 @@ gem 'newrelic_rpm' gem 'devise' gem 'omniauth' +gem 'twilio-ruby', '~> 4.11.1' + + group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platform: :mri diff --git a/Gemfile.lock b/Gemfile.lock index e0b0652d..40c83ba4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -94,6 +94,7 @@ GEM thor (>= 0.14, < 2.0) jquery-ui-rails (5.0.5) railties (>= 3.2.16) + jwt (1.5.6) launchy (2.4.3) addressable (~> 2.3) libv8 (3.16.14.17) @@ -215,6 +216,10 @@ GEM turbolinks (5.0.1) turbolinks-source (~> 5) turbolinks-source (5.0.0) + twilio-ruby (4.11.1) + builder (>= 2.1.2) + jwt (~> 1.0) + multi_json (>= 1.3.0) tzinfo (1.2.2) thread_safe (~> 0.1) uglifier (3.0.4) @@ -266,6 +271,7 @@ DEPENDENCIES therubyracer timecop turbolinks (~> 5) + twilio-ruby (~> 4.11.1) tzinfo-data uglifier (>= 1.3.0) web-console diff --git a/app/models/attempt.rb b/app/models/attempt.rb index bf1e9b25..676832d3 100644 --- a/app/models/attempt.rb +++ b/app/models/attempt.rb @@ -1,3 +1,5 @@ +require 'twilio-ruby' + class Attempt < ApplicationRecord belongs_to :schedule @@ -5,4 +7,18 @@ class Attempt < ApplicationRecord belongs_to :recipient_schedule belongs_to :question + + def send_message + twilio_number = ENV['TWILIO_NUMBER'] + client = Twilio::REST::Client.new ENV['TWILIO_ACCOUNT_SID'], ENV['TWILIO_AUTH_TOKEN'] + + client.messages.create( + from: twilio_number, + to: recipient.phone, + body: question.text + ) + + update_attributes(sent_at: Time.new) + end + end diff --git a/app/models/recipient_schedule.rb b/app/models/recipient_schedule.rb index c2b59f92..a4093c7e 100644 --- a/app/models/recipient_schedule.rb +++ b/app/models/recipient_schedule.rb @@ -10,20 +10,21 @@ class RecipientSchedule < ApplicationRecord end def make_attempt(question: next_question) - sent_at = Time.new - recipient.attempts.create( + attempt = recipient.attempts.create( schedule: schedule, recipient_schedule: self, - question: question, - sent_at: sent_at + question: question ) - upcoming = upcoming_question_ids.split(/,/)[1..-1].join(',') - attempted = (attempted_question_ids.split(/,/) + [question.id]).join(',') - update_attributes( - upcoming_question_ids: upcoming, - attempted_question_ids: attempted, - last_attempt_at: sent_at - ) + if attempt.send_message + upcoming = upcoming_question_ids.split(/,/)[1..-1].join(',') + attempted = (attempted_question_ids.split(/,/) + [question.id]).join(',') + update_attributes( + upcoming_question_ids: upcoming, + attempted_question_ids: attempted, + last_attempt_at: attempt.sent_at + ) + end + return attempt end end diff --git a/config/environments/test.rb b/config/environments/test.rb index 27721380..b8b5f507 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -42,3 +42,7 @@ Rails.application.configure do config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } end + +ENV['TWILIO_NUMBER'] = 'TWILIO_NUMBER' +ENV['TWILIO_ACCOUNT_SID'] = 'TWILIO_ACCOUNT_SID' +ENV['TWILIO_AUTH_TOKEN'] = 'TWILIO_AUTH_TOKEN' diff --git a/spec/models/attempt_spec.rb b/spec/models/attempt_spec.rb index 33640892..eabbf712 100644 --- a/spec/models/attempt_spec.rb +++ b/spec/models/attempt_spec.rb @@ -1,5 +1,47 @@ require 'rails_helper' RSpec.describe Attempt, type: :model do - pending "add some examples to (or delete) #{__FILE__}" + + let(:question) { Question.create!(text: 'What is the question?', option1: 'A', option2: 'B', option3: 'C', option4: 'D', option5: 'E')} + let(:question_list) { QuestionList.create(name: 'Parent Questions', question_ids: "#{question.id},2,3")} + + let(:recipient) { Recipient.create!(name: 'Parent', phone: '1112223333') } + let(:recipient_list) { RecipientList.create(name: 'Parent List', recipient_ids: recipient.id.to_s)} + + let(:schedule) { Schedule.create!(name: 'Parent Schedule', recipient_list_id: recipient_list.id, question_list: question_list) } + + let(:recipient_schedule) do + RecipientSchedule.create!( + recipient: recipient, + schedule: schedule, + upcoming_question_ids: "#{question.id},3", + attempted_question_ids: '2', + last_attempt_at: 2.weeks.ago + ) + end + + let!(:attempt) do + recipient.attempts.create( + schedule: schedule, + recipient_schedule: recipient_schedule, + question: question + ) + end + + describe 'send_message' do + before :each do + Timecop.freeze + attempt.send_message + end + + it 'should contact the Twilio API' do + expect(FakeSMS.messages.length).to eq(1) + expect(FakeSMS.messages.first.body).to eq(question.text) + expect(FakeSMS.messages.first.to).to eq(recipient.phone) + end + + it 'should update sent_at' do + expect(attempt.sent_at).to eq(Time.new) + end + end end diff --git a/spec/models/recipient_schedule_spec.rb b/spec/models/recipient_schedule_spec.rb index 0fdc9580..18a5ee41 100644 --- a/spec/models/recipient_schedule_spec.rb +++ b/spec/models/recipient_schedule_spec.rb @@ -5,7 +5,7 @@ RSpec.describe RecipientSchedule, type: :model do let(:question) { Question.create!(text: 'What is the question?', option1: 'A', option2: 'B', option3: 'C', option4: 'D', option5: 'E')} let(:question_list) { QuestionList.create(name: 'Parent Questions', question_ids: "#{question.id},2,3")} - let(:recipient) { Recipient.create!(name: 'Parent') } + let(:recipient) { Recipient.create!(name: 'Parent', phone: '1112223333') } let(:recipient_list) { RecipientList.create(name: 'Parent List', recipient_ids: recipient.id.to_s)} let(:schedule) { Schedule.create!(name: 'Parent Schedule', recipient_list_id: recipient_list.id, question_list: question_list) } @@ -29,14 +29,12 @@ RSpec.describe RecipientSchedule, type: :model do describe 'make_attempt' do before :each do Timecop.freeze - recipient_schedule.make_attempt end - it 'should contact the twillio API' + let!(:attempt) { recipient_schedule.make_attempt } it 'should make an attempt to ask the next question' do - expect(Attempt.count).to eq(1) - attempt = Attempt.first + expect(attempt).to be_persisted expect(attempt.recipient).to eq(recipient) expect(attempt.schedule).to eq(schedule) expect(attempt.recipient_schedule).to eq(recipient_schedule) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 8f698be4..57dbf744 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -96,4 +96,28 @@ RSpec.configure do |config| # as the one that triggered the failure. Kernel.srand config.seed =end + + config.before(:each) do + stub_const("Twilio::REST::Client", FakeSMS) + end +end + + +require 'active_support/all' +class FakeSMS + Message = Struct.new(:from, :to, :body) + + cattr_accessor :messages + self.messages = [] + + def initialize(_account_sid, _auth_token) + end + + def messages + self + end + + def create(from:, to:, body:) + self.class.messages << Message.new(from, to, body) + end end