109 lines
3.3 KiB
Ruby
109 lines
3.3 KiB
Ruby
|
|
require "test_helper"
|
|
require "stripe"
|
|
|
|
class PayoutServiceTest < ActiveSupport::TestCase
|
|
setup do
|
|
@user = users(:one)
|
|
@event = events(:concert_event)
|
|
@payout = Payout.create!(user: @user, event: @event, amount_cents: 9000, fee_cents: 1000)
|
|
Stripe.api_key = "test_key"
|
|
end
|
|
|
|
test "process! success creates transfer and updates status" do
|
|
# Mock Stripe Transfer
|
|
Stripe::Transfer.expects(:create).with(
|
|
amount: 90, # cents to euros
|
|
currency: "eur",
|
|
destination: @user.stripe_connected_account_id,
|
|
description: "Payout for event #{@event.name}"
|
|
).returns(stub(id: "tr_123", status: "succeeded"))
|
|
|
|
@payout.update(status: :pending)
|
|
|
|
service = PayoutService.new(@payout)
|
|
service.process!
|
|
|
|
@payout.reload
|
|
assert_equal :completed, @payout.status
|
|
assert_equal "tr_123", @payout.stripe_payout_id
|
|
assert @payout.earnings.update_all(status: :paid) # assume update_earnings_status
|
|
end
|
|
|
|
test "process! failure with Stripe error sets status to failed" do
|
|
Stripe::Transfer.expects(:create).raises(Stripe::CardError.new("Insufficient funds"))
|
|
|
|
@payout.update(status: :pending)
|
|
|
|
service = PayoutService.new(@payout)
|
|
assert_raises Stripe::CardError do
|
|
service.process!
|
|
end
|
|
|
|
@payout.reload
|
|
assert_equal :failed, @payout.status
|
|
assert_not_nil @payout.error_message # assume logged
|
|
end
|
|
|
|
test "process! idempotent for already completed" do
|
|
@payout.update(status: :completed, stripe_payout_id: "tr_456")
|
|
|
|
Stripe::Transfer.expects(:create).never
|
|
|
|
service = PayoutService.new(@payout)
|
|
service.process!
|
|
|
|
@payout.reload
|
|
assert_equal :completed, @payout.status
|
|
end
|
|
|
|
test "update_earnings_status marks earnings as paid" do
|
|
earning1 = Earning.create!(event: @event, user: @user, order: orders(:one), amount_cents: 4500, fee_cents: 500, status: :pending)
|
|
earning2 = Earning.create!(event: @event, user: @user, order: orders(:two), amount_cents: 4500, fee_cents: 500, status: :pending)
|
|
@payout.earnings << earning1
|
|
@payout.earnings << earning2
|
|
|
|
service = PayoutService.new(@payout)
|
|
service.update_earnings_status(:paid)
|
|
|
|
assert_equal :paid, earning1.reload.status
|
|
assert_equal :paid, earning2.reload.status
|
|
end
|
|
|
|
test "process! handles manual processing when user has no stripe account" do
|
|
# Create a user without a stripe account
|
|
user_without_stripe = User.create!(
|
|
email: "test@example.com",
|
|
password: "password123",
|
|
is_professionnal: true
|
|
)
|
|
|
|
event = Event.create!(
|
|
user: user_without_stripe,
|
|
name: "Test Event",
|
|
slug: "test-event",
|
|
description: "Test event description",
|
|
venue_name: "Test Venue",
|
|
venue_address: "Test Address",
|
|
latitude: 48.8566,
|
|
longitude: 2.3522,
|
|
start_time: 1.day.ago,
|
|
end_time: 1.hour.ago,
|
|
state: :published
|
|
)
|
|
|
|
payout = Payout.create!(user: user_without_stripe, event: event, amount_cents: 9000, fee_cents: 1000, status: :pending)
|
|
|
|
# Mock that Stripe is not available for this user
|
|
user_without_stripe.stubs(:has_stripe_account?).returns(false)
|
|
|
|
service = PayoutService.new(payout)
|
|
service.process!
|
|
|
|
payout.reload
|
|
assert_equal :completed, payout.status
|
|
assert payout.manual_payout?
|
|
assert_match /MANUAL_/, payout.stripe_payout_id
|
|
end
|
|
end
|