You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
360 lines
13 KiB
360 lines
13 KiB
require 'rails_helper'
|
|
|
|
module Legacy
|
|
describe 'survey:attempt_questions' do
|
|
include_context 'rake'
|
|
|
|
it 'should have environment as a prerequisite' do
|
|
expect(subject.prerequisites).to include('environment')
|
|
end
|
|
|
|
describe 'basic flow' do
|
|
let(:now) do
|
|
n = DateTime.now
|
|
n += 1.day until n.on_weekday?
|
|
return n
|
|
end
|
|
|
|
let(:ready_recipient_schedule) { double('ready recipient schedule', attempt_question: nil) }
|
|
let(:recipient_schedules) { double('recipient schedules', ready: [ready_recipient_schedule]) }
|
|
let(:active_schedule) { double('active schedule', recipient_schedules: recipient_schedules) }
|
|
|
|
it 'finds all active schedules' do
|
|
date = ActiveSupport::TimeZone['UTC'].parse(now.strftime('%Y-%m-%dT20:00:00%z'))
|
|
Timecop.freeze(date)
|
|
|
|
expect(ready_recipient_schedule).to receive(:attempt_question)
|
|
expect(active_schedule).to receive(:recipient_schedules)
|
|
expect(Schedule).to receive(:active).and_return([active_schedule])
|
|
subject.invoke
|
|
end
|
|
|
|
it 'works only on weekdays' do
|
|
now = DateTime.now
|
|
now += 1.day until now.on_weekend?
|
|
date = ActiveSupport::TimeZone['UTC'].parse(now.strftime('%Y-%m-%dT20:00:00%z'))
|
|
Timecop.freeze(date)
|
|
|
|
expect(ready_recipient_schedule).to_not receive(:attempt_question)
|
|
subject.invoke
|
|
end
|
|
end
|
|
|
|
xdescribe 'complex flow' do
|
|
let(:now) do
|
|
n = DateTime.now
|
|
n += 1.day until n.on_weekday?
|
|
return n
|
|
end
|
|
|
|
let!(:school) { School.create!(name: 'School') }
|
|
|
|
let!(:recipients) { create_recipients(school, 3) }
|
|
let!(:recipient_list) do
|
|
school.recipient_lists.create!(name: 'Parents', recipient_ids: recipients.map(&:id).join(','))
|
|
end
|
|
|
|
let!(:category) { Category.create(name: 'Category') }
|
|
let!(:questions) { create_questions(3, category) }
|
|
let!(:question_list) do
|
|
QuestionList.create!(name: 'Parent Questions', question_ids: questions.map(&:id).join(','))
|
|
end
|
|
|
|
let!(:schedule) do
|
|
Schedule.create!(
|
|
name: 'Parent Schedule',
|
|
recipient_list_id: recipient_list.id,
|
|
question_list: question_list,
|
|
frequency_hours: 24 * 7,
|
|
start_date: Time.new,
|
|
end_date: 1.year.from_now,
|
|
time: 1200
|
|
)
|
|
end
|
|
|
|
describe 'First attempt not at specified time' do
|
|
before :each do
|
|
now = DateTime.new
|
|
now += 1.day until now.on_weekend?
|
|
date = ActiveSupport::TimeZone['UTC'].parse(now.strftime('%Y-%m-%dT19:00:00%z'))
|
|
Timecop.freeze(date) { subject.invoke }
|
|
end
|
|
|
|
it 'should not create any attempts' do
|
|
expect(Attempt.count).to eq(0)
|
|
end
|
|
end
|
|
|
|
describe 'First attempt at specified time' do
|
|
before :each do
|
|
date = ActiveSupport::TimeZone['UTC'].parse(now.strftime('%Y-%m-%dT20:00:00%z'))
|
|
Timecop.freeze(date) { subject.invoke }
|
|
end
|
|
|
|
it 'should create the first attempt for each recipient' do
|
|
recipients.each do |recipient|
|
|
recipient.reload
|
|
expect(recipient.attempts.count).to eq(1)
|
|
attempt = recipient.attempts.first
|
|
expect(attempt.sent_at).to be_present
|
|
expect(attempt.answer_index).to be_nil
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'Second Attempts' do
|
|
before :each do
|
|
recipients.each do |recipient|
|
|
recipient_schedule = schedule.recipient_schedules.for_recipient(recipient).first
|
|
recipient_schedule.attempt_question
|
|
end
|
|
end
|
|
|
|
describe 'Immediate' do
|
|
before :each do
|
|
subject.invoke
|
|
end
|
|
|
|
it 'should do nothing' do
|
|
recipients.each do |recipient|
|
|
recipient.reload
|
|
expect(recipient.attempts.count).to eq(1)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'A Week Later' do
|
|
before :each do
|
|
recipients[1].attempts.first.update(
|
|
answer_index: 4,
|
|
responded_at: Time.new
|
|
)
|
|
Timecop.freeze(now + 7) { subject.invoke }
|
|
end
|
|
|
|
it 'should resend the first question if unanswered by a recipient' do
|
|
[recipients[0], recipients[2]].each do |recipient|
|
|
recipient.reload
|
|
expect(recipient.attempts.count).to eq(1)
|
|
attempt = recipient.attempts.last
|
|
expect(attempt.sent_at).to be > 1.day.ago
|
|
expect(attempt.answer_index).to be_nil
|
|
end
|
|
end
|
|
|
|
it 'should create the second attempt with a new question for each recipient who has answered the first question' do
|
|
recipient = recipients[1]
|
|
recipient.reload
|
|
expect(recipient.attempts.count).to eq(2)
|
|
attempt = recipient.attempts.last
|
|
expect(attempt.sent_at).to be_present
|
|
expect(attempt.answer_index).to be_nil
|
|
|
|
first_attempt = recipient.attempts.first
|
|
expect(first_attempt.question).to_not eq(attempt.question)
|
|
end
|
|
end
|
|
|
|
describe 'And Then A Recipient Answers The First Attempt' do
|
|
before :each do
|
|
recipients[1].attempts.first.save_response(answer_index: 4)
|
|
|
|
Timecop.freeze(now + 7)
|
|
recipients.each do |recipient|
|
|
recipient_schedule = schedule.recipient_schedules.for_recipient(recipient).first
|
|
recipient_schedule.attempt_question
|
|
end
|
|
|
|
@existing_message_count = FakeSMS.messages.length
|
|
|
|
Timecop.freeze(now + 8)
|
|
recipients[2].attempts.first.save_response(answer_index: 3)
|
|
subject.invoke
|
|
end
|
|
|
|
it 'should create the second attempt with a new question for each recipient who just answered the first question' do
|
|
recipient = recipients[2]
|
|
recipient.reload
|
|
expect(recipient.attempts.count).to eq(2)
|
|
attempt = recipient.attempts.last
|
|
expect(attempt.sent_at).to be_present
|
|
expect(attempt.answer_index).to be_nil
|
|
|
|
first_attempt = recipient.attempts.first
|
|
expect(first_attempt.question).to_not eq(attempt.question)
|
|
end
|
|
|
|
it 'should not send anything to anyone else' do
|
|
expect(FakeSMS.messages.length).to eq(@existing_message_count + 2)
|
|
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) do
|
|
students_recipient.recipient_schedules.for_schedule(schedule).first
|
|
end
|
|
|
|
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(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(6)
|
|
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.to_s)
|
|
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[2].body).to match(/\(for Student0\)/)
|
|
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_not match(/\(for .*\)/)
|
|
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 + 2)
|
|
expect(FakeSMS.messages[message_count].body).to match(questions.first.text)
|
|
expect(FakeSMS.messages[message_count].body).to match(/\(for Student0\)/)
|
|
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_not match(/\(for .*\)/)
|
|
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) do
|
|
students_recipient.recipient_schedules.for_schedule(schedule).first
|
|
end
|
|
|
|
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(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(6)
|
|
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
|
|
recipients[1].update(opted_out: true)
|
|
|
|
date = ActiveSupport::TimeZone['UTC'].parse(now.strftime('%Y-%m-%dT20:00:00%z'))
|
|
Timecop.freeze(date) { subject.invoke }
|
|
end
|
|
|
|
it 'should create the first attempt for each recipient' do
|
|
recipients.each_with_index do |recipient, index|
|
|
recipient.reload
|
|
if index == 1
|
|
expect(recipient.attempts.count).to eq(0)
|
|
expect(recipient.attempts.first).to be_nil
|
|
else
|
|
expect(recipient.attempts.count).to eq(1)
|
|
attempt = recipient.attempts.first
|
|
expect(attempt.sent_at).to be_present
|
|
expect(attempt.answer_index).to be_nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|