Merge pull request #1 from jaredcosulich/recipient_students

Recipient students
pull/1/head
jaredcosulich 9 years ago committed by GitHub
commit 0c2aa09ebc

@ -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

@ -6,20 +6,32 @@ class Attempt < ApplicationRecord
belongs_to :recipient
belongs_to :recipient_schedule
belongs_to :question
belongs_to :student
after_save :update_school_categories
after_commit :update_counts
scope :for_question, -> (question) { where(question_id: question.id) }
scope :for_recipient, -> (recipient) { where(recipient_id: recipient.id) }
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?
intro = "#{student.name}'s school, "
else
intro = "Your child's school, "
end
intro += "#{recipient.school.name}, would love your opinion on this question:"
[
question.text,
"#{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."
#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 'skip' to skip this question.\n\rReply 'stop' to stop these messages."
]
end
@ -70,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

@ -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 }

@ -7,6 +7,8 @@ class Recipient < ApplicationRecord
has_many :recipient_schedules
has_many :attempts
has_many :students
validates :name, presence: true
scope :for_school, -> (school) { where(school: school) }

@ -33,7 +33,7 @@ class RecipientList < ApplicationRecord
new_ids = recipient_ids.split(/,/)
(old_ids - new_ids).each do |deleted_recipient|
schedules.each do |schedule|
schedule.recipient_schedules.for(deleted_recipient).first.destroy
schedule.recipient_schedules.for_recipient(deleted_recipient).first.destroy
end
end

@ -9,12 +9,18 @@ class RecipientSchedule < ApplicationRecord
validates :next_attempt_at, presence: true
scope :ready, -> { where('next_attempt_at <= ?', Time.new) }
scope :for, -> (recipient_or_recipient_id) {
scope :for_recipient, -> (recipient_or_recipient_id) {
id = recipient_or_recipient_id.is_a?(Recipient) ?
recipient_or_recipient_id.id :
recipient_or_recipient_id
where(recipient_id: id)
}
scope :for_schedule, -> (schedule_or_schedule_id) {
id = schedule_or_schedule_id.is_a?(Schedule) ?
schedule_or_schedule_id.id :
schedule_or_schedule_id
where(schedule_id: id)
}
def next_question
if queued_question_ids.present?
@ -25,13 +31,79 @@ class RecipientSchedule < ApplicationRecord
Question.where(id: next_question_id).first
end
def upcoming_question_id_array
upcoming_question_ids.try(:split, /,/) || []
end
def attempted_question_id_array
attempted_question_ids.try(:split, /,/) || []
end
def queued_question_id_array
queued_question_ids.try(:split, /,/) || []
end
def attempt_question_for_recipient_students(send_message: true, question: next_question)
return if recipient.opted_out?
return if question.nil?
if !question.for_recipient_students?
return attempt_question(question: question)
end
missing_students = []
recipient_attempts = attempts.for_recipient(recipient).for_question(question)
recipient.students.each do |student|
if recipient_attempts.for_student(student).empty?
missing_students << student
end
end
attempt = recipient.attempts.create(
schedule: schedule,
recipient_schedule: self,
question: question,
student: missing_students.first
)
if send_message && attempt.send_message
upcoming = upcoming_question_id_array
queued = queued_question_id_array
attempted = attempted_question_id_array
if question.present?
question_id = [question.id.to_s]
upcoming = upcoming - question_id
if missing_students.length > 1
queued += question_id
else
attempted += question_id
queued -= question_id
end
end
update_attributes(
upcoming_question_ids: upcoming.empty? ? nil : upcoming.join(','),
attempted_question_ids: attempted.empty? ? nil : attempted.join(','),
queued_question_ids: queued.empty? ? nil : queued.join(','),
last_attempt_at: attempt.sent_at,
next_attempt_at: next_valid_attempt_time
)
end
return attempt
end
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?
if unanswered_attempt.nil?
if question.for_recipient_students?
return attempt_question_for_recipient_students(question: question)
end
attempt = recipient.attempts.create(
schedule: schedule,
recipient_schedule: self,
@ -40,9 +112,9 @@ class RecipientSchedule < ApplicationRecord
end
if send_message && (unanswered_attempt || attempt).send_message
upcoming = upcoming_question_ids.try(:split, /,/) || []
queued = queued_question_ids.try(:split, /,/) || []
attempted = attempted_question_ids.try(:split, /,/) || []
upcoming = upcoming_question_id_array
queued = queued_question_id_array
attempted = attempted_question_id_array
if question.present?
question_id = [question.id.to_s]

@ -0,0 +1,3 @@
class Student < ApplicationRecord
belongs_to :recipient
end

@ -1,14 +1,12 @@
[
{"category": "6-A-i", "text": "How often do you meet in person with teachers or administrators at your child's school?", "answers": ["Almost never", "Once or twice a year", "Every few months", "Monthly", "Weekly or more"]},
{"category": "6-A-i", "text": "In the past year, how often have you discussed your child's school with other parents from the school?", "answers": ["Almost never", "Once or twice a year", "Every few months", "Monthly", "Weekly or more"]},
{"category": "6-A-i", "text": "How involved have you been in activities at your child's school?", "answers": ["Not involved at all", "A little bit involved ", "Somewhat involved", "Quite involved", "Extremely involved"]},
{"category": "6-A-i", "text": "In the past year, how often have you helped out at your child's school?", "answers": ["Almost never", "Once or twice ", "Every few months", "Monthly", "Weekly or more"]},
{"category": "6-A-i", "text": "How confident are you in your ability to connect with other parents? ", "answers": ["Not confident at all", "A little bit confident", "Somewhat confident", "Quite confident", "Extremely confident"]},
{"category": "6-A-i", "text": "How confident are you in your ability to make sure your child's school meets your child's learning needs? ", "answers": ["Not confident at all", "A little bit confident", "Somewhat confident", "Quite confident", "Extremely confident"]},
{"category": "6-A-i", "child": true, "text": "How confident are you in your ability to make sure your child's school meets your child's learning needs? ", "answers": ["Not confident at all", "A little bit confident", "Somewhat confident", "Quite confident", "Extremely confident"]},
{"category": "6-A-i", "text": "How confident are you in your ability to make choices about your child's schooling?", "answers": ["Not confident at all", "A little bit confident", "Somewhat confident", "Quite confident", "Extremely confident"]},
{"category": "6-A-i", "text": "How confident are you that you can motivate your child to try hard in school? ", "answers": ["Not confident at all", "A little bit confident", "Somewhat confident", "Quite confident", "Extremely confident"]},
{"category": "6-A-i", "text": "How confident are you in your ability to support your child's learning at home? ", "answers": ["Not confident at all", "A little bit confident", "Somewhat confident", "Quite confident", "Extremely confident"]},
{"category": "6-A-i", "text": "How confident are you that you can help your child develop good friendships? ", "answers": ["Not confident at all", "A little bit confident", "Somewhat confident", "Quite confident", "Extremely confident"]},
{"category": "6-A-i", "child": true, "text": "How confident are you that you can motivate your child to try hard in school?", "answers": ["Not confident at all", "A little bit confident", "Somewhat confident", "Quite confident", "Extremely confident"]},
{"category": "6-A-i", "child": true, "text": "How confident are you in your ability to support your child's learning at home?", "answers": ["Not confident at all", "A little bit confident", "Somewhat confident", "Quite confident", "Extremely confident"]},
{"category": "6-A-i", "child": true, "text": "How confident are you that you can help your child develop good friendships?", "answers": ["Not confident at all", "A little bit confident", "Somewhat confident", "Quite confident", "Extremely confident"]},
{"category": "6-A-i", "text": "Overall, how good is this school at communicating with parents?", "answers": ["Not good at all", "Slightly good", "Somewhat good", "Quite good", "Extremely good"]},
{"category": "6-A-i", "text": "How often do you visit your child's school for an event, activity, or to volunteer?", "answers": ["Almost never", "Once or twice a year", "Every few months", "Monthly", "Weekly or more"]},
{"category": "6-A-i", "text": "How often do you discuss your child's school with other parents from the school?", "answers": ["Almost never", "Once or twice a year", "Every few months", "Monthly", "Weekly or more"]},
@ -16,14 +14,14 @@
{"category": "6-A-ii", "text": "How often would you like the school to host social events for families?", "answers": ["Almost never", "Once or twice a year", "Every few months", "Monthly", "Weekly or more"]},
{"category": "6-A-ii", "text": "How often would you like to meet with school staff to talk about helping children succeed academically?", "answers": ["Almost never", "Once or twice a year", "Every few months", "Monthly", "Weekly or more"]},
{"category": "6-A-ii", "text": "How much would you enjoy spending an hour in your childs classroom?", "answers": ["Would not enjoy that at all", "Would enjoy that a little bit", "Would enjoy that somewhat", "Would enjoy that quite a bit", "Would enjoy that a tremendous amount"]},
{"category": "6-A-ii", "child": true, "text": "How much would you enjoy spending an hour in your childs classroom?", "answers": ["Would not enjoy that at all", "Would enjoy that a little bit", "Would enjoy that somewhat", "Would enjoy that quite a bit", "Would enjoy that a tremendous amount"]},
{"category": "6-A-ii", "text": "How much would you like to receive text messages from the school about upcoming events?", "answers": ["Would not like that at all", "Would like that a little bit", "Would like that somewhat", "Would like that quite a bit", "Would like that a tremendous amount"]},
{"category": "6-A-ii", "text": "How much would you like to receive messages from the school translated into another language?", "answers": ["Would not like that at all", "Would like that a little bit", "Would like that somewhat", "Would like that quite a bit", "Would like that a tremendous amount"]},
{"category": "6-A-iii", "text": "How would you describe your sense of belonging in the school community? ", "answers": ["Very weak", "Weak", "Neutral", "Strong", "Very strong"]},
{"category": "6-A-iii", "text": "Overall, how good is this school?", "answers": ["Not good at all", "Slightly good", "Somewhat good", "Quite good", "Extremely good"]},
{"category": "6-A-iii", "text": "Overall, how welcome do you feel at this school?", "answers": ["Not welcome at all", "Slightly welcome", "Somewhat welcome", "Quite welcome", "Extremely welcome"]},
{"category": "6-A-iii", "text": "Overall, how well do you get along well with your childs teacher(s)?", "answers": ["Do not get along well at all", "Get along a little bit", "Get along somewhat", "Get along quite well", "Get along extremely well"]},
{"category": "6-A-iii", "text": "Overall, how much do the teachers at this school care about your child?", "answers": ["Do not care about my child at all", "Care about my child a little bit", "Care about my child somewhat", "Care about my child quite a bit", "Care about my child a tremendous amount"]},
{"category": "6-A-iii", "child": true, "text": "Overall, how well do you get along well with your childs teacher(s)?", "answers": ["Do not get along well at all", "Get along a little bit", "Get along somewhat", "Get along quite well", "Get along extremely well"]},
{"category": "6-A-iii", "child": true, "text": "Overall, how much do the teachers at this school care about your child?", "answers": ["Do not care about my child at all", "Care about my child a little bit", "Care about my child somewhat", "Care about my child quite a bit", "Care about my child a tremendous amount"]},
{"category": "6-A-iii", "text": "Overall, how much do people at this school care about your family?", "answers": ["Dont care at all", "Care a little bit", "Care about my family somewhat ", "Care about my family quite a bit", "Care about my family a tremendous amount"]}
]

@ -0,0 +1,18 @@
class CreateStudents < ActiveRecord::Migration[5.0]
def change
create_table :students do |t|
t.string :name
t.string :teacher
t.date :birthdate
t.string :gender
t.string :age
t.string :ethnicity
t.integer :recipient_id
t.timestamps
end
add_column :questions, :for_recipient_students, :boolean, default: false
add_column :attempts, :student_id, :integer
end
end

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20170417203127) do
ActiveRecord::Schema.define(version: 20170418173141) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -29,6 +29,7 @@ ActiveRecord::Schema.define(version: 20170417203127) do
t.datetime "updated_at", null: false
t.text "twilio_details"
t.string "twilio_sid"
t.integer "student_id"
t.index ["twilio_sid"], name: "index_attempts_on_twilio_sid", using: :btree
end
@ -70,6 +71,7 @@ ActiveRecord::Schema.define(version: 20170417203127) do
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "target_group", default: 0
t.boolean "for_recipient_students", default: false
end
create_table "recipient_lists", force: :cascade do |t|
@ -155,6 +157,18 @@ ActiveRecord::Schema.define(version: 20170417203127) do
t.index ["slug"], name: "index_schools_on_slug", unique: true, using: :btree
end
create_table "students", force: :cascade do |t|
t.string "name"
t.string "teacher"
t.date "birthdate"
t.string "gender"
t.string "age"
t.string "ethnicity"
t.integer "recipient_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "user_schools", force: :cascade do |t|
t.integer "user_id"
t.integer "school_id"

@ -21,6 +21,15 @@ recipients = [
school.recipients.create(name: 'Lynisse Patin', phone: '19176566892'),
school.recipients.create(name: 'Khemenec Patin', phone: '(347) 534-6437'),
]
recipients[0].students.create(name: 'Abigail')
recipients[0].students.create(name: 'Clara')
recipients[3].students.creaet(name: 'Zara')
recipients[3].students.creaet(name: 'Cole')
recipients[4].students.creaet(name: 'Zara')
recipients[4].students.creaet(name: 'Cole')
recipient_list = school.recipient_lists.create(name: 'Pilot Parent Test', recipient_id_array: recipients.map(&:id))
user.user_schools.create(school: school)

@ -102,7 +102,8 @@ namespace :data do
option2: question['answers'][1],
option3: question['answers'][2],
option4: question['answers'][3],
option5: question['answers'][4]
option5: question['answers'][4],
for_recipient_students: question['child'].present?
)
else
variations.each do |variation|
@ -112,7 +113,8 @@ namespace :data do
option2: question['answers'][1],
option3: question['answers'][2],
option4: question['answers'][3],
option5: question['answers'][4]
option5: question['answers'][4],
for_recipient_students: question['child'].present?
)
end
end

@ -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

@ -105,7 +105,7 @@ describe "survey:attempt_questions" do
describe 'Second Attempts' do
before :each do
recipients.each do |recipient|
recipient_schedule = schedule.recipient_schedules.for(recipient).first
recipient_schedule = schedule.recipient_schedules.for_recipient(recipient).first
recipient_schedule.attempt_question
end
end
@ -161,7 +161,7 @@ describe "survey:attempt_questions" do
Timecop.freeze(now + 7)
recipients.each do |recipient|
recipient_schedule = schedule.recipient_schedules.for(recipient).first
recipient_schedule = schedule.recipient_schedules.for_recipient(recipient).first
recipient_schedule.attempt_question
end
@ -185,13 +185,150 @@ describe "survey:attempt_questions" do
end
it 'should not send anything to anyone else' do
expect(FakeSMS.messages.length).to eq(@existing_message_count + 2)
expect(FakeSMS.messages.length).to eq(@existing_message_count + 1)
expect(recipients[0].attempts.count).to eq(1)
expect(recipients[1].attempts.count).to eq(2)
end
end
end
describe 'Multiple Students In A Family' do
before :each do
3.times do |i|
recipients[1].students.create(name: "Student#{i}")
end
end
let(:students_recipient) { recipients[1] }
let(:students_recipient_schedule) {
students_recipient.recipient_schedules.for_schedule(schedule).first
}
describe 'With A FOR_CHILD Question Is Asked' do
let!(:date) { ActiveSupport::TimeZone["UTC"].parse(now.strftime("%Y-%m-%dT20:00:00%z")) }
before :each do
questions.first.update_attributes(for_recipient_students: true)
Timecop.freeze(date) { subject.invoke }
end
it 'should create one attempt per recipient regardless of students' do
expect(FakeSMS.messages.length).to eq(3)
recipients.each do |recipient|
expect(recipient.attempts.count).to eq(1)
end
end
it 'should store queued questions when an attempt is made on first student' do
expect(students_recipient_schedule.queued_question_ids).to be_present
queued_question_ids = students_recipient_schedule.queued_question_ids.split(/,/)
expect(queued_question_ids.length).to eq(1)
expect(queued_question_ids.first).to eq("#{questions[0].id}")
end
it 'should set the next_attempt_at to now when attempt is made on first student' do
students_recipient.attempts.last.save_response(answer_index: 3)
expect(students_recipient_schedule.reload.next_attempt_at).to eq(Time.new)
end
it 'should set the next_attempt_at in the future when an attempts are made on each student' do
students_recipient.attempts.last.save_response(answer_index: 3)
expect{students_recipient_schedule.attempt_question}.to change{students_recipient.attempts.count}.by(1)
expect(students_recipient_schedule.reload.queued_question_ids).to be_present
attempt = students_recipient.attempts.last
expect(attempt.student).to eq(students_recipient.students[1])
Timecop.freeze(date + 1.day)
attempt.save_response(answer_index: 4)
expect(students_recipient_schedule.reload.next_attempt_at).to eq(date + 1.day)
expect{students_recipient_schedule.attempt_question}.to change{students_recipient.attempts.count}.by(1)
expect(students_recipient_schedule.reload.queued_question_ids).to be_nil
expect(students_recipient_schedule.reload.next_attempt_at).to_not eq(date + (60 * 60 * schedule.frequency_hours))
attempt = students_recipient.attempts.last
expect(attempt.student).to eq(students_recipient.students[2])
Timecop.freeze(date + 2.days)
attempt.save_response(answer_index: 2)
expect(students_recipient_schedule.reload.next_attempt_at).to_not eq(date + 2.days)
end
it 'should mention the students name in the text' do
expect(FakeSMS.messages[1].body).to match(/Student0's school, School, would love your opinion on this question/)
end
it 'should not mention the students name in the text if the recipient has no student specified' do
expect(FakeSMS.messages[0].body).to match(/Your child's school, School, would love your opinion on this question/)
end
it 'resends the question about the same student if not responded to' do
message_count = FakeSMS.messages.length
expect{students_recipient_schedule.attempt_question}.to change{students_recipient.attempts.count}.by(0)
expect(FakeSMS.messages.length).to eq(message_count + 1)
expect(FakeSMS.messages.last.body).to match(/Student0's school, School/)
expect(FakeSMS.messages.last.body).to match(questions.first.text)
end
it 'doesnt store any queued_question_ids when no students are present' do
recipient_schedule = recipients[0].recipient_schedules.for_schedule(schedule).first
expect(recipient_schedule.queued_question_ids).to be_nil
end
end
describe 'With A General Question Is Asked' do
before :each do
subject.invoke
end
it 'should not queue up an questions regardless of how many students there are' do
expect(students_recipient_schedule.queued_question_ids).to be_nil
end
it 'should not mention the students name in the text' do
FakeSMS.messages.each do |message|
expect(message.body).to match(/Your child's school, School, would love your opinion on this question/)
end
end
end
end
describe 'One Student In A Family' do
before :each do
recipients[1].students.create(name: "Only Student")
end
let(:students_recipient) { recipients[1] }
let(:students_recipient_schedule) {
students_recipient.recipient_schedules.for_schedule(schedule).first
}
describe 'With A FOR_CHILD Question Is Asked' do
let!(:date) { ActiveSupport::TimeZone["UTC"].parse(now.strftime("%Y-%m-%dT20:00:00%z")) }
before :each do
questions.first.update_attributes(for_recipient_students: true)
Timecop.freeze(date) { subject.invoke }
end
it 'should create one attempt per recipient regardless of students' do
expect(FakeSMS.messages.length).to eq(3)
recipients.each do |recipient|
expect(recipient.attempts.count).to eq(1)
end
end
it 'doesnt store any queued_question_ids' do
expect(students_recipient_schedule.queued_question_ids).to be_nil
end
end
end
describe 'Opted Out Recipient' do
before :each do

@ -92,13 +92,13 @@ RSpec.describe Attempt, type: :model do
end
it 'should contact the Twilio API' do
expect(FakeSMS.messages.length).to eq(2)
expect(FakeSMS.messages.length).to eq(1)
expect(FakeSMS.messages.first.to).to eq('111111111')
expect(FakeSMS.messages.first.body).to eq("Question 0:1")
# expect(FakeSMS.messages.first.to).to eq('111111111')
# 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("Option 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

@ -24,7 +24,7 @@ RSpec.describe RecipientSchedule, type: :model do
frequency_hours: 24
)
end
let!(:recipient_schedule) { schedule.recipient_schedules.for(recipient).first }
let!(:recipient_schedule) { schedule.recipient_schedules.for_recipient(recipient).first }
let!(:not_ready_recipient_schedule) do
RecipientSchedule.create!(
@ -91,6 +91,11 @@ RSpec.describe RecipientSchedule, type: :model do
end
describe 'with an opted in recipient' do
before :each do
date = ActiveSupport::TimeZone["UTC"].parse('2017-04-20T20:00:00')
Timecop.freeze(date)
end
let!(:attempt) { recipient_schedule.attempt_question }
it 'should make an attempt to ask the next question' do
@ -121,7 +126,7 @@ RSpec.describe RecipientSchedule, type: :model do
date += 1.day
date += 1.day if date.on_weekend?
expect(recipient_schedule.next_attempt_at).to eq(date.to_time)
expect(recipient_schedule.reload.next_attempt_at).to eq(date.to_time)
end
end
end

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe Student, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end
Loading…
Cancel
Save