merge disagreggation features

This commit is contained in:
rebuilt 2022-12-01 13:31:41 -08:00
parent 1a18837fa2
commit a2caf42fee
61 changed files with 4 additions and 3524 deletions

View file

@ -1,115 +0,0 @@
require 'rails_helper'
module Legacy
describe Attempt, type: :model do
let!(:school) { School.create!(name: 'School') }
let!(:recipient) { school.recipients.create(name: 'name', phone: '1' * 9) }
let!(:recipient_list) do
school.recipient_lists.create!(name: 'Parents', recipient_ids: recipient.id.to_s)
end
let!(:category) { Category.create(name: 'Category') }
let!(:question) { create_questions(1, category).first }
let!(:question_list) do
QuestionList.create!(name: 'Parent Questions', question_ids: question.id.to_s)
end
let(:schedule) do
Schedule.create!(name: 'Parent Schedule', recipient_list_id: recipient_list.id, question_list:)
end
let(:recipient_schedule) do
RecipientSchedule.create!(
recipient:,
schedule:,
upcoming_question_ids: "#{question.id},3",
attempted_question_ids: '2',
last_attempt_at: 2.weeks.ago,
next_attempt_at: Time.new
)
end
let!(:attempt) do
recipient.attempts.create(
schedule:,
recipient_schedule:,
question:
)
end
describe 'after_save' do
let!(:school_categories) { SchoolCategory.for(attempt.recipient.school, attempt.question.category) }
xit 'creates the associated school_category' do
expect(school_categories.count).to eq(1)
expect(school_categories.first.attempt_count).to eq(1)
expect(school_categories.first.response_count).to eq(0)
expect(school_categories.first.answer_index_total).to eq(0)
end
describe 'after_update' do
before :each do
attempt.update(answer_index: 4)
end
xit 'updates associated school_categories' do
expect(school_categories.count).to eq(1)
expect(school_categories.first.attempt_count).to eq(1)
expect(school_categories.first.response_count).to eq(1)
expect(school_categories.first.answer_index_total).to eq(4)
end
end
end
describe 'counters' do
it 'are updated when an attempt is created' do
expect(recipient.attempts_count).to eq(1)
expect(recipient.responses_count).to eq(0)
end
it 'are updated when an attempt is destroyed' do
attempt.destroy
expect(recipient.attempts_count).to eq(0)
expect(recipient.responses_count).to eq(0)
end
it 'are updated when an attempt is responded to' do
attempt.update(answer_index: 2)
expect(recipient.attempts_count).to eq(1)
expect(recipient.responses_count).to eq(1)
end
it 'are updated when an attempt is responded to with an open-ended response' do
attempt.update(open_response_id: 1)
expect(recipient.attempts_count).to eq(1)
expect(recipient.responses_count).to eq(1)
end
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(2)
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\nOption 0:1 B: 2\nOption 0:1 C: 3\nOption 0:1 D: 4\nOption 0:1 E: 5")
end
xit 'should update sent_at' do
expect(attempt.sent_at).to eq(Time.new)
end
it 'should update the recipient phone number' do
expect(attempt.recipient.reload.phone).to eq('+1111111111')
end
end
end
end

View file

@ -1,20 +0,0 @@
require 'rails_helper'
module Legacy
RSpec.describe District, type: :model do
let(:district1) { District.create(name: 'District one', state_id: 32) }
let(:district2) { District.new(name: 'District two', state_id: 32) }
context 'when saving or creating' do
it 'should return a slug' do
expect(district1.slug).to eq 'district-one'
district2.save
expect(district2.slug).to eq 'district-two'
first_district = District.find_by_slug('district-one')
expect(first_district.slug).to eq 'district-one'
end
end
end
end

View file

@ -1,67 +0,0 @@
require 'rails_helper'
module Legacy
RSpec.describe Question, type: :model do
let!(:school1) { School.create!(name: 'School 1') }
let!(:school2) { School.create!(name: 'School 2') }
let!(:school1recipients) { create_recipients(school1, 5) }
let!(:school2recipients) { create_recipients(school2, 4) }
let!(:category1) { Category.create!(name: 'Resources') }
let!(:category2) { Category.create!(name: 'Category 2') }
let!(:category1questions) { create_questions(3, category1) }
let!(:category2questions) { create_questions(3, category2) }
let(:question) { category1questions.first }
let!(:attempt1) do
Legacy::Attempt.create!(question: category1questions[0], recipient: school1recipients[0], answer_index: 3)
end
let!(:attempt2) do
Legacy::Attempt.create!(question: category1questions[0], recipient: school1recipients[1], answer_index: 2)
end
let!(:attempt3) { Legacy::Attempt.create!(question: category1questions[0], recipient: school1recipients[2]) }
let!(:attempt4) do
Legacy::Attempt.create!(question: category1questions[0], recipient: school1recipients[3], answer_index: 3)
end
let!(:attempt5) do
Legacy::Attempt.create!(question: category1questions[0], recipient: school2recipients[0], answer_index: 4)
end
let!(:attempt6) do
Legacy::Attempt.create!(question: category1questions[1], recipient: school1recipients[0], answer_index: 5)
end
let!(:attempt7) do
Legacy::Attempt.create!(question: category1questions[2], recipient: school1recipients[0], answer_index: 5)
end
let!(:attempt8) do
Legacy::Attempt.create!(question: category2questions[0], recipient: school1recipients[0], answer_index: 3)
end
let!(:attempt9) do
Legacy::Attempt.create!(question: category2questions[1], recipient: school1recipients[1], answer_index: 1)
end
describe 'aggregated_responses_for_school' do
let(:aggregated_responses) { question.aggregated_responses_for_school(school1) }
it 'aggregates all attempts with responses for the question for a given school' do
expect(aggregated_responses.count).to eq(3)
expect(aggregated_responses.responses.to_a).to eq([attempt1, attempt2, attempt4])
expect(aggregated_responses.answer_index_total).to eq(8)
end
it 'should calculate answer_index_average' do
expect(aggregated_responses.answer_index_average).to eq(8.0 / 3)
end
it 'should calculate the most popular answer' do
expect(aggregated_responses.most_popular_answer).to eq(question.option3)
end
it 'should provide access to the question and category' do
expect(aggregated_responses.question).to eq(question)
expect(aggregated_responses.category).to eq(question.category)
end
end
end
end

View file

@ -1,55 +0,0 @@
require 'rails_helper'
module Legacy
describe RecipientList do
describe 'Save' do
it 'should convert the recipient_id_array into the recipient_ids attribute' do
recipient_list = RecipientList.create(name: 'Name', recipient_id_array: ['', '1', '2', '3'])
expect(recipient_list).to be_a(RecipientList)
expect(recipient_list).to be_persisted
expect(recipient_list.recipient_ids).to eq('1,2,3')
recipient_list.update(recipient_id_array: ['3', '', '4', '5', '6'])
expect(recipient_list.reload.recipient_ids).to eq('3,4,5,6')
end
end
describe 'when edited' do
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!(:questions) { create_questions(3) }
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:,
random: false,
frequency_hours: 24 * 7
)
end
it 'should delete recipient_schedules if a recipient is removed' do
modified_recipient_ids = recipients.map(&:id)[0, 2].join(',')
expect do
recipient_list.update(recipient_ids: modified_recipient_ids)
end.to change { schedule.recipient_schedules.count }.from(3).to(2)
end
it 'should create recipient_schedules if a recipient is added' do
new_recipients = create_recipients(school, 2)
expect do
recipient_list.update(recipient_ids: (recipients + new_recipients).map(&:id).join(','))
end.to change { schedule.recipient_schedules.count }.from(3).to(5)
end
end
end
end

View file

@ -1,134 +0,0 @@
require 'rails_helper'
module Legacy
RSpec.describe RecipientSchedule, type: :model do
let!(:school) { School.create!(name: 'School') }
let!(:recipient) { create_recipients(school, 1).first }
let!(:recipient_list) do
school.recipient_lists.create!(name: 'Parents', recipient_ids: recipient.id.to_s)
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:,
random: false,
frequency_hours: 24
)
end
let!(:recipient_schedule) { schedule.recipient_schedules.for_recipient(recipient).first }
let!(:not_ready_recipient_schedule) do
RecipientSchedule.create!(
recipient:,
schedule:,
upcoming_question_ids: '1,3',
attempted_question_ids: '2',
last_attempt_at: Date.today + (60 * 60 * schedule.frequency_hours),
next_attempt_at: 1.day.from_now + (60 * 60 * schedule.frequency_hours)
)
end
xdescribe 'ready' do
before :each do
now = DateTime.now
date = ActiveSupport::TimeZone['UTC'].parse(now.strftime('%Y-%m-%dT16:00:00%z'))
Timecop.freeze(date)
end
subject { schedule.recipient_schedules.ready }
it('should only provide recipient_schedules who are ready to send a message') do
expect(subject.length).to eq(1)
expect(subject.first).to eq(recipient_schedule)
end
end
describe 'next_question' do
it 'should provide the next question from the upcoming_question_ids list' do
expect(recipient_schedule.next_question).to eq(questions.first)
end
end
describe 'attempt_question' do
before :each do
Timecop.freeze
end
describe 'with an opted out recipient' do
before :each do
recipient_schedule.recipient.update(opted_out: true)
end
let!(:attempt) { recipient_schedule.attempt_question }
it 'should not do anything' do
expect(attempt).to be_nil
end
end
describe 'right before a weekend' do
before :each do
friday_time = ActiveSupport::TimeZone['UTC'].parse('2017-04-21T20:00:00')
Timecop.freeze
recipient_schedule.update(next_attempt_at: friday_time)
end
let!(:attempt) { recipient_schedule.attempt_question }
it 'should schedule the next attempt for after the weekend' do
next_weekday_time = ActiveSupport::TimeZone['UTC'].parse('2017-04-24T20:00:00')
expect(recipient_schedule.reload.next_attempt_at).to eq(next_weekday_time)
end
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
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)
expect(attempt.question).to eq(questions.first)
expect(attempt.sent_at.to_i).to eq(Time.new.to_i)
expect(attempt.answer_index).to be_nil
end
it 'should update the upcoming_questions_ids' do
expect(recipient_schedule.upcoming_question_ids).to eq(questions[1..2].map(&:id).join(','))
end
it 'should update the attempted_question_ids' do
expect(recipient_schedule.attempted_question_ids).to eq(questions.first.id.to_s)
end
it 'should update last_attempt_at' do
expect(recipient_schedule.last_attempt_at.to_i).to eq(Time.new.to_i)
end
it 'should update next_attempt_at' do
now = DateTime.now
date = ActiveSupport::TimeZone['Eastern Time (US & Canada)'].parse(now.strftime('%Y-%m-%dT16:00:00%z'))
date += 1.day
date += 1.day if date.on_weekend?
expect(recipient_schedule.reload.next_attempt_at).to eq(date.to_time)
end
end
end
end
end

View file

@ -1,51 +0,0 @@
require 'rails_helper'
module Legacy
describe Recipient do
describe 'Import' do
let(:school) { School.create!(name: 'School') }
let(:data) { "name,phone\rJared,111-222-333\rLauren,222-333-4444\rAbby,333-444-5555\r" }
let(:file) { instance_double('File', path: 'path') }
xit 'should parse file contents and return a result' do
expect(File).to receive(:open).with('path', universal_newline: false, headers: true) { StringIO.new(data) }
Recipient.import(school, file)
expect(Recipient.count).to eq(3)
expect(Recipient.all.map(&:name)).to eq(%w[Jared Lauren Abby])
expect(Recipient.all.map(&:school).uniq).to eq([school])
end
end
describe 'When Deleted' do
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!(:questions) { create_questions(3) }
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:,
random: false,
frequency_hours: 24 * 7
)
end
it 'should delete all recipient_schedules and update all recipient_lists' do
expect do
recipients[1].destroy
end.to change { schedule.recipient_schedules.count }.from(3).to(2)
expect(recipient_list.recipient_ids).to eq("#{recipients[0].id},#{recipients[2].id}")
end
end
end
end

View file

@ -1,62 +0,0 @@
require 'rails_helper'
module Legacy
describe Schedule do
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!(:kid_recipients) { create_recipients(school, 3) }
let!(:kids_recipient_list) do
school.recipient_lists.create!(name: 'Kids', recipient_ids: kid_recipients.map(&:id).join(','))
end
let!(:questions) { create_questions(3) }
let!(:question_list) do
QuestionList.create!(name: 'Questions', question_ids: questions.map(&:id).join(','))
end
let(:default_schedule_params) do
{
school:,
recipient_list:,
question_list:,
name: 'Parents Schedule',
description: 'Schedule for parent questions',
start_date: 1.month.ago,
end_date: 11.months.from_now,
active: true
}
end
let!(:active_schedule) do
Schedule.create!(default_schedule_params)
end
let!(:active_schedule_kids) do
Schedule.create!(default_schedule_params.merge!(name: 'Kids Schedule', recipient_list: kids_recipient_list))
end
let!(:old_schedule) do
Schedule.create!(default_schedule_params.merge!(start_date: 13.month.ago, end_date: 1.months.ago))
end
let!(:paused_schedule) do
Schedule.create!(default_schedule_params.merge!(active: false))
end
describe 'active' do
it 'finds active schedules' do
active = Schedule.active
expect(active.length).to eq(2)
end
end
it 'creates a recipient_schedule for every recipient when created' do
expect(active_schedule.recipient_schedules.length).to eq(3)
end
end
end

View file

@ -1,94 +0,0 @@
require 'rails_helper'
module Legacy
RSpec.describe SchoolCategory, type: :model do
let!(:school1) { School.create!(name: 'School 1') }
let!(:school2) { School.create!(name: 'School 2') }
let!(:school1recipients) { create_recipients(school1, 4) }
let!(:school2recipients) { create_recipients(school2, 4) }
let!(:category1) { Category.create!(name: 'Category 1') }
let!(:category2) { Category.create!(name: 'Category 2') }
let!(:category1questions) { create_questions(3, category1) }
let!(:category2questions) { create_questions(3, category2) }
let!(:attempt1) do
Attempt.create!(question: category1questions[0], recipient: school1recipients[0], answer_index: 2)
end
let!(:attempt2) { Attempt.create!(question: category1questions[0], recipient: school1recipients[1]) }
let!(:attempt3) do
Attempt.create!(question: category1questions[0], recipient: school1recipients[2], answer_index: 3)
end
let!(:attempt4) do
Attempt.create!(question: category1questions[0], recipient: school2recipients[0], answer_index: 4)
end
let!(:attempt5) do
Attempt.create!(question: category1questions[1], recipient: school1recipients[0], answer_index: 5)
end
let!(:attempt6) do
Attempt.create!(question: category1questions[2], recipient: school1recipients[0], answer_index: 5)
end
let!(:attempt7) do
Attempt.create!(question: category2questions[0], recipient: school1recipients[0], answer_index: 3)
end
let!(:attempt8) do
Attempt.create!(question: category2questions[1], recipient: school1recipients[1], answer_index: 1)
end
let!(:school_category1) { SchoolCategory.for(school1, category1).first }
describe 'aggregated_responses' do
xit 'should provide the count and sum of all attempts' do
expect(school_category1.aggregated_responses).to eq(
attempt_count: 5,
response_count: 4,
answer_index_total: 15
)
end
end
describe 'answer_index_average' do
xit 'should provide the average answer_index for all responses' do
expect(school_category1.answer_index_average).to eq(15.0 / 4.0)
end
end
describe 'sync_aggregated_responses' do
let!(:category3) { Category.create!(name: 'Category 3', parent_category: category1) }
let!(:category3questions) { create_questions(3, category3) }
let!(:attempt7) do
Attempt.create!(question: category3questions[0], recipient: school1recipients[0], answer_index: 4)
end
let!(:attempt8) do
Attempt.create!(question: category3questions[0], recipient: school1recipients[1], answer_index: 1)
end
let!(:attempt9) { Attempt.create!(question: category3questions[0], recipient: school1recipients[2]) }
let!(:attempt10) do
Attempt.create!(question: category3questions[1], recipient: school1recipients[1], answer_index: 5)
end
let!(:attempt11) do
Attempt.create!(question: category3questions[1], recipient: school2recipients[0], answer_index: 5)
end
let!(:school_category3) { SchoolCategory.for(school1, category3).first }
xit 'should update attributes and parent_category school_category attributes' do
school_category3.sync_aggregated_responses
school_category3.reload
expect(school_category3.attempt_count).to eq(4)
expect(school_category3.response_count).to eq(3)
expect(school_category3.answer_index_total).to eq(10)
school_category1.reload
expect(school_category1.attempt_count).to eq(9)
expect(school_category1.response_count).to eq(7)
expect(school_category1.answer_index_total).to eq(25)
end
end
end
end

View file

@ -1,7 +0,0 @@
require 'rails_helper'
module Legacy
RSpec.describe UserSchool, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end
end