Move 36 root-level audit/analysis documents and 7 web app audit documents into docs/audits/ directory to declutter the project root. Remove stale EXPLORATION_SUMMARY.txt. Co-Authored-By: Paperclip <noreply@paperclip.ing>
307 lines
9.1 KiB
Markdown
307 lines
9.1 KiB
Markdown
# 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
|