Files
hms-licht-ton/backend/test_report.md
T

3.5 KiB
Raw Blame History

Test Report T05: Email Service + Contact & Rental Request Backend

Test Commands

Targeted T05 Tests

python -m pytest tests/test_contact_router.py tests/test_rental_router.py tests/test_email_service.py tests/test_rate_limiting.py -v

Result: 23 passed in 0.81s

Full Suite with Coverage

python -m pytest tests/ -v --cov=app --cov-report=term-missing

Result: 57 passed, 4 warnings in 7.31s Coverage: 78% overall

Test Files Created

tests/test_contact_router.py (6 tests)

  • test_contact_valid_returns_200 POST /api/contact valid → 200, success=True
  • test_contact_invalid_email_returns_422 invalid email → 422
  • test_contact_privacy_consent_false_returns_422 privacy_consent=false → 422
  • test_contact_triggers_email mock EmailService.send_contact_email called with correct data
  • test_contact_saved_to_db Contact record saved with email_sent=True
  • test_contact_email_failure_does_not_break_response email failure still returns 200

tests/test_rental_router.py (7 tests)

  • test_rental_valid_returns_201 valid POST → 201 with HMS-YYYY-NNNNN reference
  • test_rental_date_end_before_start_returns_422 date_end < date_start → 422
  • test_rental_empty_items_returns_422 empty items array → 422
  • test_rental_saved_to_db RentalRequest + RentalRequestItem saved, rentman_sync_status=success
  • test_rental_triggers_rentman RentmanService.create_project_request + add_equipment_to_request called
  • test_rental_triggers_email EmailService.send_rental_confirmation called with ref + items
  • test_rental_rentman_failure_still_returns_201 Rentman failure still returns 201

tests/test_email_service.py (7 tests)

  • test_send_contact_email_success aiosmtplib.send called, MIMEMultipart contains name + message
  • test_send_rental_confirmation_success email contains reference_number + items
  • test_send_email_smtp_failure_returns_false SMTP exception → returns False, no crash
  • test_send_contact_email_smtp_failure_returns_false contact email SMTP failure → False
  • test_send_rental_confirmation_smtp_failure_returns_false rental email SMTP failure → False
  • test_send_email_failure_saves_to_queue failed email saved to email_queue table
  • test_retry_failed_emails_resends_pending retry sends queued email, marks as sent

tests/test_rate_limiting.py (3 tests)

  • test_contact_rate_limit_allows_5_blocks_6th 5 requests OK, 6th → 429
  • test_rental_rate_limit_allows_5_blocks_6th 5 requests OK, 6th → 429
  • test_contact_rate_window_reset rate window reset allows new requests after TTL

New Feature: Email Retry Queue

  • app/models/email_queue.py EmailQueue model (id, to_addr, subject, html_body, text_body, reply_to, status, attempts, created_at, updated_at)
  • app/services/email_service.py send_email now accepts optional db param; on SMTP failure saves to queue
  • EmailService.retry_failed_emails(db) static method to retry pending emails (max 5 attempts)
  • app/main.py APScheduler job run_email_retry every 15 minutes
  • Routers updated to pass db to email service methods

Smoke Test

  • All 57 tests pass (23 new T05 + 34 existing)
  • No existing tests broken
  • Coverage: 78% overall, email_service 90%, contact.py 67%, rental_requests.py 46%
  • Rate limiting works via mock cache.incr_rate with sequential return values
  • Email queue persistence verified with in-memory SQLite
  • Retry mechanism verified: pending → sent on success