jam-cloud/ruby/spec/jam_ruby/models/lesson_booking_spec.rb

906 lines
38 KiB
Ruby

=begin
require 'spec_helper'
# collissions with teacher's schedule?
describe LessonBooking do
let(:user) { FactoryGirl.create(:user, stored_credit_card: false, remaining_free_lessons: 1, remaining_test_drives: 1) }
let(:teacher_user) { FactoryGirl.create(:teacher_user) }
let(:teacher) { teacher_user.teacher }
let(:lesson_booking_slot_single1) { FactoryGirl.build(:lesson_booking_slot_single) }
let(:lesson_booking_slot_single2) { FactoryGirl.build(:lesson_booking_slot_single) }
let(:lesson_booking_slot_recurring1) { FactoryGirl.build(:lesson_booking_slot_recurring, day_of_week: 2.days.from_now.wday) }
let(:lesson_booking_slot_recurring2) { FactoryGirl.build(:lesson_booking_slot_recurring, day_of_week: 3.days.from_now.wday) }
let(:valid_single_slots) { [lesson_booking_slot_single1, lesson_booking_slot_single2] }
let(:valid_recurring_slots) { [lesson_booking_slot_recurring1, lesson_booking_slot_recurring2] }
describe "suspend!" do
it "should set status as well as update status of all associated lesson_sessions" do
booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_MONTHLY, 60)
booking.lesson_sessions[0].accept({accepter: teacher_user, message: "got it", slot: booking.lesson_booking_slots[0].id})
booking.reload
booking.active.should eql true
booking.suspend!
booking.errors.any?.should be false
booking.reload
booking.active.should eql false
booking.status.should eql LessonBooking::STATUS_SUSPENDED
booking.lesson_sessions.count.should eql 2
booking.lesson_sessions.each do |lesson_session|
lesson_session.status.should eql LessonBooking::STATUS_SUSPENDED
end
end
end
describe "bill_monthlies" do
after do
Timecop.return
end
it "empty" do
LessonBooking.count.should eql 0
LessonBooking.bill_monthlies
LessonPackagePurchase.count.should eql 0
end
it "one" do
day = Date.new(2016, 1, 1)
time = day.to_time
Timecop.freeze(time)
booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_MONTHLY, 60)
booking.accept(booking.lesson_sessions[0], booking.lesson_booking_slots[0], teacher_user)
booking.errors.any?.should be false
LessonBooking.count.should eql 1
LessonPackagePurchase.count.should eql 0
LessonBooking.bill_monthlies
LessonPackagePurchase.count.should eql 1
purchase = LessonPackagePurchase.first
purchase.billing_error_reason.should eql "stripe"
purchase.billing_error_detail.should include("Cannot charge a customer that has no active card")
purchase.month.should eql 1
purchase.year.should eql 2016
purchase.lesson_booking.should eql booking
purchase.teacher.should eql teacher_user
purchase.user.should eql user
purchase.billed.should eql false
purchase.billed_at.should be_nil
purchase.billing_attempts.should eql 1
purchase.post_processed.should eql false
purchase.post_processed_at.should be_nil
purchase.last_billing_attempt_at.should eql time
purchase.sent_billing_notices.should eql false
# don't advance time, but nothing should happen because last_billing time hasn't elapsed
LessonBooking.bill_monthlies
LessonPackagePurchase.count.should eql 1
purchase.reload
purchase.billing_error_reason.should eql "stripe"
purchase.billing_error_detail.should include("Cannot charge a customer that has no active card")
purchase.month.should eql 1
purchase.year.should eql 2016
purchase.lesson_booking.should eql booking
purchase.teacher.should eql teacher_user
purchase.user.should eql user
purchase.billed.should eql false
purchase.billed_at.should eql nil
purchase.billing_attempts.should eql 1
purchase.post_processed.should eql false
purchase.post_processed_at.should be_nil
purchase.last_billing_attempt_at.should eql time
purchase.sent_billing_notices.should eql false
day = day + 1
time = day.to_time
Timecop.freeze(time)
LessonBooking.bill_monthlies
LessonPackagePurchase.count.should eql 1
purchase.reload
purchase.billing_error_reason.should eql "stripe"
purchase.billing_error_detail.should include("Cannot charge a customer that has no active card")
purchase.month.should eql 1
purchase.year.should eql 2016
purchase.lesson_booking.should eql booking
purchase.teacher.should eql teacher_user
purchase.user.should eql user
purchase.billed.should eql false
purchase.billed_at.should eql nil
purchase.billing_attempts.should eql 2
purchase.post_processed.should eql false
purchase.post_processed_at.should be_nil
purchase.last_billing_attempt_at.should eql time
purchase.sent_billing_notices.should eql false
user.card_approved(create_stripe_token, '78759', booking.id)
user.save!
day = day + 1
time = day.to_time
Timecop.freeze(time)
LessonBooking.bill_monthlies
LessonPackagePurchase.count.should eql 1
purchase.reload
purchase.month.should eql 1
purchase.year.should eql 2016
purchase.lesson_booking.should eql booking
purchase.teacher.should eql teacher_user
purchase.user.should eql user
purchase.billed.should eql true
purchase.billed_at.should eql time
# purchase.billing_error_reason.should be nil
purchase.billing_attempts.should eql 3
purchase.post_processed.should eql true
purchase.post_processed_at.should eql time
purchase.last_billing_attempt_at.should eql time
purchase.sent_billing_notices.should eql true
end
it "advances to next month" do
user.card_approved(create_stripe_token, '78759', nil)
user.save!
day = Date.new(2016, 1, 20)
time = day.to_time
Timecop.freeze(time)
booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_MONTHLY, 60)
booking.accept(booking.lesson_sessions[0], booking.lesson_booking_slots[0], teacher_user)
booking.errors.any?.should be false
LessonBooking.count.should eql 1
LessonPackagePurchase.count.should eql 0
LessonBooking.bill_monthlies
LessonPackagePurchase.count.should eql 1
LessonSession.count.should eql 2
purchase = LessonPackagePurchase.first
purchase.month.should eql 1
purchase.year.should eql 2016
purchase.lesson_booking.should eql booking
purchase.teacher.should eql teacher_user
purchase.user.should eql user
purchase.billed.should eql true
purchase.billed_at.should eql time
# purchase.billing_error_reason.should be nil
purchase.billing_attempts.should eql 1
purchase.post_processed.should eql true
purchase.post_processed_at.should eql time
purchase.last_billing_attempt_at.should eql time
purchase.sent_billing_notices.should eql true
day = Date.new(2016, 1, 27)
time = day.to_time
Timecop.freeze(time)
LessonBooking.schedule_upcoming_lessons
LessonSession.count.should eql 3
LessonPackagePurchase.count.should eql 1
LessonBooking.bill_monthlies
LessonPackagePurchase.count.should eql 2
purchase = LessonPackagePurchase.order(:month).last
purchase.month.should eql 2
purchase.year.should eql 2016
purchase.lesson_booking.should eql booking
purchase.teacher.should eql teacher_user
purchase.user.should eql user
purchase.billed.should eql true
purchase.billed_at.should eql time
# purchase.billing_error_reason.should be nil
purchase.billing_attempts.should eql 1
purchase.post_processed.should eql true
purchase.post_processed_at.should eql time
purchase.last_billing_attempt_at.should eql time
purchase.sent_billing_notices.should eql true
end
it "will suspend after enough tries" do
day = Date.new(2016, 1, 1)
time = day.to_time
Timecop.freeze(time)
booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_MONTHLY, 60)
booking.accept(booking.lesson_sessions[0], booking.lesson_booking_slots[0], teacher_user)
booking.errors.any?.should be false
LessonBooking.count.should eql 1
LessonPackagePurchase.count.should eql 0
LessonBooking.bill_monthlies
LessonPackagePurchase.count.should eql 1
purchase = LessonPackagePurchase.first
purchase.billing_error_reason.should eql "stripe"
purchase.billing_error_detail.should include("Cannot charge a customer that has no active card")
purchase.billing_attempts.should eql 1
booking.is_suspended?.should be_false
purchase.billed.should be false
day = day + 1
time = day.to_time
Timecop.freeze(time)
LessonBooking.bill_monthlies
LessonPackagePurchase.count.should eql 1
purchase.reload
purchase.billing_attempts.should eql 2
booking.reload
booking.is_suspended?.should be_false
purchase.billed.should be false
day = day + 1
time = day.to_time
Timecop.freeze(time)
LessonBooking.bill_monthlies
LessonPackagePurchase.count.should eql 1
purchase.reload
purchase.billing_attempts.should eql 3
booking.reload
booking.is_suspended?.should be_false
purchase.billed.should be false
day = day + 1
time = day.to_time
Timecop.freeze(time)
LessonBooking.bill_monthlies
LessonPackagePurchase.count.should eql 1
purchase.reload
purchase.billing_attempts.should eql 4
booking.reload
booking.is_suspended?.should be_false
purchase.billed.should be false
day = day + 1
time = day.to_time
Timecop.freeze(time)
LessonBooking.bill_monthlies
LessonPackagePurchase.count.should eql 1
purchase.reload
purchase.billing_attempts.should eql 5
booking.reload
booking.is_suspended?.should be_true
purchase.billed.should be false
# now that it's suspended, let's unsuspend it
user.card_approved(create_stripe_token, '78759', booking.id)
user.save!
day = day + 1
time = day.to_time
Timecop.freeze(time)
purchase.bill_monthly(true)
LessonPackagePurchase.count.should eql 1
purchase.reload
purchase.month.should eql 1
purchase.year.should eql 2016
purchase.lesson_booking.should eql booking
purchase.teacher.should eql teacher_user
purchase.user.should eql user
purchase.billed.should eql true
purchase.billed_at.should eql time
# purchase.billing_error_reason.should be nil
purchase.billing_attempts.should eql 6
purchase.post_processed.should eql true
purchase.post_processed_at.should eql time
purchase.last_billing_attempt_at.should eql time
purchase.sent_billing_notices.should eql true
booking.reload
booking.is_suspended?.should be_false
end
it "missed meetings deduct on next month" do
# TODO. Discuss with David a little more
end
end
describe "billable_monthlies" do
after do
Timecop.return
end
it "empty" do
LessonBooking.billable_monthlies(Time.now).count.should eql 0
end
it "one" do
time = Date.new(2016, 1, 1)
Timecop.freeze(time)
booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_MONTHLY, 60)
booking.accept(booking.lesson_sessions[0], booking.lesson_booking_slots[0], teacher_user)
booking.errors.any?.should be false
now = Time.now
billables = LessonBooking.billable_monthlies(now)
billables.all.to_a.should eql [booking]
LessonPackagePurchase.where(lesson_booking_id: booking.id).count.should eql 0
# to make this billable monthly go away, we will need to create one LessonPackagePurchase; one for this month (because it's only one we have lessons in)
# and further, mark them both as post_processed
package = LessonPackagePurchase.create(user, booking, LessonPackageType.single, 2016, 1)
LessonBooking.billable_monthlies(now).count.should eql 1
package.post_processed = true
package.save!
LessonBooking.billable_monthlies(now).count.should eql 0
end
end
describe "predicted_times_for_month" do
after do
Timecop.return
end
it "fills up month" do
next_year = Time.now.year + 1
jan1 = Date.new(next_year, 1, 1)
jan31 = Date.new(next_year, 1, -1)
Timecop.freeze(jan1)
slot = valid_recurring_slots[0]
slot.day_of_week = jan1.wday
booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_WEEKLY, 60)
times = booking.predicted_times_for_month(next_year, 1)[:times]
times.length.should eql 5
times[0].to_date.should eql (jan1)
times[1].to_date.should eql (Date.new(next_year, 1, 8))
times[2].to_date.should eql (Date.new(next_year, 1, 15))
times[3].to_date.should eql (Date.new(next_year, 1, 22))
times[4].to_date.should eql (Date.new(next_year, 1, 29))
end
it "fills up partial month" do
next_year = Time.now.year + 1
jan1 = Date.new(next_year, 1, 1)
jan15 = Date.new(next_year, 1, 15)
jan31 = Date.new(next_year, 1, -1)
Timecop.freeze(jan15)
slot = valid_recurring_slots[0]
slot.day_of_week = jan1.wday
booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_WEEKLY, 60)
times = booking.predicted_times_for_month(next_year, 1)[:times]
times.length.should eql 3
times[0].to_date.should eql (Date.new(next_year, 1, 15))
times[1].to_date.should eql (Date.new(next_year, 1, 22))
times[2].to_date.should eql (Date.new(next_year, 1, 29))
end
it "let's assume JamKazam is messed up for a few weeks" do
next_year = Time.now.year + 1
jan1 = Date.new(next_year, 1, 1)
jan15 = Date.new(next_year, 1, 15)
jan31 = Date.new(next_year, 1, -1)
Timecop.freeze(jan1)
slot = valid_recurring_slots[0]
slot.day_of_week = jan1.wday
# book a session on jan1
booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_WEEKLY, 60)
# but don't run the computation of times per month for weeks
Timecop.freeze(Date.new(next_year, 1, 23))
times = booking.predicted_times_for_month(next_year, 1)
times[:times].length.should eql 2
times[:times][0].to_date.should eql (Date.new(next_year, 1, 1))
times[:times][1].to_date.should eql (Date.new(next_year, 1, 29))
end
end
describe "book_free" do
it "allows long message to flow through chat" do
user.has_free_lessons?.should be_true
booking = LessonBooking.book_test_drive(user, teacher_user, valid_single_slots, Faker::Lorem.characters(10000))
booking.errors.any?.should be false
chat_message = ChatMessage.where(lesson_session_id: booking.next_lesson.id).first
chat_message.should_not be_nil
chat_message.message.should eq booking.description
end
it "prevents user without free lesson" do
pending "free not supported"
booking = LessonBooking.book_free(user, teacher_user, valid_single_slots, "Hey I've heard of you before.")
booking.errors.any?.should be false
ChatMessage.count.should eq 1
booking = LessonBooking.book_free(user, teacher_user, valid_single_slots, "Hey I've heard of you before.")
booking.errors.any?.should be true
booking.errors[:user].should eq ["have no remaining free lessons"]
ChatMessage.count.should eq 1
end
it "must have 2 lesson booking slots" do
booking = LessonBooking.book_test_drive(user, teacher_user, [], "Hey I've heard of you before.")
booking.errors.any?.should be true
booking.errors[:lesson_booking_slots].should eq ["must have two times specified"]
end
it "must have well-formed booking slots" do
bad_slot = FactoryGirl.build(:lesson_booking_slot_single, minute: nil)
booking = LessonBooking.book_free(user, teacher_user, [lesson_booking_slot_single1, bad_slot], "Hey I've heard of you before.")
booking.errors.any?.should be true
booking.errors[:lesson_booking_slots].should eq ["is invalid"]
bad_slot = booking.lesson_booking_slots[1]
bad_slot.errors[:minute].should eq ["is not a number"]
end
end
describe "book_test_drive" do
it "works" do
user.stored_credit_card = true
user.save!
booking = LessonBooking.book_test_drive(user, teacher_user, valid_single_slots, "Hey I've heard of you before.")
booking.errors.any?.should be false
booking.user.should eq user
booking.teacher.should eq teacher_user
booking.description.should eq ("Hey I've heard of you before.")
booking.payment_style.should eq LessonBooking::PAYMENT_STYLE_ELSEWHERE
booking.recurring.should eq false
booking.lesson_length.should eq 30
booking.lesson_type.should eq LessonBooking::LESSON_TYPE_TEST_DRIVE
booking.lesson_booking_slots.length.should eq 2
chat_message = ChatMessage.where(lesson_session_id: booking.next_lesson.id).first
chat_message.should_not be_nil
chat_message.message.should eq booking.description
user.reload
user.remaining_free_lessons.should eq 1
user.remaining_test_drives.should eq 0
end
it "allows long message to flow through chat" do
booking = LessonBooking.book_test_drive(user, teacher_user, valid_single_slots, Faker::Lorem.characters(10000))
booking.errors.any?.should be false
chat_message = ChatMessage.where(lesson_session_id: booking.next_lesson.id).first
chat_message.should_not be_nil
chat_message.message.should eq booking.description
end
it "prevents user without remaining test drives" do
user.stored_credit_card = true
user.save!
booking = LessonBooking.book_test_drive(user, teacher_user, valid_single_slots, "Hey I've heard of you before.")
booking.errors.any?.should be false
ChatMessage.count.should eq 1
user.reload
user.remaining_test_drives.should eql 0
booking = LessonBooking.book_test_drive(user, teacher_user, valid_single_slots, "Hey I've heard of you before.")
booking.errors.any?.should be true
booking.errors[:user].should eq ["have an in-progress or successful TestDrive with this teacher already"]
ChatMessage.count.should eq 1
end
it "must have well-formed booking slots" do
bad_slot = FactoryGirl.build(:lesson_booking_slot_single, minute: nil)
booking = LessonBooking.book_test_drive(user, teacher_user, [lesson_booking_slot_single1, bad_slot], "Hey I've heard of you before.")
booking.errors.any?.should be true
booking.errors[:lesson_booking_slots].should eq ["is invalid"]
bad_slot = booking.lesson_booking_slots[1]
bad_slot.errors[:minute].should eq ["is not a number"]
end
end
describe "book_normal" do
it "works" do
booking = LessonBooking.book_normal(user, teacher_user, valid_single_slots, "Hey I've heard of you before.", false, LessonBooking::PAYMENT_STYLE_SINGLE, 60)
booking.errors.any?.should be false
booking.user.should eq user
booking.teacher.should eq teacher_user
booking.description.should eq ("Hey I've heard of you before.")
booking.payment_style.should eq LessonBooking::PAYMENT_STYLE_SINGLE
booking.recurring.should eq false
booking.lesson_length.should eq 60
booking.lesson_type.should eq LessonBooking::LESSON_TYPE_PAID
booking.lesson_booking_slots.length.should eq 2
chat_message = ChatMessage.where(lesson_session_id: booking.next_lesson.id).first
chat_message.should_not be_nil
chat_message.message.should eq booking.description
user.reload
user.remaining_free_lessons.should eq 1
user.remaining_test_drives.should eq 1
end
it "works with recurring slots" do
booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_WEEKLY, 60)
booking.errors.any?.should be false
booking.user.should eq user
booking.teacher.should eq teacher_user
booking.description.should eq ("Hey I've heard of you before.")
booking.payment_style.should eq LessonBooking::PAYMENT_STYLE_WEEKLY
booking.recurring.should eq true
booking.lesson_length.should eq 60
booking.lesson_type.should eq LessonBooking::LESSON_TYPE_PAID
booking.lesson_booking_slots.length.should eq 2
chat_message = ChatMessage.where(lesson_session_id: booking.next_lesson.id).first
chat_message.should_not be_nil
chat_message.message.should eq booking.description
user.reload
user.remaining_free_lessons.should eq 1
user.remaining_test_drives.should eq 1
end
it "allows long message to flow through chat" do
booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, Faker::Lorem.characters(10000), true, LessonBooking::PAYMENT_STYLE_WEEKLY, 60)
booking.errors.any?.should be false
chat_message = ChatMessage.where(lesson_session_id: booking.next_lesson.id).first
chat_message.should_not be_nil
chat_message.message.should eq booking.description
end
it "does not prevent user without remaining test drives" do
booking = LessonBooking.book_test_drive(user, teacher_user, valid_single_slots, "Hey I've heard of you before.")
booking.errors.any?.should be false
ChatMessage.count.should eq 1
booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_WEEKLY, 60)
booking.errors.any?.should be false
ChatMessage.count.should eq 2
end
it "does not prevents user without free lesson" do
booking = LessonBooking.book_free(user, teacher_user, valid_single_slots, "Hey I've heard of you before.")
booking.errors.any?.should be false
ChatMessage.count.should eq 1
booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_WEEKLY, 60)
booking.errors.any?.should be false
ChatMessage.count.should eq 2
end
it "does not prevent user without a stored credit card" do
user.stored_credit_card = false
user.save!
booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_WEEKLY, 60)
booking.errors.any?.should be false
booking.card_presumed_ok.should eq false
booking.sent_notices.should eq false
end
it "must have well-formed booking slots" do
bad_slot = FactoryGirl.build(:lesson_booking_slot_recurring, day_of_week: nil)
booking = LessonBooking.book_test_drive(user, teacher_user, [lesson_booking_slot_recurring1, bad_slot], "Hey I've heard of you before.")
booking.errors.any?.should be true
booking.errors[:lesson_booking_slots].should eq ["is invalid"]
bad_slot = booking.lesson_booking_slots[1]
bad_slot.errors[:day_of_week].should eq ["must be specified"]
end
end
describe "find_bookings_needing_sessions" do
after do
Timecop.return
end
it "can detect missing lesson and schedules it 1 week out" do
booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_WEEKLY, 60)
booking.lesson_sessions.length.should eql 1
booking.accept(booking.lesson_sessions[0], booking.lesson_booking_slots[0], teacher_user)
booking.errors.any?.should be false
booking.reload
booking.lesson_sessions.length.should eql 2
lesson_session = booking.lesson_sessions[0]
Timecop.freeze(lesson_session.music_session.scheduled_start)
# causes find_bookings_needing_sessions to re-run
booking.sync_lessons
booking.reload
booking.lesson_sessions.length.should eql 3
# check that all the times make sense
lesson1 = booking.lesson_sessions[0]
lesson2 = booking.lesson_sessions[1]
lesson3 = booking.lesson_sessions[2]
lesson1.music_session.scheduled_start.to_i.should eql (lesson2.music_session.scheduled_start.to_i - (60 * 60 * 24 * 7))
lesson1.music_session.scheduled_start.to_i.should eql (lesson3.music_session.scheduled_start.to_i - (60 * 60 * 24 * 14))
Timecop.freeze(lesson2.music_session.scheduled_start)
# causes find_bookings_needing_sessions to re-run
booking.sync_lessons
booking.reload
booking.lesson_sessions.length.should eql 4
# check that all the times make sense
lesson4 = booking.lesson_sessions[3]
lesson1.music_session.scheduled_start.to_i.should eql (lesson4.music_session.scheduled_start.to_i - (60 * 60 * 24 * 21))
end
it "ignores non-recurring" do
booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", false, LessonBooking::PAYMENT_STYLE_SINGLE, 60)
booking.lesson_sessions.length.should eql 1
booking.accept(booking.lesson_sessions[0], booking.lesson_booking_slots[0], user)
booking.errors.any?.should be true
booking.errors[:accepter].should eql ["No one has been indicated as accepting the lesson"]
end
end
describe "canceling" do
after do
Timecop.return
end
it "single session gets canceled before accepted" do
booking = LessonBooking.book_normal(user, teacher_user, valid_single_slots, "Hey I've heard of you before.", false, LessonBooking::PAYMENT_STYLE_SINGLE, 60)
lesson_session = booking.lesson_sessions[0]
lesson_session.status.should eql LessonSession::STATUS_REQUESTED
lesson_session.scheduled_start.should eql booking.default_slot.scheduled_time(0)
# avoid 24 hour problem
UserMailer.deliveries.clear
Timecop.freeze(7.days.ago)
lesson_session.cancel({canceler: teacher_user, message: 'meh', slot: booking.default_slot.id, update_all: false})
lesson_session.errors.any?.should be_false
lesson_session.reload
lesson_session.status.should eql LessonSession::STATUS_CANCELED
lesson_session.reload
booking.reload
booking.status.should eql LessonSession::STATUS_CANCELED
UserMailer.deliveries.length.should eql 1
end
it "single session gets canceled after accepted" do
booking = LessonBooking.book_normal(user, teacher_user, valid_single_slots, "Hey I've heard of you before.", false, LessonBooking::PAYMENT_STYLE_SINGLE, 60)
lesson_session = booking.lesson_sessions[0]
lesson_session.status.should eql LessonSession::STATUS_REQUESTED
lesson_session.scheduled_start.should eql booking.default_slot.scheduled_time(0)
lesson_session.accept({accepter: teacher_user, message: 'Yeah I got this', slot: booking.default_slot.id, update_all: false})
lesson_session.errors.any?.should be_false
lesson_session.status.should eql LessonSession::STATUS_APPROVED
lesson_session.reload
lesson_session.scheduled_start.should eql booking.default_slot.scheduled_time(0)
UserMailer.deliveries.clear
Timecop.freeze(7.days.ago)
lesson_session.cancel({canceler: user, message: 'meh', slot: booking.default_slot.id, update_all: false})
lesson_session.errors.any?.should be_false
lesson_session.reload
lesson_session.status.should eql LessonSession::STATUS_CANCELED
booking.reload
booking.status.should eql LessonSession::STATUS_CANCELED
UserMailer.deliveries.length.should eql 2
end
it "recurring session gets canceled after accepted" do
booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_MONTHLY, 60)
booking.active.should eql false
lesson_session = booking.lesson_sessions[0]
lesson_session.status.should eql LessonSession::STATUS_REQUESTED
lesson_session.scheduled_start.should eql booking.default_slot.scheduled_time(0)
lesson_session.accept({accepter: teacher_user, message: 'Yeah I got this', slot: booking.default_slot.id, update_all: true})
lesson_session.errors.any?.should be_false
lesson_session.status.should eql LessonSession::STATUS_APPROVED
lesson_session.reload
lesson_session.scheduled_start.should eql booking.default_slot.scheduled_time(0)
booking.reload
booking.active.should eql true
booking.status.should eql LessonSession::STATUS_APPROVED
UserMailer.deliveries.clear
Timecop.freeze(7.days.ago)
lesson_session.cancel({canceler: user, message: 'meh', slot: booking.default_slot.id, update_all: false})
lesson_session.errors.any?.should be_false
lesson_session.status.should eql LessonSession::STATUS_CANCELED
lesson_session.reload
lesson_session.canceler.should eql user
booking.reload
booking.active.should eql true
booking.status.should eql LessonSession::STATUS_APPROVED
booking.canceler.should be_nil
UserMailer.deliveries.length.should eql 2
end
it "recurring booking gets canceled after accepted" do
booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_MONTHLY, 60)
lesson_session = booking.lesson_sessions[0]
lesson_session.status.should eql LessonSession::STATUS_REQUESTED
lesson_session.scheduled_start.should eql booking.default_slot.scheduled_time(0)
lesson_session.accept({accepter: teacher_user, message: 'Yeah I got this', slot: booking.default_slot.id, update_all: false})
lesson_session.errors.any?.should be_false
lesson_session.status.should eql LessonSession::STATUS_APPROVED
lesson_session.reload
lesson_session.scheduled_start.should eql booking.default_slot.scheduled_time(0)
UserMailer.deliveries.clear
Timecop.freeze(7.days.ago)
mailer = mock
mailer.should_receive(:deliver_now).exactly(2).times
UserMailer.should_receive(:student_lesson_booking_canceled).and_return(mailer)
UserMailer.should_receive(:teacher_lesson_booking_canceled).and_return(mailer)
UserMailer.should_receive(:student_lesson_canceled).exactly(0).times
UserMailer.should_receive(:teacher_lesson_canceled).exactly(0).times
lesson_session.cancel({canceler: user, message: 'meh', slot: booking.default_slot.id, update_all: true})
lesson_session.errors.any?.should be_false
lesson_session.reload
lesson_session.status.should eql LessonSession::STATUS_CANCELED
booking.reload
booking.status.should eql LessonSession::STATUS_CANCELED
booking.canceler.should eql user
end
end
describe "rescheduling" do
it "initial slot is in the past" do
booking = LessonBooking.book_normal(user, teacher_user, valid_single_slots, "Hey I've heard of you before.", false, LessonBooking::PAYMENT_STYLE_SINGLE, 60)
lesson_session = booking.lesson_sessions[0]
initial_scheduled_time = lesson_session.scheduled_start
counter = FactoryGirl.build(:lesson_booking_slot_single, preferred_day: Date.today + 20)
lesson_session.counter({proposer: user, slot: counter, message: 'ACtually, let\'s do this instead for just this one'})
Timecop.travel(initial_scheduled_time + 1)
lesson_session.accept({accepter: teacher_user, message: 'Yeah I got this', slot: counter.id, update_all: false})
booking.reload
booking.status.should eql LessonBooking::STATUS_APPROVED
booking.lesson_sessions.count.should eql 1
lesson_session.errors.any?.should be_false
lesson_session.reload
lesson_session.status.should eql LessonSession::STATUS_APPROVED
lesson_session.scheduled_start.should eql counter.scheduled_time(0)
end
it "non-recurring, accepted with new slot" do
booking = LessonBooking.book_normal(user, teacher_user, valid_single_slots, "Hey I've heard of you before.", false, LessonBooking::PAYMENT_STYLE_SINGLE, 60)
lesson_session = booking.lesson_sessions[0]
lesson_session.status.should eql LessonSession::STATUS_REQUESTED
lesson_session.scheduled_start.should eql booking.default_slot.scheduled_time(0)
counter = FactoryGirl.build(:lesson_booking_slot_single, hour: 16)
lesson_session.counter({proposer: user, slot: counter, message: 'Does this work better?'})
lesson_session.errors.any?.should be false
lesson_session.status.should eql LessonSession::STATUS_COUNTERED
lesson_session.scheduled_start.should eql booking.default_slot.scheduled_time(0)
lesson_session.counter_slot.should eql counter
booking.reload
booking.counter_slot.should be_nil
lesson_session.accept({accepter: teacher_user, message: 'Yeah I got this', slot: counter.id, update_all: false})
lesson_session.errors.any?.should be_false
lesson_session.status.should eql LessonSession::STATUS_APPROVED
lesson_session.reload
lesson_session.scheduled_start.should eql counter.scheduled_time(0)
booking.reload
booking.accepter.should eql teacher_user
booking.counter_slot.should be_nil
end
it "recurring" do
Timecop.freeze(Time.new(2016, 03, 4, 5, 0, 0))
booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_MONTHLY, 60)
lesson_session = booking.lesson_sessions[0]
lesson_session.status.should eql LessonSession::STATUS_REQUESTED
lesson_session.scheduled_start.should eql booking.default_slot.scheduled_time(0)
counter = FactoryGirl.build(:lesson_booking_slot_recurring, day_of_week: 2, update_all: true)
lesson_session.counter({proposer: user, slot: counter, message: 'Does this work better?'})
lesson_session.errors.any?.should be false
lesson_session.status.should eql LessonSession::STATUS_REQUESTED
lesson_session.scheduled_start.should eql booking.default_slot.scheduled_time(0)
booking.reload
booking.counter_slot.should eql counter
booking.counterer.should eql user
booking.has_recurring_counter?.should be true
booking.is_countered?.should be true
# to help scoot out the 'created_at' of the lessons
Timecop.freeze(Time.now + 10)
lesson_session.accept({accepter: teacher_user, message: 'Yeah I got this', slot: counter.id})
lesson_session.errors.any?.should be_false
lesson_session.status.should eql LessonSession::STATUS_APPROVED
booking.reload
booking.status.should eql LessonSession::STATUS_APPROVED
booking.has_recurring_counter?.should be false
booking.is_countered?.should be false
lesson_session.reload
lesson_session.scheduled_start.should eql counter.scheduled_time(0)
lesson_session2 = booking.lesson_sessions.order(:created_at)[1]
lesson_session2.scheduled_start.should eql counter.scheduled_time(1)
# now it's approved, we have 2 sessions that are not yet completed with a time
# we should be able to reschedule just one of the lessons
counter2 = FactoryGirl.build(:lesson_booking_slot_single, day_of_week: 4)
lesson_session.counter({proposer: user, slot: counter2, message: 'ACtually, let\'s do this instead for just this one'})
lesson_session.errors.any?.should be false
lesson_session.status.should eql LessonSession::STATUS_COUNTERED
lesson_session.has_recurring_counter?.should be false
booking.reload
booking.status.should eql LessonSession::STATUS_APPROVED
lesson_session.scheduled_start.should eql counter.scheduled_time(0)
lesson_session.accept({accepter: teacher_user, message: 'OK, lets fix just this one', slot: counter2.id})
lesson_session.errors.any?.should be_false
lesson_session.status.should eql LessonSession::STATUS_APPROVED
booking.reload
lesson_session.reload
lesson_session2.reload
lesson_session.scheduled_start.should eql counter2.scheduled_time(0)
lesson_session2.scheduled_start.should eql counter.scheduled_time(1) # STILL ORIGINAL COUNTER!
# we should be able to reschedule all of the lessons
counter3 = FactoryGirl.build(:lesson_booking_slot_recurring, day_of_week: 5, update_all: true)
lesson_session.counter({proposer: user, slot: counter3, message: 'ACtually, let\'s do this instead for just this one... again'})
lesson_session.errors.any?.should be false
lesson_session.status.should eql LessonSession::STATUS_APPROVED
lesson_session.reload
lesson_session.has_recurring_counter?.should be true
lesson_session2.reload
lesson_session2.has_recurring_counter?.should be true
lesson_session.scheduled_start.should eql counter2.scheduled_time(0)
lesson_session2.scheduled_start.should eql counter.scheduled_time(1)
booking.reload
booking.counter_slot.should eql counter3
lesson_session.accept({accepter: teacher_user, message: 'OK, lets fix all of them', slot: counter3.id})
lesson_session.errors.any?.should be_false
lesson_session.status.should eql LessonSession::STATUS_APPROVED
booking.reload
booking.counter_slot.should be_nil
lesson_session.reload
lesson_session2.reload
lesson_session.reload
lesson_session.has_recurring_counter?.should be false
lesson_session2.reload
lesson_session2.has_recurring_counter?.should be false
lesson_session.created_at.should be < lesson_session2.created_at
lesson_session.scheduled_start.should eql counter3.scheduled_time(0)
lesson_session2.scheduled_start.should eql counter3.scheduled_time(1)
end
end
end
=end