require 'spec_helper' describe LessonSession do let(:user) {FactoryGirl.create(:user, stored_credit_card: true, remaining_free_lessons: 1, remaining_test_drives: 1)} let(:teacher) {FactoryGirl.create(:teacher_user)} let(:slot1) { FactoryGirl.build(:lesson_booking_slot_single) } let(:slot2) { FactoryGirl.build(:lesson_booking_slot_single) } let(:lesson_booking) {b = LessonBooking.book_normal(user, teacher, [slot1, slot2], "Hey I've heard of you before.", false, LessonBooking::PAYMENT_STYLE_SINGLE, 60); b.card_presumed_ok = true; b.save!; b} let(:lesson_session) {lesson_booking.lesson_sessions[0]} describe "counter" do describe "recurring" do it "counter madness" do lesson = monthly_lesson(user, teacher, {accept:false}) # start with the student invalid = FactoryGirl.build(:lesson_booking_slot_single, update_all: false) lesson.counter({proposer: user, message: "crumble and bumble", slot: invalid}) lesson.errors.any?.should be_true lesson.errors[:counter_slot].should eql ["Only 'update all' counter-proposals are allowed for un-approved, recurring lessons", "Only 'recurring' counter-proposals are allowed for un-approved, recurring lessons"] lesson.reload lesson.counter_slot.should be_nil counter1 = FactoryGirl.build(:lesson_booking_slot_recurring, update_all: true) lesson.counter({proposer: user, message: "crumble and bumble take 2", slot: counter1}) lesson.errors.any?.should be_false lesson.reload lesson.status.should eql LessonSession::STATUS_COUNTERED lesson.counter_slot.id.should eql counter1.id lesson.lesson_booking.counter_slot.id.should eql counter1.id counter2 = FactoryGirl.build(:lesson_booking_slot_recurring, update_all: true) lesson.counter({proposer: teacher, message: "crumble and bumble take 3", slot: counter2}) lesson.errors.any?.should be_false lesson.reload lesson.status.should eql LessonSession::STATUS_COUNTERED lesson.counter_slot.id.should eql counter2.id lesson.lesson_booking.counter_slot.id.should eql counter2.id lesson.accept({accepter: user, message: "burp", slot: counter2.id}) lesson.errors.any?.should be_false lesson.reload lesson.status.should eql LessonSession::STATUS_APPROVED counter3 = FactoryGirl.build(:lesson_booking_slot_recurring, update_all: false) lesson.counter({proposer: user, message: "crumble and bumble take 4", slot: counter3}) lesson.errors.any?.should be_false lesson.reload lesson.status.should eql LessonSession::STATUS_COUNTERED lesson.counter_slot.id.should eql counter3.id lesson.lesson_booking.counter_slot.id.should eql counter3.id counter4 = FactoryGirl.build(:lesson_booking_slot_recurring, update_all: true) lesson.counter({proposer: teacher, message: "crumble and bumble take 5", slot: counter4}) lesson.errors.any?.should be_false lesson.reload lesson.status.should eql LessonSession::STATUS_COUNTERED lesson.counter_slot.id.should eql counter4.id lesson.lesson_booking.counter_slot.id.should eql counter4.id end end end describe "autocancel" do it "can't autocancel in the past" do lesson_session.status.should eql LessonSession::STATUS_REQUESTED lesson_session.autocancel lesson_session.reload lesson_session.status.should eql LessonSession::STATUS_REQUESTED lesson_session.lesson_booking.status.should eql LessonSession::STATUS_REQUESTED end it "can't autocancel approved" do lesson_session = normal_lesson(user, teacher, {accept: true}) lesson_session.status.should eql LessonSession::STATUS_APPROVED lesson_session.autocancel lesson_session.reload lesson_session.status.should eql LessonSession::STATUS_APPROVED lesson_session.lesson_booking.status.should eql LessonSession::STATUS_APPROVED end it "autocancel works" do lesson_session.status.should eql LessonSession::STATUS_REQUESTED Timecop.travel(Date.today + 10) lesson_session.autocancel lesson_session.reload lesson_session.status.should eql LessonSession::STATUS_UNCONFIRMED lesson_session.lesson_booking.status.should eql LessonSession::STATUS_UNCONFIRMED end it "autocancel sweeper works" do lesson_session.status.should eql LessonSession::STATUS_REQUESTED Timecop.travel(Date.today + 10) LessonSession.auto_cancel lesson_session.reload lesson_session.lesson_booking.active.should be_false lesson_session.status.should eql LessonSession::STATUS_UNCONFIRMED lesson_session.lesson_booking.status.should eql LessonSession::STATUS_UNCONFIRMED end end describe "slow_responses" do it "sorts correctly" do lesson_session1 = normal_lesson(user, teacher, {counter: true, counterer: user}) lesson_session2 = normal_lesson(user, teacher, {counter: true, counterer: teacher}) # this shouldn't show up Timecop.travel(Date.today - 5) lesson_session3 = normal_lesson(user, teacher, {}) slow = LessonSession.unscoped.slow_responses slow.count.should eql 2 slow[0].should eql lesson_session3 slow[1].should eql lesson_session1 end end describe "least_time_left" do it "sorts correctly" do lesson_session1 = normal_lesson(user, teacher, {counter: true, counterer: user}) lesson_session2 = normal_lesson(user, teacher, {counter: true, counterer: teacher}) # this shouldn't show up Timecop.travel(Date.today - 5) lesson_session3 = normal_lesson(user, teacher, {}) slow = LessonSession.unscoped.least_time_left slow.count.should eql 2 slow[0].should eql lesson_session1 slow[1].should eql lesson_session3 end end describe "remind_counters" do it "finds old requested and pokes teacher" do lesson_session1 = normal_lesson(user, teacher, {}) mailer = mock mailer.should_receive(:deliver_now) UserMailer.should_receive(:teacher_counter_reminder).and_return(mailer) LessonSession.remind_counters lesson_session1.reload lesson_session1.lesson_booking.sent_counter_reminder.should be_false Timecop.travel(Date.today + 10) LessonSession.remind_counters lesson_session1.reload lesson_session1.lesson_booking.sent_counter_reminder.should be_true end it "finds old counter and pokes teacher" do lesson_session1 = normal_lesson(user, teacher, {counter: true, counterer: user}) mailer = mock mailer.should_receive(:deliver_now) UserMailer.should_receive(:teacher_counter_reminder).and_return(mailer) LessonSession.remind_counters lesson_session1.reload lesson_session1.lesson_booking.sent_counter_reminder.should be_false Timecop.travel(Date.today + 10) LessonSession.remind_counters lesson_session1.reload lesson_session1.lesson_booking.sent_counter_reminder.should be_true end it "finds old counter and pokes teacher" do lesson_session1 = normal_lesson(user, teacher, {counter: true, counterer: teacher}) mailer = mock mailer.should_receive(:deliver_now) UserMailer.should_receive(:student_counter_reminder).and_return(mailer) LessonSession.remind_counters lesson_session1.reload lesson_session1.lesson_booking.sent_counter_reminder.should be_false Timecop.travel(Date.today + 10) LessonSession.remind_counters lesson_session1.reload lesson_session1.lesson_booking.sent_counter_reminder.should be_true end end describe "accept" do it "accepts in the past is errored" do slot = FactoryGirl.build(:lesson_booking_slot_single, preferred_day: Date.today + 1) lesson = normal_lesson(user, teacher, {slots: [slot, slot2]}) Timecop.travel(Date.today + 2) lesson.accept({ message: "Teacher time!", acceptor: teacher, slot: slot.id }) lesson.errors.any?.should be_true lesson.errors[:slot].should eql ["is in the past"] end it "accepts in the past for a recurring is OK" do slotRecurring1 = FactoryGirl.build(:lesson_booking_slot_recurring) slotRecurring2 = FactoryGirl.build(:lesson_booking_slot_recurring) lesson = monthly_lesson(user, teacher, {slots: [slotRecurring1, slotRecurring2]}) Timecop.travel(Date.today + 100) lesson.accept({ message: "Teacher time!", accepter: teacher, slot: slotRecurring1.id }) lesson.errors.any?.should be_false end it "cancel in the past is OK" do slot = FactoryGirl.build(:lesson_booking_slot_single, preferred_day: Date.today + 1) lesson = normal_lesson(user, teacher, {slots: [slot, slot2]}) Timecop.travel(Date.today + 2) lesson.cancel({ message: "Cancel time!", canceler: teacher, slot: slot }) lesson.errors.any?.should be_false lesson.reload lesson.status.should eql LessonSession::STATUS_CANCELED lesson.lesson_booking.status.should eql LessonSession::STATUS_CANCELED end end describe "permissions" do it "student can join session" do lesson = normal_lesson(user, teacher) FactoryGirl.create(:active_music_session, music_session: lesson.music_session, creator: teacher) connection1 = FactoryGirl.create(:connection, user: user, music_session_id: lesson.music_session.active_music_session.id, as_musician: true) connection2 = FactoryGirl.create(:connection, user: teacher, music_session_id: lesson.music_session.active_music_session.id, as_musician: true) connection1.can_join_music_session connection1.errors.any?.should be_false connection2.can_join_music_session connection2.errors.any?.should be_false end end describe "upcoming_sessions_reminder" do it "succeeds" do lesson = normal_lesson(user, teacher) UserMailer.deliveries.clear LessonSession.upcoming_sessions_reminder #UserMailer.deliveries.count.should eql 2 lesson.touch lesson.sent_starting_notice.should be_false lesson.is_approved?.should be_true lesson.music_session.scheduled_start = 15.minutes.from_now lesson.music_session.save! LessonSession.upcoming_sessions_reminder UserMailer.deliveries.count.should eql 2 UserMailer.deliveries.clear lesson.reload lesson.sent_starting_notice.should be_true LessonSession.upcoming_sessions_reminder UserMailer.deliveries.count.should eql 0 end end describe "index" do it "finds single lesson as student" do lesson_session.touch lesson_session.music_session.creator.should eql lesson_session.lesson_booking.user lesson_session.lesson_booking.teacher.should eql teacher query = LessonSession.index(user)[:query] query.length.should eq 1 # make sure some random nobody can see this lesson session query = LessonSession.index(FactoryGirl.create(:user))[:query] query.length.should eq 0 end it "finds single lesson as teacher" do # just sanity check that the lesson_session Factory is doing what it should lesson_session.music_session.creator.should eql lesson_session.lesson_booking.user lesson_session.lesson_booking.teacher.should eql teacher query = LessonSession.index(teacher, {as_teacher: true})[:query] query.length.should eq 1 # make sure some random nobody can see this lesson session query = LessonSession.index(FactoryGirl.create(:user), {as_teacher: true})[:query] query.length.should eq 0 end describe "schools" do let (:school) {FactoryGirl.create(:school, scheduling_communication: School::SCHEDULING_COMM_SCHOOL)} describe "owner" do it "works when not a teacher" do query = LessonSession.index(school.owner, {as_teacher: true})[:query] query.length.should eql 0 teacher.teacher.school = school teacher.teacher.save! teacher.reload school.reload school.teachers.to_a.should eql [teacher.teacher] lesson = normal_lesson(user, teacher, {accept: false}) lesson.status.should eql LessonSession::STATUS_REQUESTED lesson.lesson_booking.school.should eql school school.owner.reload query = LessonSession.index(school.owner, {as_teacher: true})[:query] query.length.should eql 1 query = LessonSession.index(teacher, {as_teacher: true})[:query] query.length.should eql 0 lesson = normal_lesson(user, teacher, {accept: true}) lesson.status.should eql LessonSession::STATUS_APPROVED lesson.lesson_booking.school.should eql school query = LessonSession.index(school.owner, {as_teacher: true})[:query] query.length.should eql 1 query = LessonSession.index(teacher, {as_teacher: true})[:query] query.length.should eql 1 end end end end end