feat: Implement comprehensive email notifications system
This commit implements a complete email notifications system for purchase confirmations and event reminders as requested in the medium priority backlog tasks. ## Features Added ### Purchase Confirmation Emails - Automatically sent when orders are marked as paid - Supports both single tickets and multi-ticket orders - Includes PDF ticket attachments - Professional HTML and text templates in French ### Event Reminder Emails - Automated reminders sent 7 days, 1 day, and day of events - Only sent to users with active tickets - Smart messaging based on time until event - Venue details and ticket information included ### Background Jobs - EventReminderJob: Sends reminders to all users for a specific event - EventReminderSchedulerJob: Daily scheduler to queue reminder jobs - Proper error handling and logging ### Email Templates - Responsive HTML templates with ApéroNight branding - Text fallbacks for better email client compatibility - Dynamic content based on number of tickets and time until event ### Configuration & Testing - Environment-based SMTP configuration for production - Development setup with MailCatcher support - Comprehensive test suite with mocking for PDF generation - Integration tests for end-to-end functionality - Documentation with usage examples ## Technical Implementation - Enhanced TicketMailer with new notification methods - Background job scheduling via Rails initializer - Order model integration for automatic purchase confirmations - Proper associations handling for user/ticket relationships - Configurable via environment variables ## Files Added/Modified - Enhanced app/mailers/ticket_mailer.rb with order support - Added app/jobs/event_reminder_*.rb for background processing - Updated email templates in app/views/ticket_mailer/ - Added automatic scheduling in config/initializers/ - Comprehensive test coverage in test/ directory - Complete documentation in docs/email-notifications.md 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
101
test/integration/email_notifications_integration_test.rb
Normal file
101
test/integration/email_notifications_integration_test.rb
Normal file
@@ -0,0 +1,101 @@
|
||||
require "test_helper"
|
||||
|
||||
class EmailNotificationsIntegrationTest < ActionDispatch::IntegrationTest
|
||||
include ActiveJob::TestHelper
|
||||
|
||||
def setup
|
||||
@user = User.create!(
|
||||
email: "test@example.com",
|
||||
password: "password123",
|
||||
first_name: "Test",
|
||||
last_name: "User"
|
||||
)
|
||||
|
||||
@event = Event.create!(
|
||||
name: "Test Event",
|
||||
slug: "test-event",
|
||||
description: "A test event for integration testing",
|
||||
state: :published,
|
||||
venue_name: "Test Venue",
|
||||
venue_address: "123 Test Street",
|
||||
latitude: 40.7128,
|
||||
longitude: -74.0060,
|
||||
start_time: 1.week.from_now,
|
||||
end_time: 1.week.from_now + 4.hours,
|
||||
user: @user
|
||||
)
|
||||
|
||||
@ticket_type = TicketType.create!(
|
||||
name: "General Admission",
|
||||
description: "General admission ticket",
|
||||
price_cents: 2500,
|
||||
quantity: 100,
|
||||
sale_start_at: 1.day.ago,
|
||||
sale_end_at: 1.day.from_now,
|
||||
event: @event
|
||||
)
|
||||
|
||||
@order = Order.create!(
|
||||
user: @user,
|
||||
event: @event,
|
||||
status: "draft",
|
||||
total_amount_cents: 2500,
|
||||
payment_attempts: 0
|
||||
)
|
||||
|
||||
@ticket = Ticket.create!(
|
||||
order: @order,
|
||||
ticket_type: @ticket_type,
|
||||
first_name: "Test",
|
||||
last_name: "User",
|
||||
price_cents: 2500,
|
||||
status: "draft"
|
||||
)
|
||||
end
|
||||
|
||||
test "sends purchase confirmation email when order is marked as paid" do
|
||||
# Mock PDF generation to avoid QR code issues
|
||||
@ticket.stubs(:to_pdf).returns("fake_pdf_content")
|
||||
|
||||
assert_emails 1 do
|
||||
@order.mark_as_paid!
|
||||
end
|
||||
|
||||
assert_equal "paid", @order.status
|
||||
assert_equal "active", @ticket.reload.status
|
||||
end
|
||||
|
||||
test "event reminder email can be sent to users with active tickets" do
|
||||
# Setup: mark order as paid and activate tickets
|
||||
@ticket.stubs(:to_pdf).returns("fake_pdf_content")
|
||||
@order.mark_as_paid!
|
||||
|
||||
# Clear any emails from the setup
|
||||
ActionMailer::Base.deliveries.clear
|
||||
|
||||
assert_emails 1 do
|
||||
TicketMailer.event_reminder(@user, @event, 7).deliver_now
|
||||
end
|
||||
|
||||
email = ActionMailer::Base.deliveries.last
|
||||
assert_equal [@user.email], email.to
|
||||
assert_equal "Rappel : #{@event.name} dans une semaine", email.subject
|
||||
end
|
||||
|
||||
test "event reminder job schedules emails for users with tickets" do
|
||||
# Setup: mark order as paid and activate tickets
|
||||
@ticket.stubs(:to_pdf).returns("fake_pdf_content")
|
||||
@order.mark_as_paid!
|
||||
|
||||
# Clear any emails from the setup
|
||||
ActionMailer::Base.deliveries.clear
|
||||
|
||||
# Perform the job
|
||||
EventReminderJob.perform_now(@event.id, 7)
|
||||
|
||||
assert_equal 1, ActionMailer::Base.deliveries.size
|
||||
email = ActionMailer::Base.deliveries.last
|
||||
assert_equal [@user.email], email.to
|
||||
assert_match "une semaine", email.subject
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user