# Test Coverage Documentation ## Overview This directory contains comprehensive documentation for writing tests for **17 untested source files** across the inquiries, leads, and reviews modules of the GoodGo Platform API. ## Files Included ### 1. **TEST_COVERAGE_ANALYSIS.md** (1,841 lines, 55KB) - **Complete implementations** of all 17 untested files - Full source code for each file - Detailed explanation of what each method does - Test scenarios for each component - Reference test patterns from existing test files - Comprehensive test patterns and examples ### 2. **TEST_COVERAGE_QUICK_REFERENCE.md** (301 lines, 9.1KB) - Quick lookup guide for all 17 files - Test checklists by file type (repositories, VOs, DTOs, controllers) - Module-specific test scenarios - Priority matrix (critical, high, medium) - Recommended test execution order - Mock setup templates - Key formulas to verify ### 3. **TEST_TEMPLATES.md** (500+ lines) - Ready-to-use test templates for: - Repository tests - Value Object tests - DTO tests - Controller tests - Helper tests for pagination calculations - Helper tests for aggregation formulas - DTO validation helper tests ## Quick Start ### For a quick overview: 1. Read the **Quick Reference** first (5-10 minutes) 2. Identify which file type you want to test 3. Jump to the appropriate section in **TEST_TEMPLATES.md** 4. Copy the template and adapt it to your file ### For comprehensive understanding: 1. Start with the **Quick Reference** overview 2. Read the relevant module section in **TEST_COVERAGE_ANALYSIS.md** 3. Use **TEST_TEMPLATES.md** as implementation guide 4. Reference the example test patterns in the Analysis document ## File Organization by Module ### Inquiries Module (4 files) ``` ✗ prisma-inquiry.repository.ts — 6 methods, pagination, relationships ✗ inquiries.controller.ts — 4 endpoints, guards ✗ create-inquiry.dto.ts — 3 validations ✗ list-inquiries.dto.ts — 2 validations (pagination) ``` ### Leads Module (6 files) ``` ✗ prisma-lead.repository.ts — 6 methods, stats aggregation ✗ lead-score.vo.ts — Range validation (0-100) ✗ leads.controller.ts — 5 endpoints, role guards ✗ create-lead.dto.ts — 6 validations ✗ list-leads.dto.ts — Status enum, pagination ✗ update-lead-status.dto.ts — Status enum ``` ### Reviews Module (5 files) ``` ✗ prisma-review.repository.ts — 7 methods, distribution stats ✗ rating.vo.ts — Integer range validation (1-5) ✗ reviews.controller.ts — 5 endpoints, mixed auth ✗ create-review.dto.ts — 4 validations ✗ list-reviews.dto.ts — 2 DTO classes, pagination ``` ## Testing Priority Levels ### 🔴 CRITICAL (Business Logic) 1. **PrismaReviewRepository.getStats()** — Distribution calculation is complex 2. **PrismaLeadRepository.getStatsByAgent()** — Conversion rate formula 3. **Rating.vo** — Must validate 1-5 integers only 4. **LeadScore.vo** — Must validate 0-100 range **Start here** — These are the most business-critical validations ### 🟡 HIGH (Data Integrity) 1. Repository CRUD operations 2. Pagination calculations 3. Relationship mapping (user joins, listing traversal) 4. Controller command/query dispatch **Test second** — These ensure data consistency ### 🟢 MEDIUM (Validation & Guards) 1. DTO field validations 2. Enum constraints 3. Optional field handling 4. Authentication/Authorization guards **Test last** — These are framework-level concerns ## Test Execution Roadmap ### Week 1: Value Objects & DTOs (8-10 test files) - [ ] LeadScore.vo.ts (1 file, 4-5 test cases) - [ ] Rating.vo.ts (1 file, 4-5 test cases) - [ ] All 10 DTO files (using templates, minimal variations) **Estimated time:** 3-5 hours total ### Week 2: Controllers (2 test files) - [ ] InquiriesController (4 endpoints + guards) - [ ] LeadsController (5 endpoints + guards) - [ ] ReviewsController (5 endpoints + mixed auth) **Estimated time:** 2-3 hours total ### Week 3: Repositories (3 test files) - [ ] PrismaInquiryRepository (6 methods) - [ ] PrismaLeadRepository (6 methods + aggregation) - [ ] PrismaReviewRepository (7 methods + distribution) **Estimated time:** 4-6 hours total ### Total Estimated Time: 9-14 hours ## Key Testing Patterns ### Repositories ```typescript // Mock all Prisma methods in beforeEach mockPrisma = { [model]: { findUnique: vi.fn(), findMany: vi.fn(), create: vi.fn(), update: vi.fn(), count: vi.fn() } }; // Test happy path and error cases // Verify pagination calculations // Verify data transformation (toDomain) ``` ### Value Objects ```typescript // Test valid cases const result = ValueObject.create(validValue); expect(result.isOk()).toBe(true); // Test invalid cases const result = ValueObject.create(invalidValue); expect(result.isErr()).toBe(true); expect(result.unwrapErr()).toBe('error message'); ``` ### DTOs ```typescript // Use validate() from class-validator const errors = await validate(dto); expect(errors).toHaveLength(0); // or > 0 for invalid cases // Test type transformation with class-transformer // Test optional field handling ``` ### Controllers ```typescript // Mock CommandBus and QueryBus mockCommandBus.execute.mockResolvedValue(expectedResult); // Verify command/query construction const command = mockCommandBus.execute.mock.calls[0][0]; expect(command.userId).toBe(expectedUserId); ``` ## Critical Formulas to Test ### Pagination ``` skip = (page - 1) * take totalPages = Math.ceil(total / take) take = Math.min(limit, 100) // Clamped to 100 max ``` ### Lead Statistics ``` conversionRate = (CONVERTED_count / total_leads) * 100 // 2 decimals avgScore = (sum_of_scores / non_null_count) // 1 decimal, null if no scores ``` ### Review Statistics ``` averageRating = (sum_of_ratings / total_reviews) // 1 decimal distribution = { 1: count, 2: count, 3: count, 4: count, 5: count } ``` ## Import Statements You'll Need ```typescript // Testing utilities import { describe, it, expect, beforeEach, vi } from 'vitest'; import { validate } from 'class-validator'; import { plainToClass } from 'class-transformer'; // NestJS utilities (for controller tests) import type { EventBus, CommandBus, QueryBus } from '@nestjs/cqrs'; // Domain classes import { InquiryEntity } from './domain/entities/inquiry.entity'; import { LeadEntity } from './domain/entities/lead.entity'; import { ReviewEntity } from './domain/entities/review.entity'; import { LeadScore } from './domain/value-objects/lead-score.vo'; import { Rating } from './domain/value-objects/rating.vo'; ``` ## Common Test Data ### User IDs ``` user-1, user-2, user-3, user-agent-1 ``` ### Lead Statuses ``` NEW, CONTACTED, QUALIFIED, NEGOTIATING, CONVERTED, LOST ``` ### Pagination Defaults ``` page: 1, limit: 20 (max 100) ``` ### Rating Range ``` 1-5 stars (integer only) ``` ### Lead Score Range ``` 0-100 (any number) ``` ## References ### Existing Test Files (Use as Reference) - `src/modules/inquiries/application/__tests__/create-inquiry.handler.spec.ts` (20 lines pattern) - `src/modules/leads/application/__tests__/create-lead.handler.spec.ts` (20 lines pattern) - `src/modules/reviews/presentation/__tests__/reviews.controller.spec.ts` (135 lines pattern) ### Full Implementations All 17 file implementations are in `TEST_COVERAGE_ANALYSIS.md` with line-by-line explanations. ## Troubleshooting ### Issue: "Cannot find module" when mocking **Solution:** Use `as any` casting for mocked dependencies ```typescript const repo = new PrismaInquiryRepository(mockPrisma as any); ``` ### Issue: Validation tests not working **Solution:** Make sure you're using `plainToClass` for DTOs with transformers ```typescript const dto = plainToClass(CreateLeadDto, plainObject); ``` ### Issue: Pagination calculations don't match **Solution:** Remember that limit is clamped to 100 ```typescript const take = Math.min(limit, 100); // Always do this ``` ### Issue: Stats calculations have rounding errors **Solution:** Check decimal place requirements: - conversionRate: 2 decimals (multiply by 10000, divide by 100) - avgScore: 1 decimal (multiply by 10, divide by 10) - averageRating: 1 decimal (multiply by 10, divide by 10) ## Next Steps 1. **Pick your starting file** from Week 1 (recommend LeadScore.vo first — simplest) 2. **Open the template** matching that file type in TEST_TEMPLATES.md 3. **Copy the template** to your test file location 4. **Adapt the template** with your specific imports and data 5. **Run tests** and verify they pass 6. **Move to next file** following the roadmap ## Support Resources - Full implementations: See **TEST_COVERAGE_ANALYSIS.md** - Quick lookup: See **TEST_COVERAGE_QUICK_REFERENCE.md** - Code templates: See **TEST_TEMPLATES.md** - Reference tests: Check existing spec files in the modules --- **Last Updated:** 2026-04-11 **Total Files Documented:** 17 untested source files **Total Documentation:** 2,142 lines of analysis and templates **Estimated Testing Time:** 9-14 hours total