492 lines
20 KiB
Ruby
492 lines
20 KiB
Ruby
require 'spec_helper'
|
|
|
|
describe TeacherPayment do
|
|
|
|
let(:user) { FactoryGirl.create(:user) }
|
|
let(:user2) { FactoryGirl.create(:user) }
|
|
let(:teacher1_auth) { UserAuthorization.create(provider: 'stripe_connect', uid: stripe_account1_id, token: 'abc', refresh_token: 'abc', token_expiration: Date.today + 365, secret: 'secret') }
|
|
let(:teacher2_auth) { UserAuthorization.create(provider: 'stripe_connect', uid: stripe_account2_id, token: 'abc', refresh_token: 'abc', token_expiration: Date.today + 365, secret: 'secret') }
|
|
let(:teacher) { FactoryGirl.create(:user) }
|
|
let(:teacher2) { FactoryGirl.create(:user) }
|
|
let(:teacher_obj) { FactoryGirl.create(:teacher, user: teacher) }
|
|
let(:teacher_obj2) { FactoryGirl.create(:teacher, user: teacher2) }
|
|
|
|
let(:school_teacher) { FactoryGirl.create(:user) }
|
|
let(:school_owner_teacher) { FactoryGirl.create(:teacher, user: school_teacher) }
|
|
|
|
let(:test_drive_lesson) { testdrive_lesson(user, teacher) }
|
|
let(:test_drive_lesson2) { testdrive_lesson(user2, teacher2) }
|
|
let(:test_drive_distribution) { FactoryGirl.create(:teacher_distribution, lesson_session: test_drive_lesson, teacher: teacher, teacher_payment: nil, ready: false) }
|
|
let(:test_drive_distribution2) { FactoryGirl.create(:teacher_distribution, lesson_session: test_drive_lesson2, teacher: teacher2, teacher_payment: nil, ready: false) }
|
|
let(:normal_lesson_session) { normal_lesson(user, teacher) }
|
|
let(:normal_distribution) { FactoryGirl.create(:teacher_distribution, lesson_session: normal_lesson_session, teacher: teacher, teacher_payment: nil, ready: false) }
|
|
let(:school) { FactoryGirl.create(:school, user: school_teacher) }
|
|
|
|
describe "pending_teacher_payments" do
|
|
|
|
describe "normal teachers" do
|
|
before(:each) do
|
|
teacher_obj.touch
|
|
teacher_obj2.touch
|
|
teacher.teacher.stripe_account_id = stripe_account1_id
|
|
teacher2.teacher.stripe_account_id = stripe_account2_id
|
|
end
|
|
it "empty" do
|
|
TeacherPayment.pending_teacher_payments.count.should eql 0
|
|
end
|
|
|
|
it "one distribution" do
|
|
teacher.should eql teacher_obj.user
|
|
test_drive_distribution.touch
|
|
|
|
teacher.user_authorizations.count.should eql 1
|
|
user_auth = teacher.user_authorizations[0]
|
|
user_auth.provider.should eql 'stripe_connect'
|
|
payments = TeacherPayment.pending_teacher_payments
|
|
payments.count.should eql 0
|
|
|
|
test_drive_distribution.ready = true
|
|
test_drive_distribution.save!
|
|
test_drive_distribution.distributed.should be_false
|
|
|
|
payments = TeacherPayment.pending_teacher_payments
|
|
payments.count.should eql 1
|
|
payments[0]['id'].should eql teacher.id
|
|
end
|
|
|
|
it "multiple teachers" do
|
|
test_drive_distribution.touch
|
|
test_drive_distribution2.touch
|
|
|
|
payments = TeacherPayment.pending_teacher_payments
|
|
payments.count.should eql 0
|
|
|
|
test_drive_distribution.ready = true
|
|
test_drive_distribution.save!
|
|
test_drive_distribution2.ready = true
|
|
test_drive_distribution2.save!
|
|
|
|
payments = TeacherPayment.pending_teacher_payments
|
|
payments.count.should eql 2
|
|
payment_user_ids = payments.map(&:id)
|
|
payment_user_ids.include? teacher.id
|
|
payment_user_ids.include? teacher2.id
|
|
end
|
|
end
|
|
|
|
describe "school teachers" do
|
|
before(:each) do
|
|
teacher_obj.touch
|
|
teacher.teacher.stripe_account_id = stripe_account1_id
|
|
end
|
|
|
|
it "school distribution" do
|
|
|
|
test_drive_distribution.school = school
|
|
test_drive_distribution.save!
|
|
|
|
payments = TeacherPayment.pending_teacher_payments
|
|
payments.count.should eql 0
|
|
|
|
test_drive_distribution.ready = true
|
|
test_drive_distribution.save!
|
|
|
|
payments = TeacherPayment.pending_teacher_payments
|
|
payments.count.should eql 1
|
|
payments[0]['id'].should eql teacher.id
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
describe "teacher_payments" do
|
|
|
|
describe "normal teachers" do
|
|
before(:each) do
|
|
teacher_obj.touch
|
|
teacher_obj2.touch
|
|
teacher.teacher.stripe_account_id = stripe_account1_id
|
|
teacher2.teacher.stripe_account_id = stripe_account2_id
|
|
end
|
|
|
|
|
|
it "empty" do
|
|
TeacherPayment.teacher_payments
|
|
end
|
|
|
|
it "charges test drive" do
|
|
test_drive_distribution.touch
|
|
|
|
test_drive_distribution.ready = true
|
|
test_drive_distribution.save!
|
|
|
|
TeacherPayment.teacher_payments
|
|
|
|
test_drive_distribution.reload
|
|
test_drive_distribution.teacher_payment.should_not be_nil
|
|
TeacherPayment.count.should eql 1
|
|
|
|
payment = test_drive_distribution.teacher_payment
|
|
|
|
if payment.teacher_payment_charge.billing_error_reason
|
|
puts payment.teacher_payment_charge.billing_error_reason
|
|
puts payment.teacher_payment_charge.billing_error_detail
|
|
end
|
|
payment.teacher_payment_charge.billed.should eql true
|
|
payment.teacher_payment_charge.amount_in_cents.should eql (1000 + 1000 * APP_CONFIG.stripe[:ach_pct]).round
|
|
payment.teacher_payment_charge.fee_in_cents.should eql 0
|
|
teacher_distribution = payment.teacher_payment_charge.distribution
|
|
teacher_distribution.amount_in_cents.should eql 1000
|
|
charge = Stripe::Charge.retrieve(payment.teacher_payment_charge.stripe_charge_id)
|
|
charge.amount.should eql (1000 + 1000 * APP_CONFIG.stripe[:ach_pct]).round
|
|
charge.application_fee.should eql nil
|
|
|
|
TeacherPayment.pending_teacher_payments.count.should eql 0
|
|
end
|
|
|
|
it "charges normal" do
|
|
normal_distribution.touch
|
|
|
|
normal_distribution.ready = true
|
|
normal_distribution.save!
|
|
UserMailer.deliveries.clear
|
|
|
|
TeacherPayment.teacher_payments
|
|
|
|
normal_distribution.reload
|
|
normal_distribution.teacher_payment.should_not be_nil
|
|
TeacherPayment.count.should eql 1
|
|
|
|
payment = normal_distribution.teacher_payment
|
|
|
|
if payment.teacher_payment_charge.billing_error_reason
|
|
puts payment.teacher_payment_charge.billing_error_reason
|
|
puts payment.teacher_payment_charge.billing_error_detail
|
|
end
|
|
|
|
# only one confirm email to teacher
|
|
UserMailer.deliveries.length.should eql 1
|
|
payment.teacher_payment_charge.billed.should eql true
|
|
payment.teacher_payment_charge.amount_in_cents.should eql ((1000 * 0.72) + (1000 * 0.72) * APP_CONFIG.stripe[:ach_pct]).round
|
|
payment.teacher_payment_charge.fee_in_cents.should eql 280
|
|
payment.teacher_payment_charge.teacher.should eql teacher
|
|
teacher_distribution = payment.teacher_payment_charge.distribution
|
|
teacher_distribution.amount_in_cents.should eql 1000
|
|
charge = Stripe::Charge.retrieve(payment.teacher_payment_charge.stripe_charge_id)
|
|
charge.amount.should eql ((1000 * 0.72) + (1000 * 0.72) * APP_CONFIG.stripe[:ach_pct]).round
|
|
charge.application_fee.should be_nil
|
|
end
|
|
|
|
|
|
it "charges multiple" do
|
|
test_drive_distribution.touch
|
|
test_drive_distribution.ready = true
|
|
test_drive_distribution.save!
|
|
normal_distribution.touch
|
|
normal_distribution.ready = true
|
|
normal_distribution.save!
|
|
|
|
TeacherPayment.teacher_payments
|
|
|
|
normal_distribution.reload
|
|
normal_distribution.teacher_payment.should_not be_nil
|
|
TeacherPayment.count.should eql 2
|
|
|
|
payment = normal_distribution.teacher_payment
|
|
|
|
if payment.teacher_payment_charge.billing_error_reason
|
|
puts payment.teacher_payment_charge.billing_error_reason
|
|
puts payment.teacher_payment_charge.billing_error_detail
|
|
end
|
|
payment.teacher_payment_charge.billed.should eql true
|
|
payment.teacher_payment_charge.amount_in_cents.should eql ((1000 * 0.72) + (1000 * 0.72) * APP_CONFIG.stripe[:ach_pct]).round
|
|
payment.teacher_payment_charge.fee_in_cents.should eql 280
|
|
teacher_distribution = payment.teacher_payment_charge.distribution
|
|
teacher_distribution.amount_in_cents.should eql 1000
|
|
charge = Stripe::Charge.retrieve(payment.teacher_payment_charge.stripe_charge_id)
|
|
charge.amount.should eql ((1000 * 0.72) + (1000 * 0.72) * APP_CONFIG.stripe[:ach_pct]).round
|
|
charge.application_fee.should be_nil
|
|
|
|
test_drive_distribution.reload
|
|
payment = test_drive_distribution.teacher_payment
|
|
|
|
if payment.teacher_payment_charge.billing_error_reason
|
|
puts payment.teacher_payment_charge.billing_error_reason
|
|
puts payment.teacher_payment_charge.billing_error_detail
|
|
end
|
|
payment.teacher_payment_charge.billed.should eql true
|
|
payment.teacher_payment_charge.amount_in_cents.should eql (1000 + 1000 * APP_CONFIG.stripe[:ach_pct]).round
|
|
payment.teacher_payment_charge.fee_in_cents.should eql 0
|
|
teacher_distribution = payment.teacher_payment_charge.distribution
|
|
teacher_distribution.amount_in_cents.should eql 1000
|
|
charge = Stripe::Charge.retrieve(payment.teacher_payment_charge.stripe_charge_id)
|
|
charge.amount.should eql 1000 + (1000 * APP_CONFIG.stripe[:ach_pct]).round
|
|
charge.application_fee.should be_nil
|
|
end
|
|
|
|
|
|
end
|
|
|
|
describe "school teachers" do
|
|
before(:each) do
|
|
teacher_obj.touch
|
|
teacher.teacher.stripe_account_id = stripe_account1_id
|
|
school_owner_teacher.touch
|
|
school_teacher.teacher.stripe_account_id = stripe_account2_id
|
|
end
|
|
|
|
|
|
it "charges school" do
|
|
teacher.touch
|
|
normal_distribution.school = school
|
|
normal_distribution.ready = true
|
|
normal_distribution.save!
|
|
|
|
UserMailer.deliveries.clear
|
|
TeacherPayment.teacher_payments
|
|
|
|
normal_distribution.reload
|
|
normal_distribution.teacher_payment.should_not be_nil
|
|
normal_distribution.teacher_payment.school.should eql school
|
|
TeacherPayment.count.should eql 1
|
|
|
|
payment = normal_distribution.teacher_payment
|
|
|
|
if payment.teacher_payment_charge.billing_error_reason
|
|
puts payment.teacher_payment_charge.billing_error_reason
|
|
puts payment.teacher_payment_charge.billing_error_detail
|
|
end
|
|
# one to school owner, one to teacher
|
|
UserMailer.deliveries.length.should eql 2
|
|
payment.teacher_payment_charge.billed.should eql true
|
|
payment.teacher_payment_charge.amount_in_cents.should eql ((1000 * 0.67) + (1000 * 0.67) * APP_CONFIG.stripe[:ach_pct]).round
|
|
payment.teacher_payment_charge.fee_in_cents.should eql 330
|
|
payment.teacher_payment_charge.user.should eql school.owner
|
|
teacher_distribution = payment.teacher_payment_charge.distribution
|
|
teacher_distribution.amount_in_cents.should eql 1000
|
|
charge = Stripe::Charge.retrieve(payment.teacher_payment_charge.stripe_charge_id)
|
|
charge.destination.should_not be_nil
|
|
charge.amount.should eql 675
|
|
charge.application_fee.should be_nil
|
|
end
|
|
end
|
|
|
|
describe "stripe mocked" do
|
|
before {
|
|
StripeMock.start
|
|
}
|
|
|
|
after { StripeMock.stop }
|
|
describe "normal" do
|
|
before {
|
|
teacher_obj.touch
|
|
teacher_obj2.touch
|
|
teacher.teacher.stripe_account_id = stripe_account1_id
|
|
teacher2.teacher.stripe_account_id = stripe_account2_id
|
|
}
|
|
|
|
it "failed payment, then success" do
|
|
StripeMock.prepare_card_error(:card_declined)
|
|
|
|
normal_distribution.touch
|
|
normal_distribution.ready = true
|
|
normal_distribution.save!
|
|
|
|
TeacherPayment.teacher_payments
|
|
|
|
normal_distribution.reload
|
|
normal_distribution.teacher_payment.should_not be_nil
|
|
TeacherPayment.count.should eql 1
|
|
|
|
payment = normal_distribution.teacher_payment
|
|
|
|
payment.teacher_payment_charge.billing_error_reason.should eql("card_declined")
|
|
payment.teacher_payment_charge.billing_error_detail.should include("declined")
|
|
|
|
payment.teacher_payment_charge.billed.should eql false
|
|
payment.teacher_payment_charge.amount_in_cents.should eql ((1000 * 0.72) + (1000 * 0.72) * APP_CONFIG.stripe[:ach_pct]).round
|
|
payment.teacher_payment_charge.fee_in_cents.should eql 280
|
|
teacher_distribution = payment.teacher_payment_charge.distribution
|
|
teacher_distribution.amount_in_cents.should eql 1000
|
|
|
|
payment.teacher_payment_charge.stripe_charge_id.should be_nil
|
|
|
|
StripeMock.clear_errors
|
|
|
|
TeacherPayment.teacher_payments
|
|
|
|
normal_distribution.reload
|
|
normal_distribution.teacher_payment.should_not be_nil
|
|
TeacherPayment.count.should eql 1
|
|
|
|
# make sure the teacher_payment is reused, and charge is reused
|
|
normal_distribution.teacher_payment.should eql(payment)
|
|
normal_distribution.teacher_payment.teacher_payment_charge.should eql(payment.teacher_payment_charge)
|
|
|
|
# no attempt should be made because a day hasn't gone by
|
|
payment = normal_distribution.teacher_payment
|
|
payment.teacher_payment_charge.billed.should eql false
|
|
payment.teacher_payment_charge.amount_in_cents.should eql ((1000 * 0.72) + (1000 * 0.72) * APP_CONFIG.stripe[:ach_pct]).round
|
|
payment.teacher_payment_charge.fee_in_cents.should eql 280
|
|
teacher_distribution = payment.teacher_payment_charge.distribution
|
|
teacher_distribution.amount_in_cents.should eql 1000
|
|
|
|
# advance one day so that a charge is attempted again
|
|
Timecop.freeze(Date.today + 2)
|
|
|
|
TeacherPayment.teacher_payments
|
|
normal_distribution.reload
|
|
normal_distribution.teacher_payment.should_not be_nil
|
|
TeacherPayment.count.should eql 1
|
|
|
|
# make sure the teacher_payment is reused, and charge is reused
|
|
normal_distribution.teacher_payment.should eql(payment)
|
|
normal_distribution.teacher_payment.teacher_payment_charge.should eql(payment.teacher_payment_charge)
|
|
|
|
# no attempt should be made because a day hasn't gone by
|
|
payment = normal_distribution.teacher_payment
|
|
payment.reload
|
|
payment.teacher_payment_charge.billed.should eql true
|
|
payment.teacher_payment_charge.amount_in_cents.should eql ((1000 * 0.72) + (1000 * 0.72) * APP_CONFIG.stripe[:ach_pct]).round
|
|
payment.teacher_payment_charge.fee_in_cents.should eql 280
|
|
teacher_distribution = payment.teacher_payment_charge.distribution
|
|
teacher_distribution.amount_in_cents.should eql 1000
|
|
charge = Stripe::Charge.retrieve(payment.teacher_payment_charge.stripe_charge_id)
|
|
charge.amount.should eql 726
|
|
end
|
|
|
|
|
|
|
|
it "charges multiple (with initial failure)" do
|
|
StripeMock.prepare_card_error(:card_declined)
|
|
|
|
test_drive_distribution.touch
|
|
test_drive_distribution.ready = true
|
|
test_drive_distribution.save!
|
|
normal_distribution.touch
|
|
normal_distribution.ready = true
|
|
normal_distribution.save!
|
|
|
|
TeacherPayment.teacher_payments
|
|
|
|
TeacherPayment.count.should eql 1
|
|
payment = TeacherPayment.first
|
|
payment.teacher_payment_charge.billed.should be_false
|
|
|
|
# advance one day so that a charge is attempted again
|
|
Timecop.freeze(Date.today + 2)
|
|
|
|
StripeMock.clear_errors
|
|
TeacherPayment.teacher_payments
|
|
|
|
normal_distribution.reload
|
|
normal_distribution.teacher_payment.should_not be_nil
|
|
TeacherPayment.count.should eql 2
|
|
|
|
payment = normal_distribution.teacher_payment
|
|
|
|
payment.teacher_payment_charge.billed.should eql true
|
|
payment.teacher_payment_charge.amount_in_cents.should eql ((1000 * 0.72) + (1000 * 0.72) * APP_CONFIG.stripe[:ach_pct]).round
|
|
payment.teacher_payment_charge.fee_in_cents.should eql 280
|
|
teacher_distribution = payment.teacher_payment_charge.distribution
|
|
teacher_distribution.amount_in_cents.should eql 1000
|
|
charge = Stripe::Charge.retrieve(payment.teacher_payment_charge.stripe_charge_id)
|
|
charge.amount.should eql ((1000 * 0.72) + (1000 * 0.72) * APP_CONFIG.stripe[:ach_pct]).round
|
|
|
|
test_drive_distribution.reload
|
|
payment = test_drive_distribution.teacher_payment
|
|
|
|
payment.teacher_payment_charge.billed.should eql true
|
|
payment.teacher_payment_charge.amount_in_cents.should eql (1000 + 1000 * APP_CONFIG.stripe[:ach_pct]).round
|
|
payment.teacher_payment_charge.fee_in_cents.should eql 0
|
|
teacher_distribution = payment.teacher_payment_charge.distribution
|
|
teacher_distribution.amount_in_cents.should eql 1000
|
|
charge = Stripe::Charge.retrieve(payment.teacher_payment_charge.stripe_charge_id)
|
|
charge.amount.should eql 1000 + (1000 * APP_CONFIG.stripe[:ach_pct]).round
|
|
end
|
|
end
|
|
|
|
describe "school" do
|
|
before {
|
|
teacher_obj.touch
|
|
teacher.teacher.stripe_account_id = stripe_account1_id
|
|
school_owner_teacher.touch
|
|
school_teacher.teacher.stripe_account_id = stripe_account2_id
|
|
}
|
|
|
|
|
|
it "failed payment, then success (school)" do
|
|
StripeMock.prepare_card_error(:card_declined)
|
|
|
|
normal_distribution.school = school
|
|
normal_distribution.ready = true
|
|
normal_distribution.save!
|
|
|
|
TeacherPayment.teacher_payments
|
|
|
|
normal_distribution.reload
|
|
normal_distribution.teacher_payment.should_not be_nil
|
|
TeacherPayment.count.should eql 1
|
|
|
|
payment = normal_distribution.teacher_payment
|
|
|
|
payment.teacher_payment_charge.billing_error_reason.should eql("card_declined")
|
|
payment.teacher_payment_charge.billing_error_detail.should include("declined")
|
|
|
|
payment.teacher_payment_charge.billed.should eql false
|
|
payment.teacher_payment_charge.amount_in_cents.should eql ((1000 * 0.67) + (1000 * 0.67) * APP_CONFIG.stripe[:ach_pct]).round
|
|
payment.teacher_payment_charge.fee_in_cents.should eql 330
|
|
teacher_distribution = payment.teacher_payment_charge.distribution
|
|
teacher_distribution.amount_in_cents.should eql 1000
|
|
|
|
payment.teacher_payment_charge.stripe_charge_id.should be_nil
|
|
|
|
StripeMock.clear_errors
|
|
|
|
TeacherPayment.teacher_payments
|
|
|
|
normal_distribution.reload
|
|
normal_distribution.teacher_payment.should_not be_nil
|
|
TeacherPayment.count.should eql 1
|
|
|
|
# make sure the teacher_payment is reused, and charge is reused
|
|
normal_distribution.teacher_payment.should eql(payment)
|
|
normal_distribution.teacher_payment.teacher_payment_charge.should eql(payment.teacher_payment_charge)
|
|
|
|
# no attempt should be made because a day hasn't gone by
|
|
payment = normal_distribution.teacher_payment
|
|
payment.teacher_payment_charge.billed.should eql false
|
|
payment.teacher_payment_charge.amount_in_cents.should eql ((1000 * 0.67) + (1000 * 0.67) * APP_CONFIG.stripe[:ach_pct]).round
|
|
payment.teacher_payment_charge.fee_in_cents.should eql 330
|
|
teacher_distribution = payment.teacher_payment_charge.distribution
|
|
teacher_distribution.amount_in_cents.should eql 1000
|
|
|
|
# advance one day so that a charge is attempted again
|
|
Timecop.freeze(Date.today + 2)
|
|
|
|
TeacherPayment.teacher_payments
|
|
normal_distribution.reload
|
|
normal_distribution.teacher_payment.should_not be_nil
|
|
TeacherPayment.count.should eql 1
|
|
|
|
# make sure the teacher_payment is reused, and charge is reused
|
|
normal_distribution.teacher_payment.should eql(payment)
|
|
normal_distribution.teacher_payment.teacher_payment_charge.should eql(payment.teacher_payment_charge)
|
|
|
|
# no attempt should be made because a day hasn't gone by
|
|
payment = normal_distribution.teacher_payment
|
|
payment.reload
|
|
payment.teacher_payment_charge.billed.should eql true
|
|
payment.teacher_payment_charge.amount_in_cents.should eql ((1000 * 0.67) + (1000 * 0.67) * APP_CONFIG.stripe[:ach_pct]).round
|
|
payment.teacher_payment_charge.fee_in_cents.should eql 330
|
|
teacher_distribution = payment.teacher_payment_charge.distribution
|
|
teacher_distribution.amount_in_cents.should eql 1000
|
|
charge = Stripe::Charge.retrieve(payment.teacher_payment_charge.stripe_charge_id)
|
|
charge.amount.should eql 675
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|