2016-04-06 02:23:15 +00:00
require 'spec_helper'
describe " TestDrive 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 ] }
before {
2016-05-12 21:29:27 +00:00
Timecop . return
2016-04-06 02:23:15 +00:00
teacher . stripe_account_id = stripe_account1_id
teacher . save!
}
it " works " do
2016-05-05 02:20:38 +00:00
user . desired_package = LessonPackageType . test_drive_2
user . save!
2016-04-06 02:23:15 +00:00
# user has no test drives, no credit card on file, but attempts to book a lesson
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 . card_presumed_ok . should be_false
booking . user . should eql user
booking . card_presumed_ok . should be_false
booking . should eql user . unprocessed_test_drive
booking . sent_notices . should be_false
2016-05-05 02:20:38 +00:00
2016-04-06 02:23:15 +00:00
user . reload
user . remaining_test_drives . should eql 0
########## Need validate their credit card
token = create_stripe_token
2016-05-05 02:20:38 +00:00
result = user . payment_update ( { token : token , zip : '78759' , test_drive : true , booking_id : booking . id } )
2016-04-06 02:23:15 +00:00
booking = result [ :lesson ]
booking . errors . any? . should be_false
2016-05-05 02:20:38 +00:00
lesson = booking . lesson_sessions [ 0 ]
2016-04-06 02:23:15 +00:00
lesson . errors . any? . should be_false
2016-05-05 02:20:38 +00:00
test_drive = result [ :test_drive ]
2016-04-06 02:23:15 +00:00
test_drive . errors . any? . should be_false
2016-05-05 02:20:38 +00:00
user . reload
user . remaining_test_drives . should eql 1
2016-04-06 02:23:15 +00:00
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 . reload
test_drive . stripe_charge_id . should_not be_nil
2016-05-05 02:20:38 +00:00
test_drive . recurly_tax_in_cents . should be 247
test_drive . recurly_total_in_cents . should eql 2999 + 247
test_drive . recurly_subtotal_in_cents . should eql 2999
2016-04-06 02:23:15 +00:00
test_drive . recurly_currency . should eql 'USD'
line_item = test_drive . sale_line_items [ 0 ]
line_item . quantity . should eql 1
line_item . product_type . should eql SaleLineItem :: LESSON
2016-05-05 02:20:38 +00:00
line_item . product_id . should eq LessonPackageType . test_drive_2 . id
2016-04-06 02:23:15 +00:00
user . reload
user . stripe_customer_id . should_not be nil
user . lesson_purchases . length . should eql 1
2016-05-05 02:20:38 +00:00
user . remaining_test_drives . should eql 1
2016-04-06 02:23:15 +00:00
lesson_purchase = user . lesson_purchases [ 0 ]
2016-05-05 02:20:38 +00:00
lesson_purchase . price . should eql 29 . 99
2016-04-06 02:23:15 +00:00
lesson_purchase . lesson_package_type . is_test_drive? . should eql true
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
teacher_countered_slot = FactoryGirl . build ( :lesson_booking_slot_single , hour : 14 )
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
######### Student counters with new slot
student_countered_slot = FactoryGirl . build ( :lesson_booking_slot_single , hour : 16 )
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
lesson_session . accept ( { message : 'Yeah I got this' , slot : student_counter . id , update_all : false } )
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
chat . message . should eql 'Yeah I got this'
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-04-21 14:23:29 +00:00
notification . message . should be_nil
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
analysis = JSON . parse ( lesson_session . analysis )
analysis [ " reason " ] . should eql LessonSessionAnalyser :: STUDENT_FAULT
analysis [ " student " ] . should eql LessonSessionAnalyser :: NO_SHOW
lesson_session . billed . should be false
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 . billing_error_reason . should be_nil
lesson_session . sent_notices . should be true
purchase = lesson_session . lesson_package_purchase
2016-05-05 02:20:38 +00:00
purchase . should_not be_nil
purchase . price_in_cents . should eql 2999
2016-04-06 02:23:15 +00:00
purchase . lesson_package_type . is_test_drive? . should be true
user . reload
2016-05-05 02:20:38 +00:00
user . remaining_test_drives . should eql 1
2016-04-06 02:23:15 +00:00
UserMailer . deliveries . length . should eql 2 # one for student, one for teacher
teacher_distribution = lesson_session . teacher_distribution
teacher_distribution . amount_in_cents . should eql 1000
teacher_distribution . ready . should be_true
teacher_distribution . distributed . should be_false
LessonBooking . hourly_check
LessonSession . hourly_check
teacher_distribution . reload
teacher_distribution . amount_in_cents . should eql 1000
teacher_distribution . ready . should be_true
teacher_distribution . distributed . should be_false
TeacherPayment . count . should eql 0
2016-04-21 14:23:29 +00:00
TeacherPayment . hourly_check
2016-04-06 02:23:15 +00:00
TeacherPayment . count . should eql 1
lesson_session . reload
purchase . reload
purchase . teacher_distribution . should be_nil
teacher_payment = TeacherPayment . first
teacher_payment . amount_in_cents . should eql 1000
teacher_payment . fee_in_cents . should eql 0
teacher_payment . teacher . should eql teacher_user
teacher_distribution . reload
teacher_distribution . amount_in_cents . should eql 1000
teacher_distribution . ready . should be_true
teacher_distribution . distributed . should be_true
teacher_payment . teacher_payment_charge . amount_in_cents . should eql 1000
teacher_payment . teacher_payment_charge . fee_in_cents . should eql 0
end
end