require "test_helper" class PayoutTest < ActiveSupport::TestCase setup do @payout = payouts(:one) @user = users(:one) @event = events(:concert_event) 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 # Assuming event.net_earnings_cents is a method that calculates >0 @event.earnings.create!(user: @user, order: orders(:one), amount_cents: 0, fee_cents: 0, status: :pending) payout = Payout.new(user: @user, event: @event, 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 @event.earnings.first.update(amount_cents: 2000) assert payout.valid? 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 refund_count = @event.orders.refunded.count # Assuming orders have refunded status payout = Payout.create!(user: @user, event: @event, amount_cents: 1000, fee_cents: 100) assert_equal refund_count, 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 "scope: eligible_for_payout" do # Assuming this scope exists or test if needed eligible_event = events(:another_event) # Setup with net >0, ended, etc. ineligible = events(:ineligible) eligible_payouts = Payout.eligible_for_payout assert_includes eligible_payouts, eligible_event.payouts.first if eligible_event.can_request_payout? end end