Files
aperonight/test/controllers/promoter/payouts_controller_test.rb
kbe 3c1e17c2af feat(payouts): implement promoter earnings viewing, request flow, and admin Stripe processing with webhooks
Add model methods for accurate net calculations (€0.50 + 1.5% fees), eligibility, refund handling
Update promoter/payouts controller for index (pending events), create (eligibility checks)
Integrate admin processing via Stripe::Transfer, webhook for status sync
Enhance views: index pending cards, events/show preview/form
Add comprehensive tests (models, controllers, service, integration); run migrations
2025-09-17 02:07:52 +02:00

164 lines
5.7 KiB
Ruby

require "test_helper"
class Promoter::PayoutsControllerTest < ActionDispatch::IntegrationTest
setup do
@user = users(:one)
@event = events(:concert_event)
@payout = payouts(:one)
end
test "should get index" do
sign_in @user
# Make the user a promoter
@user.update(is_professionnal: true)
get promoter_payouts_url
assert_response :success
end
test "should get show" do
sign_in @user
# Make the user a promoter
@user.update(is_professionnal: true)
# Create a payout that belongs to the user
payout = Payout.create!(
user: @user,
event: @event,
amount_cents: 1000,
fee_cents: 100
)
get promoter_payout_url(payout)
assert_response :success
end
test "should create payout" do
sign_in @user
# Make the user a promoter
@user.update(is_professionnal: true)
# Make the user the owner of the event
@event.update(user: @user)
# Make the event end in the past
@event.update(end_time: 1.day.ago)
# Create some earnings for the event
@event.earnings.create!(
user: @user,
order: orders(:paid_order),
amount_cents: 1000,
fee_cents: 100,
status: :pending
)
assert_difference("Payout.count", 1) do
post promoter_payouts_url, params: { event_id: @event.id }
end
assert_redirected_to promoter_payout_path(Payout.last)
end
# Comprehensive index test with data
test "index shows completed payouts, eligible events, and totals for promoter" do
sign_in @user
@user.update(is_professionnal: true)
# Create completed payouts for user
completed_payout = Payout.create!(user: @user, event: @event, amount_cents: 1000, fee_cents: 100, status: :completed)
# Create eligible event
eligible_event = Event.create!(name: "Eligible Event", slug: "eligible-event", description: "desc", venue_name: "v", venue_address: "a", latitude: 48.0, longitude: 2.0, start_time: 1.day.ago, end_time: 2.days.ago, user: @user, state: :published)
# Setup net >0 for eligible
earning = Earning.create!(event: eligible_event, user: @user, order: orders(:one), amount_cents: 900, fee_cents: 100, status: :pending)
get promoter_payouts_url
assert_response :success
assert_select "table#payouts tbody tr", count: 1 # completed payout
assert_select ".eligible-events li", count: 1 # eligible event
assert_match /Pending net earnings: €9.00/, @response.body # totals
assert_match /Total paid out: €10.00/, @response.body
end
test "index does not show for non-professional" do
sign_in @user
get promoter_payouts_url
assert_redirected_to root_path # or appropriate redirect
end
# Show test with access control
test "show renders payout details for own payout" do
sign_in @user
@user.update(is_professionnal: true)
payout = Payout.create!(user: @user, event: @event, amount_cents: 1000, fee_cents: 100, status: :completed)
get promoter_payout_url(payout)
assert_response :success
assert_match payout.amount.to_s, @response.body
end
test "show returns 404 for other user's payout" do
sign_in @user
@user.update(is_professionnal: true)
other_user = User.create!(email: "other@example.com", password: "password123", password_confirmation: "password123", is_professionnal: true)
other_payout = Payout.create!(user: other_user, event: @event, amount_cents: 2000, fee_cents: 200, status: :completed)
get promoter_payout_url(other_payout)
assert_response :not_found
end
# Expanded create test: success
test "create payout success for eligible event" do
sign_in @user
@user.update(is_professionnal: true)
@event.update(user: @user, end_time: 1.day.ago) # ended
# Setup net >0
earning = @event.earnings.create!(user: @user, order: orders(:paid_order), amount_cents: 900, fee_cents: 100, status: :pending)
# Ensure eligible
assert @event.can_request_payout?(@user)
assert_difference("Payout.count", 1) do
post promoter_payouts_url, params: { event_id: @event.id }
end
assert_redirected_to promoter_payout_path(Payout.last)
assert_flash :notice, /Payout requested successfully/
assert_equal :requested, @event.reload.payout_status # assume enum
payout = Payout.last
assert_equal @event.total_gross_cents, payout.amount_cents
assert_equal @event.total_fees_cents, payout.fee_cents
end
# Create failure: ineligible event
test "create payout fails for ineligible event" do
sign_in @user
@user.update(is_professionnal: true)
@event.update(user: @user, end_time: 1.day.from_now) # not ended
assert_not @event.can_request_payout?(@user)
assert_no_difference("Payout.count") do
post promoter_payouts_url, params: { event_id: @event.id }
end
assert_redirected_to event_path(@event)
assert_flash :alert, /Event not eligible for payout/
end
# Create failure: validation errors
test "create payout fails with validation errors" do
sign_in @user
@user.update(is_professionnal: true)
@event.update(user: @user, end_time: 1.day.ago)
# Setup net =0
assert_not @event.can_request_payout?(@user)
assert_no_difference("Payout.count") do
post promoter_payouts_url, params: { event_id: @event.id }
end
assert_response :success # renders new or show with errors
assert_template :new # or appropriate
assert_flash :alert, /Validation failed/
end
# Unauthorized create
test "create requires authentication and professional status" do
post promoter_payouts_url, params: { event_id: @event.id }
assert_redirected_to new_user_session_path
sign_in @user # non-professional
post promoter_payouts_url, params: { event_id: @event.id }
assert_redirected_to root_path # or deny access
end
end