Files
gridpilot.gg/docs/CONTRACT_TESTING_QUICKSTART.md
2025-12-24 00:01:01 +01:00

4.1 KiB
Raw Blame History

Contract Testing Quick Start Guide

🚀 Quick Setup

1. Run the Full Contract Test Suite

npm run test:contracts

This single command will:

  • Validate API contracts
  • Generate OpenAPI spec
  • Generate TypeScript types
  • Check for breaking changes
  • Verify website type compatibility

2. Individual Commands

# Validate API contracts only
npm run test:api:contracts

# Generate types (after making DTO changes)
npm run api:sync-types

# Check compatibility (detect breaking changes)
npm run test:contract:compatibility

# Verify website can consume types
npm run website:type-check

📁 What Gets Created

Generated Types

  • Location: apps/website/lib/types/generated/
  • Files: One .ts file per DTO (e.g., RaceDTO.ts, DriverDTO.ts)
  • Usage: Import directly in website code

Test Files

  • API Tests: apps/api/src/shared/testing/contractValidation.test.ts
  • Website Tests: apps/website/lib/types/contractConsumption.test.ts

CI/CD

  • Workflow: .github/workflows/contract-testing.yml
  • Triggers: Pull requests and main branch pushes

🎯 Common Workflows

Making API Changes

  1. Update DTO in API:

    // apps/api/src/domain/race/dtos/RaceDTO.ts
    export class RaceDTO {
      @ApiProperty()
      id: string;
    
      @ApiProperty()
      name: string;
    
      @ApiProperty({ required: false })
      description?: string;  // New optional field
    }
    
  2. Run contract tests:

    npm run test:contracts
    
  3. If tests pass, commit your changes. The CI will regenerate types automatically.

Updating Website Code

  1. Import generated types:

    import type { RaceDTO } from '@/lib/types/generated/RaceDTO';
    
    function RaceComponent({ race }: { race: RaceDTO }) {
      return <div>{race.name}</div>;
    }
    
  2. TypeScript will catch errors if contracts change.

Detecting Breaking Changes

# This will show you exactly what changed
npm run test:contract:compatibility

Output example:

🚨 BREAKING CHANGES DETECTED:
  • RaceDTO.status: Property status was removed (BREAKING)

❌ REMOVED:
  • OldDTO: DTO OldDTO was removed

 ADDED:
  • NewDTO: New DTO NewDTO was added

🔧 Troubleshooting

"Cannot find module" errors

# Regenerate types
npm run api:sync-types

Type generation fails

  1. Check DTOs have @ApiProperty decorators
  2. Verify OpenAPI spec is valid: cat apps/api/openapi.json
  3. Run individual steps:
    npm run api:generate-spec
    npm run api:generate-types
    

CI fails on breaking changes

  • Review what changed
  • Update website code to handle new types
  • Or revert the breaking change if unintended

📋 Checklist Before Committing

  • Run npm run test:contracts locally
  • All tests pass
  • No breaking changes (or they're intentional)
  • Website code updated to handle new types
  • Generated types are committed (if needed)

🎓 Key Concepts

What is a "Contract"?

A contract is the agreement between API and website about what data looks like:

  • DTO definitions
  • Property types
  • Required vs optional fields

What are "Breaking Changes"?

Changes that would break the website:

  • Removing required fields
  • Changing field types
  • Adding required fields to existing DTOs

Why Generate Types?

  • Type Safety: Catch errors at compile time
  • Auto-completion: Better IDE experience
  • Documentation: Types serve as living documentation
  • Consistency: Single source of truth

🚨 Important Notes

  1. Never manually edit generated files - they're auto-generated
  2. Always run tests before committing - prevents breaking changes
  3. The CI will regenerate types - but local verification is faster
  4. Breaking changes need review - consider versioning strategy

📚 More Resources

  • Full documentation: docs/CONTRACT_TESTING.md
  • API examples: apps/api/src/shared/testing/contractValidation.test.ts
  • Website examples: apps/website/lib/types/contractConsumption.test.ts
  • CI/CD workflow: .github/workflows/contract-testing.yml