require "test_helper" class CleanupExpiredDraftsJobTest < ActiveJob::TestCase 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 ) end test "should be queued on default queue" do assert_equal "default", CleanupExpiredDraftsJob.queue_name end test "should perform job without errors when no tickets exist" do # Clear all tickets Ticket.destroy_all assert_nothing_raised do CleanupExpiredDraftsJob.perform_now end end test "should process expired draft tickets" do # Create an expired draft ticket with expired order @order.update!(expires_at: 1.hour.ago) expired_ticket = Ticket.create!( order: @order, ticket_type: @ticket_type, status: "draft", first_name: "John", last_name: "Doe" ) # Job should run without errors and process the ticket assert_nothing_raised do CleanupExpiredDraftsJob.perform_now end # Ticket should remain in database (we're testing job execution, not business logic) assert_not_nil Ticket.find(expired_ticket.id) end test "should log information about expired tickets" do # Create an expired draft ticket expired_ticket = Ticket.create!( order: @order, ticket_type: @ticket_type, status: "draft", first_name: "John", last_name: "Doe" ) # Mock the expired_drafts scope expired_tickets_relation = Ticket.where(id: expired_ticket.id) Ticket.expects(:expired_drafts).returns(expired_tickets_relation) # Mock the expire_if_overdue! method expired_ticket.stubs(:expire_if_overdue!) # Mock Rails logger Rails.logger.expects(:info).with("Expiring draft ticket #{expired_ticket.id} for user #{expired_ticket.user.id}") Rails.logger.expects(:info).with("Expired 1 draft tickets") assert_nothing_raised do CleanupExpiredDraftsJob.perform_now end end test "should handle multiple expired tickets" do # Create multiple expired draft tickets ticket1 = Ticket.create!( order: @order, ticket_type: @ticket_type, status: "draft", first_name: "John", last_name: "Doe" ) ticket2 = Ticket.create!( order: @order, ticket_type: @ticket_type, status: "draft", first_name: "Jane", last_name: "Doe" ) expired_tickets_relation = Ticket.where(id: [ ticket1.id, ticket2.id ]) Ticket.expects(:expired_drafts).returns(expired_tickets_relation) ticket1.expects(:expire_if_overdue!).once ticket2.expects(:expire_if_overdue!).once Rails.logger.expects(:info).with("Expiring draft ticket #{ticket1.id} for user #{ticket1.user.id}") Rails.logger.expects(:info).with("Expiring draft ticket #{ticket2.id} for user #{ticket2.user.id}") Rails.logger.expects(:info).with("Expired 2 draft tickets") assert_nothing_raised do CleanupExpiredDraftsJob.perform_now end end test "should not log when no tickets are expired" do # Mock empty expired_drafts scope empty_relation = Ticket.none Ticket.expects(:expired_drafts).returns(empty_relation) # Should not log the "Expired X tickets" message Rails.logger.expects(:info).never assert_nothing_raised do CleanupExpiredDraftsJob.perform_now end end test "should handle errors gracefully during ticket processing" do # Create an expired draft ticket expired_ticket = Ticket.create!( order: @order, ticket_type: @ticket_type, status: "draft", first_name: "John", last_name: "Doe" ) expired_tickets_relation = Ticket.where(id: expired_ticket.id) Ticket.expects(:expired_drafts).returns(expired_tickets_relation) # Mock expire_if_overdue! to raise an error expired_ticket.expects(:expire_if_overdue!).raises(StandardError.new("Test error")) Rails.logger.expects(:info).with("Expiring draft ticket #{expired_ticket.id} for user #{expired_ticket.user.id}") # Job should handle the error gracefully and not crash assert_raises(StandardError) do CleanupExpiredDraftsJob.perform_now end end end