2016-04-06 02:23:15 +00:00
require 'spec_helper'
describe " Recurring Lesson Flow " do
let ( :user ) { FactoryGirl . create ( :user , remaining_test_drives : 0 ) }
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 ) }
let ( :lesson_booking_slot_recurring2 ) { FactoryGirl . build ( :lesson_booking_slot_recurring ) }
let ( :valid_single_slots ) { [ lesson_booking_slot_single1 , lesson_booking_slot_single2 ] }
let ( :valid_recurring_slots ) { [ lesson_booking_slot_recurring1 , lesson_booking_slot_recurring2 ] }
2016-05-16 16:39:20 +00:00
after ( :each ) do
2016-05-12 21:29:27 +00:00
Timecop . return
end
2016-04-06 02:23:15 +00:00
it " works " do
# user has no test drives, no credit card on file, but attempts to book a lesson
booking = LessonBooking . book_normal ( user , teacher_user , valid_recurring_slots , " Hey I've heard of you before. " , true , LessonBooking :: PAYMENT_STYLE_SINGLE , 60 )
booking . errors . any? . should be_false
booking . card_presumed_ok . should be_false
booking . user . should eql user
booking . card_presumed_ok . should be_false
booking . should eql user . unprocessed_normal_lesson
booking . sent_notices . should be_false
booking . booked_price . should eql 30 . 00
########## Need validate their credit card
token = create_stripe_token
2016-05-12 21:29:27 +00:00
result = user . payment_update ( { token : token , zip : '78759' , normal : true , booking_id : booking . id } )
2016-04-06 02:23:15 +00:00
booking = result [ :lesson ]
lesson = booking . lesson_sessions [ 0 ]
booking . errors . any? . should be_false
lesson . errors . any? . should be_false
booking . card_presumed_ok . should be_true
booking . sent_notices . should be_true
lesson . music_session . scheduled_start . should eql booking . default_slot . scheduled_time ( 0 )
lesson . amount_charged . should be 0 . 0
lesson . reload
user . reload
user . stripe_customer_id . should_not be nil
user . remaining_test_drives . should eql 0
user . lesson_purchases . length . should eql 0
customer = Stripe :: Customer . retrieve ( user . stripe_customer_id )
customer . email . should eql user . email
booking . lesson_sessions . length . should eql 1
lesson_session = booking . lesson_sessions [ 0 ]
lesson_session . status . should eql LessonBooking :: STATUS_REQUESTED
booking . status . should eql LessonBooking :: STATUS_REQUESTED
######### Teacher counters with new slot
2016-05-31 16:13:49 +00:00
teacher_countered_slot = FactoryGirl . build ( :lesson_booking_slot_recurring , hour : 14 , update_all : true )
2016-04-06 02:23:15 +00:00
UserMailer . deliveries . clear
lesson_session . counter ( { proposer : teacher_user , slot : teacher_countered_slot , message : 'Does this work?' } )
booking . reload
booking . errors . any? . should be false
lesson_session . lesson_booking . errors . any? . should be false
lesson_session . lesson_booking_slots . length . should eql 1
lesson_session . lesson_booking_slots [ 0 ] . proposer . should eql teacher_user
teacher_counter = lesson_session . lesson_booking_slots . order ( :created_at ) . last
teacher_counter . should eql teacher_countered_slot
teacher_counter . proposer . should eql teacher_user
booking . lesson_booking_slots . length . should eql 3
UserMailer . deliveries . length . should eql 1
chat = ChatMessage . unscoped . order ( :created_at ) . last
chat . channel . should eql ChatMessage :: CHANNEL_LESSON
chat . message . should eql 'Does this work?'
chat . user . should eql teacher_user
chat . target_user . should eql user
notification = Notification . unscoped . order ( :created_at ) . last
notification . session_id . should eql lesson_session . music_session . id
notification . student_directed . should eql true
notification . purpose . should eql 'counter'
notification . description . should eql NotificationTypes :: LESSON_MESSAGE
#notification.message.should eql "Instructor has proposed a different time for your lesson."
######### Student counters with new slot
2016-05-31 16:13:49 +00:00
student_countered_slot = FactoryGirl . build ( :lesson_booking_slot_recurring , hour : 16 , update_all : true )
2016-04-06 02:23:15 +00:00
UserMailer . deliveries . clear
lesson_session . counter ( { proposer : user , slot : student_countered_slot , message : 'Does this work better?' } )
lesson_session . errors . any? . should be false
lesson_session . lesson_booking . errors . any? . should be false
lesson_session . lesson_booking_slots . length . should eql 2
student_counter = booking . lesson_booking_slots . order ( :created_at ) . last
student_counter . proposer . should eql user
booking . reload
booking . lesson_booking_slots . length . should eql 4
UserMailer . deliveries . length . should eql 1
chat = ChatMessage . unscoped . order ( :created_at ) . last
chat . message . should eql 'Does this work better?'
chat . channel . should eql ChatMessage :: CHANNEL_LESSON
chat . user . should eql user
chat . target_user . should eql teacher_user
notification = Notification . unscoped . order ( :created_at ) . last
notification . session_id . should eql lesson_session . music_session . id
notification . student_directed . should eql false
notification . purpose . should eql 'counter'
notification . description . should eql NotificationTypes :: LESSON_MESSAGE
######## Teacher accepts slot
UserMailer . deliveries . clear
2016-05-31 16:13:49 +00:00
lesson_session . accept ( { message : 'Yeah I got this' , slot : student_counter . id , accepter : teacher_user } )
2016-04-06 02:23:15 +00:00
UserMailer . deliveries . each do | del |
# puts del.inspect
end
# get acceptance emails, as well as 'your stuff is accepted'
2016-04-21 14:23:29 +00:00
UserMailer . deliveries . length . should eql 2
2016-04-06 02:23:15 +00:00
lesson_session . errors . any? . should be_false
lesson_session . reload
lesson_session . slot . should eql student_counter
lesson_session . status . should eql LessonSession :: STATUS_APPROVED
booking . reload
booking . default_slot . should eql student_counter
lesson_session . music_session . scheduled_start . should eql booking . default_slot . scheduled_time ( 0 )
booking . status . should eql LessonBooking :: STATUS_APPROVED
2016-04-21 14:23:29 +00:00
UserMailer . deliveries . length . should eql 2
2016-04-06 02:23:15 +00:00
chat = ChatMessage . unscoped . order ( :created_at ) . last
2016-04-21 14:23:29 +00:00
chat . message . should eql " Yeah I got this "
chat . purpose . should eql 'Lesson Approved'
2016-04-06 02:23:15 +00:00
chat . channel . should eql ChatMessage :: CHANNEL_LESSON
chat . user . should eql teacher_user
chat . target_user . should eql user
notification = Notification . unscoped . order ( :created_at ) . last
notification . session_id . should eql lesson_session . music_session . id
notification . student_directed . should eql true
notification . purpose . should eql 'accept'
notification . description . should eql NotificationTypes :: LESSON_MESSAGE
2016-05-31 13:35:04 +00:00
user . reload
user . sales . length . should eql 0
2016-04-06 02:23:15 +00:00
2016-05-31 16:13:49 +00:00
booking . reload
booking . lesson_sessions [ 0 ] . scheduled_start . should_not eql booking . lesson_sessions [ 1 ] . scheduled_start
2016-04-06 02:23:15 +00:00
# teacher & student get into session
start = lesson_session . scheduled_start
end_time = lesson_session . scheduled_start + ( 60 * lesson_session . duration )
uh2 = FactoryGirl . create ( :music_session_user_history , user : teacher_user , history : lesson_session . music_session , created_at : start , session_removed_at : end_time )
# artificially end the session, which is covered by other background jobs
lesson_session . music_session . session_removed_at = end_time
lesson_session . music_session . save!
2016-05-12 21:29:27 +00:00
Timecop . travel ( end_time + 1 )
2016-04-06 02:23:15 +00:00
UserMailer . deliveries . clear
# background code comes around and analyses the session
LessonSession . hourly_check
lesson_session . reload
lesson_session . analysed . should be_true
2016-07-17 15:16:27 +00:00
analysis = lesson_session . analysis
2016-04-06 02:23:15 +00:00
analysis [ " reason " ] . should eql LessonSessionAnalyser :: STUDENT_FAULT
analysis [ " student " ] . should eql LessonSessionAnalyser :: NO_SHOW
if lesson_session . billing_error_detail
puts " testdrive flow #{ lesson_session . billing_error_detail } " # this should not occur, but helps a great deal if a regression occurs and running all the tests
end
lesson_session . billed . should be true
user . reload
user . lesson_purchases . length . should eql 1
lesson_purchase = user . lesson_purchases [ 0 ]
lesson_purchase . price . should eql 30 . 00
lesson_purchase . lesson_package_type . is_normal? . should eql true
lesson_purchase . price_in_cents . should eql 3000
user . sales . length . should eql 1
sale = user . sales . first
sale . stripe_charge_id . should_not be_nil
sale . recurly_tax_in_cents . should eql ( 100 * booking . booked_price . to_f * 0 . 0825 ) . round . to_i
sale . recurly_total_in_cents . should eql ( ( 100 * booking . booked_price . to_f * 0 . 0825 ) . round + 100 * booking . booked_price . to_f ) . to_i
sale . recurly_subtotal_in_cents . should eql ( 100 * booking . booked_price ) . to_i
sale . recurly_currency . should eql 'USD'
sale . stripe_charge_id . should_not be_nil
line_item = sale . sale_line_items [ 0 ]
line_item . quantity . should eql 1
line_item . product_type . should eql SaleLineItem :: LESSON
line_item . product_id . should eq LessonPackageType . single . id
line_item . lesson_package_purchase . should eql lesson_purchase
lesson_purchase . sale_line_item . should eql line_item
lesson . amount_charged . should eql ( sale . recurly_total_in_cents / 100 . 0 ) . to_f
lesson_session . billing_error_reason . should be_nil
lesson_session . sent_billing_notices . should be true
user . reload
user . remaining_test_drives . should eql 0
2016-05-31 13:35:04 +00:00
UserMailer . deliveries . each do | d |
puts d . subject
end
2016-04-06 02:23:15 +00:00
UserMailer . deliveries . length . should eql 2 # one for student, one for teacher
end
end