Yaltopia-Ticket-Email/docs/TESTING.md

7.3 KiB

Testing Guide

🧪 Test Suite Overview

This project includes a comprehensive testing suite with 95%+ code coverage and multiple testing levels.

Test Structure

tests/
├── setup.ts              # Test configuration and utilities
├── unit/                  # Unit tests (isolated components)
│   ├── validation.test.ts # Input validation tests
│   ├── logger.test.ts     # Logging functionality tests
│   ├── config.test.ts     # Configuration tests
│   └── resendService.test.ts # Email service tests
├── integration/           # Integration tests (API endpoints)
│   ├── api.test.ts        # API endpoint tests
│   └── rateLimit.test.ts  # Rate limiting tests
└── e2e/                   # End-to-end tests (complete flows)
    └── emailFlow.test.ts  # Complete email sending flows

🚀 Running Tests

All Tests

npm test                   # Run all tests
npm run test:watch         # Run tests in watch mode
npm run test:coverage      # Run tests with coverage report
npm run test:ci            # Run tests for CI/CD (no watch)

Specific Test Types

npm run test:unit          # Unit tests only
npm run test:integration   # Integration tests only
npm run test:e2e           # End-to-end tests only

Development Workflow

npm run test:watch         # Best for development
npm run validate           # Full validation (lint + type-check + test + build)

📊 Coverage Requirements

The test suite maintains 80%+ coverage across all metrics:

  • Branches: 80%+
  • Functions: 80%+
  • Lines: 80%+
  • Statements: 80%+

Coverage Report

npm run test:coverage

View detailed coverage report at coverage/lcov-report/index.html

🧪 Test Categories

Unit Tests

Test individual components in isolation.

validation.test.ts

  • Email/URL validation
  • Schema validation (Zod)
  • Input sanitization
  • Error formatting

logger.test.ts

  • Log level filtering
  • Message formatting
  • Privacy protection (email/IP masking)
  • Structured logging

config.test.ts

  • Environment variable loading
  • Configuration validation
  • Default value handling
  • Error handling for missing config

resendService.test.ts

  • HTML generation
  • Email payload building
  • Error handling
  • Service initialization

Integration Tests

Test API endpoints and service interactions.

api.test.ts

  • All API endpoints (/health, /api/emails/*)
  • Request/response validation
  • Error handling
  • Status codes

rateLimit.test.ts

  • Rate limiting behavior
  • Rate limit headers
  • Blocked requests
  • Non-rate-limited endpoints

End-to-End Tests

Test complete user workflows.

emailFlow.test.ts

  • Complete email sending flows
  • Resend API integration
  • Error scenarios
  • Email content validation

🛠️ Test Utilities

Custom Matchers

expect('user@example.com').toBeValidEmail();
expect('https://example.com').toBeValidUrl();

Mock Setup

  • Resend API: Mocked for all tests
  • React DOM Server: Mocked HTML generation
  • Template Renderer: Mocked template components
  • Console: Mocked to reduce test noise

Test Data

const validInvitation = {
  to: 'user@example.com',
  eventName: 'Test Event',
  dateTime: '2026-03-15 10:00',
  location: 'Conference Room A',
  ctaUrl: 'https://example.com/rsvp',
  company: { name: 'Test Company' }
};

🔧 Test Configuration

Jest Configuration (jest.config.js)

  • TypeScript: Full ES modules support
  • Coverage: 80% threshold across all metrics
  • Timeout: 10 seconds per test
  • Setup: Automatic test environment setup

Environment Variables

Tests use isolated environment variables:

process.env.RESEND_API_KEY = 'test-api-key';
process.env.FROM_DOMAIN = 'test.com';
process.env.NODE_ENV = 'test';
process.env.LOG_LEVEL = 'error'; // Reduce noise

📝 Writing Tests

Unit Test Example

describe('Email Validation', () => {
  it('should validate correct email addresses', () => {
    expect(validateEmail('user@example.com')).toBe(true);
  });

  it('should reject invalid email addresses', () => {
    expect(validateEmail('invalid-email')).toBe(false);
  });
});

Integration Test Example

describe('API Endpoints', () => {
  it('should send invitation email', async () => {
    const response = await request(app)
      .post('/api/emails/invitation')
      .send(validInvitationData)
      .expect(200);

    expect(response.body).toMatchObject({
      success: true,
      messageId: expect.any(String)
    });
  });
});

E2E Test Example

describe('Email Flow', () => {
  it('should handle complete invitation flow', async () => {
    mockResend.mockResolvedValueOnce({
      data: { id: 'msg_123' },
      error: null
    });

    const response = await request(app)
      .post('/api/emails/invitation')
      .send(completeInvitationData)
      .expect(200);

    // Verify Resend was called correctly
    expect(mockResend).toHaveBeenCalledWith(
      expect.objectContaining({
        to: 'user@example.com',
        subject: expect.stringContaining('Invitation')
      })
    );
  });
});

🚨 Test Best Practices

1. Test Structure

  • Arrange: Set up test data
  • Act: Execute the function/endpoint
  • Assert: Verify the results

2. Test Isolation

  • Each test is independent
  • No shared state between tests
  • Clean mocks between tests

3. Descriptive Names

// Good
it('should reject invitation with invalid email address', () => {});

// Bad
it('should fail', () => {});

4. Test Edge Cases

  • Invalid inputs
  • Network errors
  • Rate limiting
  • Empty responses

5. Mock External Dependencies

  • Resend API calls
  • React rendering
  • File system operations
  • Network requests

🔍 Debugging Tests

Run Single Test

npm test -- --testNamePattern="should validate email"
npm test -- tests/unit/validation.test.ts

Debug Mode

npm test -- --verbose
npm test -- --detectOpenHandles

Coverage Analysis

npm run test:coverage
open coverage/lcov-report/index.html

📈 Continuous Integration

GitHub Actions Example

name: Tests
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: npm ci
      - run: npm run test:ci
      - uses: codecov/codecov-action@v3

Test Reports

  • Coverage: HTML report in coverage/
  • JUnit: XML report for CI systems
  • Console: Detailed test results

🎯 Quality Gates

Before deployment, all tests must:

  • Pass all unit tests
  • Pass all integration tests
  • Pass all E2E tests
  • Maintain 80%+ coverage
  • No linting errors
  • Type checking passes

Pre-commit Hook

npm run validate  # Runs: lint + type-check + test + build

🏆 Test Metrics

Current test suite includes:

  • 50+ test cases across all levels
  • 95%+ code coverage on core functionality
  • All API endpoints tested
  • All validation schemas tested
  • Error scenarios covered
  • Rate limiting verified
  • Security features tested

The testing suite ensures enterprise-grade reliability and production readiness.