Add comprehensive Orders controller tests (partial)

- Tests authentication requirements for all actions
- Tests new order form with cart validation
- Tests order creation with ticket data
- Tests show and checkout actions
- Tests retry payment functionality
- Tests AJAX payment attempt increment
- Tests error handling for missing resources
- Added Mocha gem and Devise test helpers
- 21 tests with 13 passing, covering core functionality
- Some session handling tests need further refinement

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
kbe
2025-09-05 13:34:53 +02:00
parent eee7855d36
commit ffd9d31c94
3 changed files with 336 additions and 0 deletions

View File

@@ -0,0 +1,329 @@
require "test_helper"
class OrdersControllerTest < ActionDispatch::IntegrationTest
def setup
@user = User.create!(
email: "test@example.com",
password: "password123",
password_confirmation: "password123"
)
@event = Event.create!(
name: "Test Event",
slug: "test-event",
description: "A valid description for the test event that is long enough",
latitude: 48.8566,
longitude: 2.3522,
venue_name: "Test Venue",
venue_address: "123 Test Street",
user: @user,
start_time: 1.week.from_now,
end_time: 1.week.from_now + 3.hours,
state: :published
)
@ticket_type = TicketType.create!(
name: "General Admission",
description: "General admission tickets with full access to the event",
price_cents: 2500,
quantity: 100,
sale_start_at: Time.current,
sale_end_at: @event.start_time - 1.hour,
requires_id: false,
event: @event
)
@order = Order.create!(
user: @user,
event: @event,
status: "draft",
total_amount_cents: 2500
)
@ticket = Ticket.create!(
order: @order,
ticket_type: @ticket_type,
status: "draft",
first_name: "John",
last_name: "Doe"
)
sign_in @user
end
# === Authentication Tests ===
test "should require authentication for all actions" do
sign_out @user
get event_order_new_path(@event.slug, @event.id)
assert_redirected_to new_user_session_path
post event_order_create_path(@event.slug, @event.id)
assert_redirected_to new_user_session_path
get order_path(@order)
assert_redirected_to new_user_session_path
get checkout_order_path(@order)
assert_redirected_to new_user_session_path
end
# === New Action Tests ===
test "should get new with valid event" do
# Mock session to have cart data
@request.session[:pending_cart] = {
@ticket_type.id.to_s => { "quantity" => "2" }
}
get event_order_new_path(@event.slug, @event.id)
assert_response :success
# Should assign tickets_needing_names
tickets_needing_names = assigns(:tickets_needing_names)
assert_not_nil tickets_needing_names
assert_equal 2, tickets_needing_names.size
assert_equal @ticket_type.id, tickets_needing_names.first[:ticket_type_id]
end
test "new should redirect when cart is empty" do
# Clear any cart data
@request.session[:pending_cart] = {}
get event_order_new_path(@event.slug, @event.id)
assert_redirected_to event_path(@event.slug, @event)
assert_match /sélectionner vos billets/, flash[:alert]
end
test "new should redirect when no cart data" do
# No cart data in session
@request.session.delete(:pending_cart)
get event_order_new_path(@event.slug, @event.id)
assert_redirected_to event_path(@event.slug, @event)
assert_match /sélectionner vos billets/, flash[:alert]
end
# === Create Action Tests ===
test "should create order with valid ticket data" do
@request.session[:pending_cart] = {
@ticket_type.id.to_s => { "quantity" => "1" }
}
assert_difference "Order.count", 1 do
assert_difference "Ticket.count", 1 do
post event_order_create_path(@event.slug, @event.id), params: {
tickets_attributes: {
"0" => {
ticket_type_id: @ticket_type.id,
first_name: "Jane",
last_name: "Smith"
}
}
}
end
end
new_order = Order.last
assert_equal "draft", new_order.status
assert_equal @user, new_order.user
assert_equal @event, new_order.event
assert_equal @ticket_type.price_cents, new_order.total_amount_cents
assert_redirected_to checkout_order_path(new_order)
assert_equal new_order.id, session[:draft_order_id]
assert_nil session[:pending_cart]
end
test "create should redirect when cart is empty" do
@request.session[:pending_cart] = {}
assert_no_difference "Order.count" do
post event_order_create_path(@event.slug, @event.id)
end
assert_redirected_to event_path(@event.slug, @event)
assert_match /Aucun billet sélectionné/, flash[:alert]
end
test "create should handle missing ticket names" do
@request.session[:pending_cart] = {
@ticket_type.id.to_s => { "quantity" => "1" }
}
post event_order_create_path(@event.slug, @event.id), params: {
tickets_attributes: {
"0" => {
ticket_type_id: @ticket_type.id,
first_name: "",
last_name: ""
}
}
}
# Should redirect back to new order page
assert_redirected_to event_order_new_path(@event.slug, @event.id)
assert_match /Aucun billet valide créé/, flash[:alert]
end
# === Show Action Tests ===
test "should show order" do
get order_path(@order)
assert_response :success
order = assigns(:order)
assert_equal @order, order
tickets = assigns(:tickets)
assert_includes tickets, @ticket
end
test "should not show other user's order" do
other_user = User.create!(
email: "other@example.com",
password: "password123",
password_confirmation: "password123"
)
other_order = Order.create!(
user: other_user,
event: @event,
status: "draft",
total_amount_cents: 2500
)
get order_path(other_order)
# Should redirect to dashboard/root with alert
assert_redirected_to root_path
assert_match /Commande non trouvée/, flash[:alert]
end
# === Checkout Action Tests ===
test "should show checkout page" do
get checkout_order_path(@order)
assert_response :success
order = assigns(:order)
assert_equal @order, order
tickets = assigns(:tickets)
assert_includes tickets, @ticket
total_amount = assigns(:total_amount)
assert_equal @order.total_amount_cents, total_amount
expiring_soon = assigns(:expiring_soon)
assert_not_nil expiring_soon
end
test "checkout should redirect expired order" do
# Make order expired
@order.update!(expires_at: 1.hour.ago)
get checkout_order_path(@order)
assert_redirected_to event_path(@event.slug, @event)
assert_match /commande a expiré/, flash[:alert]
@order.reload
assert_equal "expired", @order.status
end
# === Retry Payment Tests ===
test "should allow retry payment for retryable order" do
post retry_payment_order_path(@order)
assert_redirected_to checkout_order_path(@order)
end
test "should not allow retry payment for non-retryable order" do
# Make order non-retryable (too many attempts)
@order.update!(payment_attempts: Order::MAX_PAYMENT_ATTEMPTS)
post retry_payment_order_path(@order)
assert_redirected_to event_path(@event.slug, @event)
assert_match /ne peut plus être payée/, flash[:alert]
end
# === Increment Payment Attempt Tests ===
test "should increment payment attempt via AJAX" do
initial_attempts = @order.payment_attempts
post increment_payment_attempt_order_path(@order), xhr: true
assert_response :success
response_data = JSON.parse(@response.body)
assert response_data["success"]
assert_equal initial_attempts + 1, response_data["attempts"]
@order.reload
assert_equal initial_attempts + 1, @order.payment_attempts
assert_not_nil @order.last_payment_attempt_at
end
# === Payment Success Tests (simplified) ===
test "payment_success should redirect when Stripe not configured" do
# Mock the config to return nil
Rails.application.config.stripe = { secret_key: nil }
get order_payment_success_path, params: { session_id: "test_session" }
assert_redirected_to root_path
assert_match /système de paiement n'est pas correctement configuré/, flash[:alert]
end
# === Payment Cancel Tests ===
test "payment_cancel should redirect to checkout if order can retry" do
@request.session[:draft_order_id] = @order.id
get order_payment_cancel_path
assert_redirected_to checkout_order_path(@order)
assert_match /paiement a été annulé.*réessayer/, flash[:alert]
end
test "payment_cancel should redirect to root if no order in session" do
@request.session.delete(:draft_order_id)
get order_payment_cancel_path
assert_redirected_to root_path
assert_match /paiement a été annulé/, flash[:alert]
end
# === Error Handling Tests ===
test "should handle non-existent event in new" do
get event_order_new_path(@event.slug, 99999)
assert_redirected_to events_path
assert_match /Événement non trouvé/, flash[:alert]
end
test "should handle non-existent event in create" do
post event_order_create_path(@event.slug, 99999)
assert_redirected_to events_path
assert_match /Événement non trouvé/, flash[:alert]
end
test "should handle non-existent order" do
get order_path(99999)
assert_redirected_to root_path
assert_match /Commande non trouvée/, flash[:alert]
end
# === Route Helper Tests ===
test "should have correct route helpers" do
# Test that the route helpers exist and work
assert_not_nil event_order_new_path(@event.slug, @event.id)
assert_not_nil event_order_create_path(@event.slug, @event.id)
assert_not_nil order_path(@order)
assert_not_nil checkout_order_path(@order)
assert_not_nil retry_payment_order_path(@order)
assert_not_nil increment_payment_attempt_order_path(@order)
end
end

View File

@@ -2,6 +2,7 @@ ENV["RAILS_ENV"] ||= "test"
require_relative "../config/environment"
require "rails/test_help"
require "minitest/reporters"
require "mocha/minitest"
Minitest::Reporters.use!
# Minitest::Reporters.use!(Minitest::Reporters::SpecReporter.new, color: true)
@@ -18,3 +19,7 @@ module ActiveSupport
# Add more helper methods to be used by all tests here...
end
end
class ActionDispatch::IntegrationTest
include Devise::Test::IntegrationHelpers
end