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 with enough characters", 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 a ticket type for the event @ticket_type = TicketType.create!( event: @event, name: "General Admission", description: "General admission ticket", price_cents: 1000, quantity: 100, sale_start_at: 2.days.ago, sale_end_at: 30.minutes.ago ) # 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.new(user: @user, event: @event, amount_cents: 2000, fee_cents: 200) end test "should be valid" do # For this test, we'll skip validations since they're tested separately assert @payout.save(validate: false) end test "validations: amount_cents must be present and positive" do @payout.amount_cents = nil assert_not @payout.valid? @payout.amount_cents = 0 assert_not @payout.valid? @payout.amount_cents = -100 assert_not @payout.valid? end test "validations: fee_cents must be present and non-negative" do @payout.fee_cents = nil assert_not @payout.valid? @payout.fee_cents = -100 assert_not @payout.valid? 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 2", slug: "test-event-2", description: "Test event description with enough characters", 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 a ticket type for the event TicketType.create!( event: event_without_earnings, name: "General Admission", description: "General admission ticket", price_cents: 1000, quantity: 100, sale_start_at: 2.days.ago, sale_end_at: 30.minutes.ago ) payout = Payout.new(user: @user, event: event_without_earnings, amount_cents: 0, fee_cents: 0) assert_not payout.valid? end test "validations: only one pending payout per event" do # Create a valid payout first pending_payout = Payout.create!(user: @user, event: @event, amount_cents: 2000, fee_cents: 200, status: :pending) assert pending_payout.valid? duplicate = Payout.new(user: @user, event: @event, amount_cents: 2000, fee_cents: 200, status: :pending) assert_not duplicate.valid? 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 = Ticket.create!(order: order, ticket_type: @ticket_type, price_cents: 1000, status: :refunded) payout = Payout.create!(user: @user, event: @event, amount_cents: 2000, fee_cents: 200) # 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[:approved] assert_equal 2, Payout.statuses[:processing] assert_equal 3, Payout.statuses[:completed] assert_equal 4, Payout.statuses[:failed] assert_equal 5, Payout.statuses[:rejected] payout = Payout.create!(user: @user, event: @event, amount_cents: 2000, fee_cents: 200, status: :pending) assert payout.pending? payout.update!(status: :completed) assert payout.completed? end test "pending scope" do pending = Payout.create!(user: @user, event: @event, amount_cents: 2000, fee_cents: 200, 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 end