From 3deaa205d599e2c647ea34a7c99ce04654f9faec Mon Sep 17 00:00:00 2001 From: Seth Call Date: Fri, 20 May 2016 22:13:39 -0500 Subject: [PATCH] dont allow accepting slots in the past --- ruby/lib/jam_ruby/models/lesson_session.rb | 5 + ruby/lib/jam_ruby/models/user.rb | 2 +- .../flows/monthly_recurring_lesson_spec.rb | 8 +- .../spec/jam_ruby/flows/normal_lesson_spec.rb | 7 +- .../jam_ruby/models/lesson_session_spec.rb | 45 ++++- ruby/spec/support/lesson_session.rb | 170 ++++++------------ web/app/assets/javascripts/globals.js | 3 +- 7 files changed, 113 insertions(+), 127 deletions(-) diff --git a/ruby/lib/jam_ruby/models/lesson_session.rb b/ruby/lib/jam_ruby/models/lesson_session.rb index ef8600cd4..59b3d99c5 100644 --- a/ruby/lib/jam_ruby/models/lesson_session.rb +++ b/ruby/lib/jam_ruby/models/lesson_session.rb @@ -426,6 +426,11 @@ module JamRuby self.errors.add(:status, "This session is already #{self.status_was}.") end + # if this is a single lesson (testdrive, paid), but the scheduled time is before now, then it's in the past, and we have to reject + if !recurring && self.slot.scheduled_time(0) <= Time.now + self.errors.add(:slot, "is in the past") + end + if approved_before? # only checking for this on 1st time through acceptance if lesson_booking && lesson_booking.is_test_drive? && lesson_package_purchase.nil? diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index b95eb155c..e8f017756 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -2067,7 +2067,7 @@ module JamRuby LessonBooking.unprocessed(self).where(lesson_type: LessonBooking::LESSON_TYPE_PAID).first end - def most_recent_test_drive_purchase + def most_recent_test_drive_purchase lesson_purchases.where('lesson_package_type_id in (?)', LessonPackageType.test_drive_package_ids).order('created_at desc').first end diff --git a/ruby/spec/jam_ruby/flows/monthly_recurring_lesson_spec.rb b/ruby/spec/jam_ruby/flows/monthly_recurring_lesson_spec.rb index 05e707fcb..ee2aea0bf 100644 --- a/ruby/spec/jam_ruby/flows/monthly_recurring_lesson_spec.rb +++ b/ruby/spec/jam_ruby/flows/monthly_recurring_lesson_spec.rb @@ -424,10 +424,12 @@ describe "Monthly Recurring Lesson Flow" do teacher_user.affiliate_referral = affiliate_partner2 teacher_user.save! - lesson = monthly_lesson(user, teacher_user, true) + user.lesson_purchases.count.should eql 0 + lesson = monthly_lesson(user, teacher_user, {finish:true, accept:true}) user.reload + puts "user.lesson_purchases #{user.lesson_purchases}" user.lesson_purchases.count.should eql 1 lesson_package_purchase = user.lesson_purchases.first teacher_distribution = lesson_package_purchase.teacher_distribution @@ -451,7 +453,7 @@ describe "Monthly Recurring Lesson Flow" do user.affiliate_referral = affiliate_partner user.save! - lesson = monthly_lesson(user, teacher_user, true) + lesson = monthly_lesson(user, teacher_user, {finish:true, accept:true }) user.sales.count.should eql 1 user.sales[0].sale_line_items[0].affiliate_distributions.count.should eql 1 @@ -473,7 +475,7 @@ describe "Monthly Recurring Lesson Flow" do teacher_user.affiliate_referral = affiliate_partner teacher_user.save! - lesson = monthly_lesson(user, teacher_user, true) + lesson = monthly_lesson(user, teacher_user, {finish: true, accept: true}) user.sales.count.should eql 1 user.sales[0].sale_line_items[0].affiliate_distributions.count.should eql 2 diff --git a/ruby/spec/jam_ruby/flows/normal_lesson_spec.rb b/ruby/spec/jam_ruby/flows/normal_lesson_spec.rb index 6963c35bd..b9a558afd 100644 --- a/ruby/spec/jam_ruby/flows/normal_lesson_spec.rb +++ b/ruby/spec/jam_ruby/flows/normal_lesson_spec.rb @@ -573,7 +573,7 @@ describe "Normal Lesson Flow" do teacher_user.affiliate_referral = affiliate_partner2 teacher_user.save! - lesson = normal_lesson(user, teacher_user, true) + lesson = normal_lesson(user, teacher_user, {accept: true, finish:true}) user.reload user.sales.count.should eql 1 @@ -594,7 +594,8 @@ describe "Normal Lesson Flow" do user.affiliate_referral = affiliate_partner user.save! - lesson = normal_lesson(user, teacher_user, true) + lesson = normal_lesson(user, teacher_user, {accept: true, finish:true}) + lesson.errors.any?.should be_false user.sales.count.should eql 1 user.sales[0].sale_line_items[0].affiliate_distributions.count.should eql 1 @@ -612,7 +613,7 @@ describe "Normal Lesson Flow" do teacher_user.affiliate_referral = affiliate_partner teacher_user.save! - lesson = normal_lesson(user, teacher_user, true) + lesson = normal_lesson(user, teacher_user, {accept: true, finish:true}) user.sales.count.should eql 1 user.sales[0].sale_line_items[0].affiliate_distributions.count.should eql 2 diff --git a/ruby/spec/jam_ruby/models/lesson_session_spec.rb b/ruby/spec/jam_ruby/models/lesson_session_spec.rb index 3b8d62815..5ec246d8e 100644 --- a/ruby/spec/jam_ruby/models/lesson_session_spec.rb +++ b/ruby/spec/jam_ruby/models/lesson_session_spec.rb @@ -10,13 +10,56 @@ describe LessonSession do 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]} - after{Timecop.return} describe "accept" do it "can accept" do 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 + }) + 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!", + acceptor: teacher, + slot: slot + }) + lesson.errors.any?.should be_true + lesson.errors[:slot].should eql ["is in the past"] + 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) diff --git a/ruby/spec/support/lesson_session.rb b/ruby/spec/support/lesson_session.rb index e535b4686..b263ed73b 100644 --- a/ruby/spec/support/lesson_session.rb +++ b/ruby/spec/support/lesson_session.rb @@ -11,20 +11,36 @@ module StripeMock end end -def testdrive_lesson(user, teacher, options = {finish: false, accept: true, cancel: false, miss: false}) +def book_lesson(user, teacher, options) - #if slots.nil? - slots = [] - slots << FactoryGirl.build(:lesson_booking_slot_single) - slots << FactoryGirl.build(:lesson_booking_slot_single) - #end + if options[:slots].nil? + slots = [] + if options[:monthly] + slots << FactoryGirl.build(:lesson_booking_slot_recurring) + slots << FactoryGirl.build(:lesson_booking_slot_recurring) + else + slots << FactoryGirl.build(:lesson_booking_slot_single) + slots << FactoryGirl.build(:lesson_booking_slot_single) + end - if user.stored_credit_card == false - user.stored_credit_card = true - user.save! + else + slots = options[:slots] end - booking = LessonBooking.book_test_drive(user, teacher, slots, "Hey I've heard of you before.") + if user.stored_credit_card == false + token = create_stripe_token + result = user.payment_update({token: token, zip: '78759', normal: true}) + #user.stored_credit_card = true + #user.save! + end + + if options[:test_drive] + booking = LessonBooking.book_test_drive(user, teacher, slots, "Hey I've heard of you before.") + elsif options[:normal] + booking = LessonBooking.book_normal(user, teacher, slots, "Hey I've heard of you before.", false, LessonBooking::PAYMENT_STYLE_SINGLE, 60) + elsif options[:monthly] + booking = LessonBooking.book_normal(user, teacher, slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_MONTHLY, 60) + end if booking.errors.any? puts "BOOKING #{booking.errors.inspect}" end @@ -36,10 +52,13 @@ def testdrive_lesson(user, teacher, options = {finish: false, accept: true, canc booking.card_presumed_ok.should be_true - if user.most_recent_test_drive_purchase.nil? - LessonPackagePurchase.create(user, booking, LessonPackageType.test_drive_4) + if options[:test_drive] + if user.most_recent_test_drive_purchase.nil? + LessonPackagePurchase.create(user, booking, LessonPackageType.test_drive_4) + end end + if options[:accept] lesson.accept({message: 'Yeah I got this', slot: slots[0]}) lesson.errors.any?.should be_false @@ -62,7 +81,8 @@ def testdrive_lesson(user, teacher, options = {finish: false, accept: true, canc lesson.analyse lesson.session_completed - els if options[:finish] + + elsif options[:finish] # teacher & student get into session uh2 = FactoryGirl.create(:music_session_user_history, user: teacher, history: lesson.music_session, created_at: start, session_removed_at: end_time) # artificially end the session, which is covered by other background jobs @@ -74,114 +94,28 @@ def testdrive_lesson(user, teacher, options = {finish: false, accept: true, canc lesson.analyse lesson.session_completed - end - lesson -end - - -def normal_lesson(user, teacher, finish = false) - - #if slots.nil? - slots = [] - slots << FactoryGirl.build(:lesson_booking_slot_single) - slots << FactoryGirl.build(:lesson_booking_slot_single) - #end - - if user.stored_credit_card == false - token = create_stripe_token - result = user.payment_update({token: token, zip: '78759', normal: true}) - #user.stored_credit_card = true - #user.save! - end - - booking = LessonBooking.book_normal(user, teacher, slots, "Hey I've heard of you before.", false, LessonBooking::PAYMENT_STYLE_SINGLE, 60) - # puts "NORMAL BOOKING #{booking.errors.inspect}" - booking.errors.any?.should be_false - lesson = booking.lesson_sessions[0] - booking.card_presumed_ok.should be_true - - #if user.most_recent_test_drive_purchase.nil? - # LessonPackagePurchase.create(user, booking, LessonPackageType.test_drive_4) - #end - - lesson.accept({message: 'Yeah I got this', slot: slots[0]}) - lesson.errors.any?.should be_false - lesson.reload - lesson.slot.should eql slots[0] - lesson.status.should eql LessonSession::STATUS_APPROVED - lesson.music_session.should_not be_nil - - if finish - # teacher & student get into session - start = lesson.scheduled_start - end_time = lesson.scheduled_start + (60 * lesson.duration) - uh2 = FactoryGirl.create(:music_session_user_history, user: teacher_user, history: lesson.music_session, created_at: start, session_removed_at: end_time) - # artificially end the session, which is covered by other background jobs - lesson.music_session.session_removed_at = end_time - lesson.music_session.save! - - Timecop.travel(end_time + 1) - - lesson.analyse - lesson.session_completed - end - - lesson -end - - -def monthly_lesson(user, teacher, finish = true) - - slots = [] - slots << FactoryGirl.build(:lesson_booking_slot_recurring) - slots << FactoryGirl.build(:lesson_booking_slot_recurring) - - if user.stored_credit_card == false - token = create_stripe_token - result = user.payment_update({token: token, zip: '78759', normal: true}) - end - - booking = LessonBooking.book_normal(user, teacher, slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_MONTHLY, 60) - # puts "NORMAL BOOKING #{booking.errors.inspect}" - booking.errors.any?.should be_false - lesson = booking.lesson_sessions[0] - booking.card_presumed_ok.should be_true - - #if user.most_recent_test_drive_purchase.nil? - # LessonPackagePurchase.create(user, booking, LessonPackageType.test_drive_4) - #end - - lesson.accept({message: 'Yeah I got this', slot: slots[0]}) - lesson.errors.any?.should be_false - lesson.reload - lesson.slot.should eql slots[0] - lesson.status.should eql LessonSession::STATUS_APPROVED - lesson.music_session.should_not be_nil - - if finish - # teacher & student get into session - start = lesson.scheduled_start - end_time = lesson.scheduled_start + (60 * lesson.duration) - uh2 = FactoryGirl.create(:music_session_user_history, user: teacher_user, history: lesson.music_session, created_at: start, session_removed_at: end_time) - # artificially end the session, which is covered by other background jobs - lesson.music_session.session_removed_at = end_time - lesson.music_session.save! - - Timecop.travel(end_time + 1) - lesson.analyse - lesson.session_completed - - today = Date.today - if today.month == 12 - next_month = Date.new(today.year + 1, 1, 1) - else - next_month = Date.new(today.year, today.month + 1, 1) + if options[:monthly] + LessonBooking.hourly_check end - - #Timecop.travel(next_month) - LessonBooking.hourly_check end lesson +end + +def testdrive_lesson(user, teacher, options = {finish: false, accept: true, cancel: false, miss: false, slots: nil}) + options[:test_drive] = true + book_lesson(user, teacher, options) +end + + +def normal_lesson(user, teacher, options = {finish: false, accept: true, cancel: false, miss: false, slots: nil}) + options[:normal] = true + book_lesson(user, teacher, options) +end + + +def monthly_lesson(user, teacher, options = {finish: false, accept: true, cancel: false, miss: false, slots: nil}) + options[:monthly] = true + book_lesson(user, teacher, options) end \ No newline at end of file diff --git a/web/app/assets/javascripts/globals.js b/web/app/assets/javascripts/globals.js index 817ab2dad..b38aeabd7 100644 --- a/web/app/assets/javascripts/globals.js +++ b/web/app/assets/javascripts/globals.js @@ -289,7 +289,8 @@ context.JK.entityToPrintable = { - music_session: "music session" + music_session: "music session", + slot: "Requested time" } context.JK.AUDIO_DEVICE_BEHAVIOR = {