155 lines
5.7 KiB
Ruby
155 lines
5.7 KiB
Ruby
require "test_helper"
|
|
|
|
class PayoutTest < ActiveSupport::TestCase
|
|
setup do
|
|
@user = User.create!(email: "test@example.com", password: "password123", is_professionnal: true)
|
|
@event = Event.create!(
|
|
user: @user,
|
|
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
|
|
)
|
|
# Create some earnings for the event
|
|
Earning.create!(event: @event, user: @user, order: Order.create!(user: @user, event: @event, status: :paid, total_amount_cents: 1000), amount_cents: 2000, fee_cents: 200, status: :pending)
|
|
@payout = Payout.create!(user: @user, event: @event, amount_cents: 1000, fee_cents: 100)
|
|
end
|
|
|
|
test "should be valid" do
|
|
assert @payout.valid?
|
|
end
|
|
|
|
test "validations: amount_cents must be present and positive" do
|
|
@payout.amount_cents = nil
|
|
assert_not @payout.valid?
|
|
assert_includes @payout.errors[:amount_cents], "can't be blank"
|
|
|
|
@payout.amount_cents = 0
|
|
assert_not @payout.valid?
|
|
assert_includes @payout.errors[:amount_cents], "must be greater than 0"
|
|
|
|
@payout.amount_cents = -100
|
|
assert_not @payout.valid?
|
|
assert_includes @payout.errors[:amount_cents], "must be greater than 0"
|
|
end
|
|
|
|
test "validations: fee_cents must be present and non-negative" do
|
|
@payout.fee_cents = nil
|
|
assert_not @payout.valid?
|
|
assert_includes @payout.errors[:fee_cents], "can't be blank"
|
|
|
|
@payout.fee_cents = -100
|
|
assert_not @payout.valid?
|
|
assert_includes @payout.errors[:fee_cents], "must be greater than or equal to 0"
|
|
end
|
|
|
|
test "validations: net earnings must be greater than 0" do
|
|
# Create an event with no earnings (net earnings = 0)
|
|
event_without_earnings = Event.create!(
|
|
user: @user,
|
|
name: "Test Event",
|
|
slug: "test-event-2",
|
|
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.new(user: @user, event: event_without_earnings, amount_cents: 1000, fee_cents: 100)
|
|
assert_not payout.valid?
|
|
assert_includes payout.errors[:base], "net earnings must be greater than 0" # Custom validation message
|
|
end
|
|
|
|
test "validations: only one pending payout per event" do
|
|
pending_payout = Payout.create!(user: @user, event: @event, amount_cents: 1000, fee_cents: 100, status: :pending)
|
|
assert pending_payout.valid?
|
|
|
|
duplicate = Payout.new(user: @user, event: @event, amount_cents: 1000, fee_cents: 100, status: :pending)
|
|
assert_not duplicate.valid?
|
|
assert_includes duplicate.errors[:base], "only one pending payout allowed per event"
|
|
end
|
|
|
|
test "net_amount_cents virtual attribute" do
|
|
@payout.amount_cents = 10000
|
|
@payout.fee_cents = 1000
|
|
assert_equal 9000, @payout.net_amount_cents
|
|
end
|
|
|
|
test "after_create callback sets refunded_orders_count" do
|
|
# Create some refunded tickets to test the callback
|
|
order = Order.create!(user: @user, event: @event, status: :paid, total_amount_cents: 1000)
|
|
ticket_type = TicketType.create!(event: @event, name: "General Admission", price_cents: 1000, quantity: 10)
|
|
ticket = Ticket.create!(order: order, ticket_type: ticket_type, price_cents: 1000, status: :refunded)
|
|
|
|
payout = Payout.create!(user: @user, event: @event, amount_cents: 1000, fee_cents: 100)
|
|
# The refunded_orders_count should be set by the callback
|
|
assert_equal 1, payout.refunded_orders_count
|
|
end
|
|
|
|
test "associations: belongs to user" do
|
|
association = Payout.reflect_on_association(:user)
|
|
assert_equal :belongs_to, association.macro
|
|
end
|
|
|
|
test "associations: belongs to event" do
|
|
association = Payout.reflect_on_association(:event)
|
|
assert_equal :belongs_to, association.macro
|
|
end
|
|
|
|
test "status enum" do
|
|
assert_equal 0, Payout.statuses[:pending]
|
|
assert_equal 1, Payout.statuses[:processing]
|
|
assert_equal 2, Payout.statuses[:completed]
|
|
assert_equal 3, Payout.statuses[:failed]
|
|
|
|
@payout.status = :pending
|
|
assert @payout.pending?
|
|
|
|
@payout.status = :completed
|
|
assert @payout.completed?
|
|
end
|
|
|
|
test "pending scope" do
|
|
pending = Payout.create!(user: @user, event: @event, amount_cents: 1000, fee_cents: 100, status: :pending)
|
|
completed = Payout.create!(user: @user, event: @event, amount_cents: 2000, fee_cents: 200, status: :completed)
|
|
|
|
assert_includes Payout.pending, pending
|
|
assert_not_includes Payout.pending, completed
|
|
end
|
|
|
|
test "manual_payout? returns true for manual payouts" do
|
|
payout = Payout.create!(user: @user, event: @event, amount_cents: 1000, fee_cents: 100,
|
|
stripe_payout_id: "MANUAL_abc123")
|
|
assert payout.manual_payout?
|
|
end
|
|
|
|
test "manual_payout? returns false for Stripe payouts" do
|
|
payout = Payout.create!(user: @user, event: @event, amount_cents: 1000, fee_cents: 100,
|
|
stripe_payout_id: "tr_123")
|
|
assert_not payout.manual_payout?
|
|
end
|
|
|
|
test "manual_payout? returns false when no stripe_payout_id" do
|
|
payout = Payout.create!(user: @user, event: @event, amount_cents: 1000, fee_cents: 100)
|
|
assert_not payout.manual_payout?
|
|
end
|
|
|
|
test "mark_as_manually_processed! updates status and creates manual ID" do
|
|
payout = Payout.create!(user: @user, event: @event, amount_cents: 1000, fee_cents: 100, status: :pending)
|
|
payout.mark_as_manually_processed!
|
|
|
|
assert payout.completed?
|
|
assert payout.manual_payout?
|
|
assert_match /MANUAL_/, payout.stripe_payout_id
|
|
end
|
|
end |