working on recipient_schedule relationships

pull/1/head
Jared Cosulich 9 years ago
parent b0e65da944
commit 64996c422a

1
.gitignore vendored

@ -19,3 +19,4 @@
# Ignore Byebug command history file.
.byebug_history
config/local_env.yml

@ -7,7 +7,6 @@ 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']

@ -1,6 +1,7 @@
class RecipientList < ApplicationRecord
belongs_to :school
validates_associated :school
validates :name, presence: true
validates :recipient_ids, presence: true

@ -4,7 +4,11 @@ class RecipientSchedule < ApplicationRecord
belongs_to :schedule
has_many :attempts
validates_associated :recipient
validates_associated :schedule
scope :ready, -> { where('next_attempt_at <= ?', Time.new) }
scope :for, -> (recipient) { where(recipient_id: recipient.id) }
def next_question
upcoming = upcoming_question_ids.split(/,/)
@ -19,8 +23,9 @@ class RecipientSchedule < ApplicationRecord
)
if attempt.send_message
return if upcoming_question_ids.blank?
upcoming = upcoming_question_ids.split(/,/)[1..-1].join(',')
attempted = (attempted_question_ids.split(/,/) + [question.id]).join(',')
attempted = ((attempted_question_ids.try(:split, /,/) || []) + [question.id]).join(',')
update_attributes(
upcoming_question_ids: upcoming,
attempted_question_ids: attempted,

@ -8,6 +8,22 @@ class Schedule < ApplicationRecord
validates :recipient_list, presence: true
validates :question_list, presence: true
after_create :create_recipient_schedules
scope :active, -> { where(active: true).where("start_date <= ? and end_date > ?", Date.today, Date.today) }
private
def create_recipient_schedules
recipient_list.recipients.each do |recipient|
question_ids = question_list.question_ids.split(/,/)
question_ids = question_ids.shuffle if random
recipient_schedules.create(
recipient: recipient,
upcoming_question_ids: question_ids.join(','),
next_attempt_at: Time.new
)
end
end
end

@ -7,10 +7,10 @@
%ul
- question_list.errors.full_messages.each do |message|
%li= message
.field
.form-group
= f.label :name
= f.text_field :name, class: 'form-control'
.field
.form-group
= f.label :description
= f.text_area :description, class: 'form-control'
.form-group

@ -1,4 +1,12 @@
Rails.application.configure do
config.before_configuration do
env_file = File.join(Rails.root, 'config', 'local_env.yml')
YAML.load(File.open(env_file)).each do |key, value|
ENV[key.to_s] = value
end if File.exists?(env_file)
end
# Settings specified here will take precedence over those in config/application.rb.
# In the development environment your application's code is reloaded on

@ -20,9 +20,17 @@ require 'rails_helper'
RSpec.describe SchedulesController, type: :controller do
let(:school) { School.create!(name: 'School') }
let(:recipient_list) { RecipientList.create!(name: 'Parents', recipient_id_array: [1, 2, 3]) }
let(:question_list) { QuestionList.create!(name: 'Parents Questions', question_id_array: [1, 2, 3]) }
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
# This should return the minimal set of attributes required to create a valid
# Schedule. As you add validations to Schedule, be sure to

@ -2,11 +2,17 @@ require 'rails_helper'
RSpec.describe Attempt, 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!(:school) { School.create!(name: 'School') }
let(:recipient) { Recipient.create!(name: 'Parent', phone: '1112223333') }
let(:recipient_list) { RecipientList.create(name: 'Parent List', recipient_ids: recipient.id.to_s)}
let!(:recipient) { create_recipients(school, 1).first }
let!(:recipient_list) do
school.recipient_lists.create!(name: 'Parents', recipient_ids: "#{recipient.id}")
end
let!(:question) { create_questions(1).first }
let!(:question_list) do
QuestionList.create!(name: 'Parent Questions', question_ids: "#{question.id}")
end
let(:schedule) { Schedule.create!(name: 'Parent Schedule', recipient_list_id: recipient_list.id, question_list: question_list) }

@ -1,8 +1,7 @@
require 'rails_helper'
describe Recipient do
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)
@ -12,6 +11,11 @@ describe Recipient do
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
it 'should delete recipient_schedules if a recipient is removed'
it 'should create recipient_schedules if a recipient is added'
end
end

@ -2,37 +2,34 @@ require 'rails_helper'
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!(:school) { School.create!(name: 'School') }
let(:recipient) { Recipient.create!(name: 'Parent', phone: '1112223333') }
let(:recipient_list) { RecipientList.create(name: 'Parent List', recipient_ids: recipient.id.to_s)}
let!(:recipient) { create_recipients(school, 1).first }
let!(:recipient_list) do
school.recipient_lists.create!(name: 'Parents', recipient_ids: "#{recipient.id}")
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
let!(:schedule) do
Schedule.create!(
name: 'Parent Schedule',
recipient_list_id: recipient_list.id,
question_list: question_list,
random: false,
frequency_hours: 24 * 7
)
end
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,
next_attempt_at: 2.weeks.ago + (60 * 60 * schedule.frequency_hours)
)
end
let!(:recipient_schedule) { schedule.recipient_schedules.for(recipient).first }
let!(:not_ready_recipient_schedule) do
RecipientSchedule.create!(
recipient: recipient,
schedule: schedule,
upcoming_question_ids: "#{question.id},3",
upcoming_question_ids: '1,3',
attempted_question_ids: '2',
last_attempt_at: 1.day.ago,
next_attempt_at: 1.day.ago + (60 * 60 * schedule.frequency_hours)
@ -50,7 +47,7 @@ RSpec.describe RecipientSchedule, type: :model do
describe 'next_question' do
it 'should provide the next question from the upcoming_question_ids list' do
expect(recipient_schedule.next_question).to eq(question)
expect(recipient_schedule.next_question).to eq(questions.first)
end
end
@ -66,17 +63,17 @@ RSpec.describe RecipientSchedule, type: :model do
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(question)
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('3')
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("2,#{question.id}")
expect(recipient_schedule.attempted_question_ids).to eq(questions.first.id.to_s)
end
it 'should update last_attempt_at' do

@ -2,7 +2,6 @@ require 'rails_helper'
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') }
@ -15,4 +14,8 @@ describe Recipient do
expect(Recipient.all.map(&:school).uniq).to eq([school])
end
end
describe "When Deleted" do
it 'should delete all recipient_schedules'
end
end

@ -2,12 +2,22 @@ require 'rails_helper'
describe Schedule do
describe "active" do
let!(:school) { School.create!(name: 'School') }
let!(:recipient_list) { RecipientList.create!(name: 'Parents', recipient_id_array: [1, 2, 3]) }
let!(:kids_recipient_list) { RecipientList.create!(name: 'Kids', recipient_id_array: [4, 5, 6]) }
let!(:question_list) { QuestionList.create!(name: 'Questions', question_id_array: [1, 2, 3]) }
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) {
{
@ -38,10 +48,15 @@ describe Schedule do
Schedule.create!(default_schedule_params.merge!(active: false))
}
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

@ -121,3 +121,29 @@ class FakeSMS
self.class.messages << Message.new(from, to, body)
end
end
def create_recipients(school, count)
recipients = []
count.times do |i|
recipients << school.recipients.create(
name: "Person#{count}",
phone: "#{count}" * 10,
)
end
return recipients
end
def create_questions(count)
questions = []
count.times do |i|
questions << Question.create(
text: "Question #{i}:#{count}",
option1: "Option #{i}:#{count} A",
option2: "Option #{i}:#{count} B",
option3: "Option #{i}:#{count} C",
option4: "Option #{i}:#{count} D",
option5: "Option #{i}:#{count} E"
)
end
return questions
end

Loading…
Cancel
Save