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:
kbe
2025-09-06 13:25:02 +02:00
parent 73eefdd7bd
commit 7f36abbcec
17 changed files with 854 additions and 26 deletions

View 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