chore: update project documentation, audit reports, and initialize IDE configuration files
Some checks failed
CI / Lint → Typecheck → Test → Build (22) (push) Failing after 29s
CI / E2E Tests (push) Has been skipped
CodeQL Analysis / CodeQL (javascript-typescript) (push) Failing after 2m42s
Deploy / Build Web Image (push) Failing after 27s
Deploy / Build AI Services Image (push) Failing after 29s
E2E Tests / Playwright E2E (push) Failing after 43s
Deploy / Build API Image (push) Failing after 1m31s
Security Scanning / Dependency Audit (pnpm) (push) Failing after 6s
Security Scanning / Trivy Scan — API Image (push) Failing after 5m35s
Security Scanning / Trivy Scan — AI Services Image (push) Failing after 3m45s
Deploy / Deploy to Staging (push) Has been skipped
Deploy / Smoke Test Staging (push) Has been skipped
Deploy / Deploy to Production (push) Has been skipped
Deploy / Smoke Test Production (push) Has been skipped
Deploy / Rollback Staging (push) Has been skipped
Deploy / Rollback Production (push) Has been skipped
Security Scanning / Trivy Scan — Web Image (push) Failing after 13m51s
Security Scanning / Trivy Filesystem Scan (push) Failing after 14m46s
Security Scanning / Security Gate (push) Has been cancelled
Some checks failed
CI / Lint → Typecheck → Test → Build (22) (push) Failing after 29s
CI / E2E Tests (push) Has been skipped
CodeQL Analysis / CodeQL (javascript-typescript) (push) Failing after 2m42s
Deploy / Build Web Image (push) Failing after 27s
Deploy / Build AI Services Image (push) Failing after 29s
E2E Tests / Playwright E2E (push) Failing after 43s
Deploy / Build API Image (push) Failing after 1m31s
Security Scanning / Dependency Audit (pnpm) (push) Failing after 6s
Security Scanning / Trivy Scan — API Image (push) Failing after 5m35s
Security Scanning / Trivy Scan — AI Services Image (push) Failing after 3m45s
Deploy / Deploy to Staging (push) Has been skipped
Deploy / Smoke Test Staging (push) Has been skipped
Deploy / Deploy to Production (push) Has been skipped
Deploy / Smoke Test Production (push) Has been skipped
Deploy / Rollback Staging (push) Has been skipped
Deploy / Rollback Production (push) Has been skipped
Security Scanning / Trivy Scan — Web Image (push) Failing after 13m51s
Security Scanning / Trivy Filesystem Scan (push) Failing after 14m46s
Security Scanning / Security Gate (push) Has been cancelled
This commit is contained in:
@@ -1,91 +1,91 @@
|
||||
# Test Coverage Quick Reference Guide
|
||||
# Hướng Dẫn Tham Khảo Nhanh về Độ Phủ Kiểm Thử
|
||||
|
||||
## 17 Untested Source Files Overview
|
||||
## Tổng Quan 17 Tệp Nguồn Chưa Được Kiểm Thử
|
||||
|
||||
### INQUIRIES MODULE (4 files)
|
||||
### MODULE INQUIRIES (4 tệp)
|
||||
```
|
||||
1. prisma-inquiry.repository.ts — 6 methods to test + 1 private mapper
|
||||
2. inquiries.controller.ts — 4 endpoints to test + guard validation
|
||||
3. create-inquiry.dto.ts — 3 field validations
|
||||
4. list-inquiries.dto.ts — 2 field validations (pagination)
|
||||
1. prisma-inquiry.repository.ts — 6 phương thức cần kiểm thử + 1 mapper riêng
|
||||
2. inquiries.controller.ts — 4 endpoint cần kiểm thử + xác thực guard
|
||||
3. create-inquiry.dto.ts — 3 xác thực trường dữ liệu
|
||||
4. list-inquiries.dto.ts — 2 xác thực trường dữ liệu (phân trang)
|
||||
```
|
||||
|
||||
### LEADS MODULE (6 files)
|
||||
### MODULE LEADS (6 tệp)
|
||||
```
|
||||
5. prisma-lead.repository.ts — 6 methods + stats aggregation
|
||||
6. lead-score.vo.ts — Value object: range 0-100
|
||||
7. leads.controller.ts — 5 endpoints + class-level role guard
|
||||
8. create-lead.dto.ts — 6 field validations
|
||||
9. list-leads.dto.ts — Status enum + pagination
|
||||
10. update-lead-status.dto.ts — Status enum validation
|
||||
5. prisma-lead.repository.ts — 6 phương thức + tổng hợp thống kê
|
||||
6. lead-score.vo.ts — Value object: phạm vi 0-100
|
||||
7. leads.controller.ts — 5 endpoint + role guard cấp class
|
||||
8. create-lead.dto.ts — 6 xác thực trường dữ liệu
|
||||
9. list-leads.dto.ts — Enum trạng thái + phân trang
|
||||
10. update-lead-status.dto.ts — Xác thực enum trạng thái
|
||||
```
|
||||
|
||||
### REVIEWS MODULE (5 files)
|
||||
### MODULE REVIEWS (5 tệp)
|
||||
```
|
||||
11. prisma-review.repository.ts — 7 methods + stats with distribution
|
||||
12. rating.vo.ts — Value object: range 1-5 (integers only)
|
||||
13. reviews.controller.ts — 5 endpoints + mixed auth
|
||||
14. create-review.dto.ts — 4 field validations
|
||||
15. list-reviews.dto.ts — 2 DTOs: ListReviewsByTargetDto, ReviewStatsDto
|
||||
11. prisma-review.repository.ts — 7 phương thức + thống kê với phân phối
|
||||
12. rating.vo.ts — Value object: phạm vi 1-5 (chỉ số nguyên)
|
||||
13. reviews.controller.ts — 5 endpoint + xác thực hỗn hợp
|
||||
14. create-review.dto.ts — 4 xác thực trường dữ liệu
|
||||
15. list-reviews.dto.ts — 2 DTO: ListReviewsByTargetDto, ReviewStatsDto
|
||||
```
|
||||
|
||||
### REFERENCE PATTERNS (2 test files)
|
||||
### MẪU THAM KHẢO (2 tệp kiểm thử)
|
||||
```
|
||||
16. create-inquiry.handler.spec.ts — Handler test pattern
|
||||
17. create-lead.handler.spec.ts — Handler test pattern
|
||||
18. reviews.controller.spec.ts — Controller test pattern
|
||||
16. create-inquiry.handler.spec.ts — Mẫu kiểm thử handler
|
||||
17. create-lead.handler.spec.ts — Mẫu kiểm thử handler
|
||||
18. reviews.controller.spec.ts — Mẫu kiểm thử controller
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Test Scenarios by Type
|
||||
## Kịch Bản Kiểm Thử Nhanh Theo Loại
|
||||
|
||||
### REPOSITORIES (3 files)
|
||||
Test checklist for each repository:
|
||||
- [ ] findById() returns entity or null
|
||||
- [ ] save() creates record with correct data mapping
|
||||
- [ ] Paginated methods respect limit cap (100 max)
|
||||
- [ ] Pagination calculation: skip = (page - 1) * take
|
||||
- [ ] Relationships are joined correctly
|
||||
- [ ] Aggregations calculate correctly (stats methods)
|
||||
- [ ] Optional fields handling (null coercion)
|
||||
- [ ] ISO date formatting in DTOs
|
||||
### REPOSITORIES (3 tệp)
|
||||
Danh sách kiểm tra cho từng repository:
|
||||
- [ ] findById() trả về entity hoặc null
|
||||
- [ ] save() tạo bản ghi với ánh xạ dữ liệu đúng
|
||||
- [ ] Các phương thức phân trang tuân thủ giới hạn tối đa (tối đa 100)
|
||||
- [ ] Tính toán phân trang: skip = (page - 1) * take
|
||||
- [ ] Các quan hệ được nối đúng
|
||||
- [ ] Các phép tổng hợp tính toán đúng (các phương thức thống kê)
|
||||
- [ ] Xử lý trường tùy chọn (ép kiểu null)
|
||||
- [ ] Định dạng ngày ISO trong DTO
|
||||
|
||||
**Specific to PrismaInquiryRepository:**
|
||||
- countUnreadByAgent() aggregation
|
||||
- findByListing() includes property.title
|
||||
- findByAgent() joins through listing.agentId
|
||||
**Riêng cho PrismaInquiryRepository:**
|
||||
- countUnreadByAgent() tổng hợp
|
||||
- findByListing() bao gồm property.title
|
||||
- findByAgent() nối qua listing.agentId
|
||||
|
||||
**Specific to PrismaLeadRepository:**
|
||||
- findByAgent() optional status filter
|
||||
- getStatsByAgent() calculates:
|
||||
**Riêng cho PrismaLeadRepository:**
|
||||
- findByAgent() bộ lọc trạng thái tùy chọn
|
||||
- getStatsByAgent() tính toán:
|
||||
- totalLeads count
|
||||
- byStatus object (dict of counts)
|
||||
- conversionRate: (CONVERTED / total) * 100 (2 decimals)
|
||||
- avgScore: average of non-null scores (1 decimal)
|
||||
- conversionRate: (CONVERTED / total) * 100 (2 chữ số thập phân)
|
||||
- avgScore: trung bình của các điểm khác null (1 chữ số thập phân)
|
||||
|
||||
**Specific to PrismaReviewRepository:**
|
||||
- findByUserAndTarget() unique constraint query
|
||||
- getStats() builds distribution object (keys 1-5)
|
||||
- averageRating calculation: (sum / total) * 10 / 10 (1 decimal)
|
||||
**Riêng cho PrismaReviewRepository:**
|
||||
- findByUserAndTarget() truy vấn ràng buộc duy nhất
|
||||
- getStats() xây dựng đối tượng phân phối (khóa 1-5)
|
||||
- Tính toán averageRating: (sum / total) * 10 / 10 (1 chữ số thập phân)
|
||||
|
||||
---
|
||||
|
||||
### VALUE OBJECTS (2 files)
|
||||
Test checklist:
|
||||
- [ ] create() with valid value returns Result.ok()
|
||||
- [ ] create() with invalid value returns Result.err() with correct message
|
||||
- [ ] Getter returns props.value
|
||||
- [ ] Invalid cases covered (negative, > max, non-integer, null)
|
||||
### VALUE OBJECTS (2 tệp)
|
||||
Danh sách kiểm tra:
|
||||
- [ ] create() với giá trị hợp lệ trả về Result.ok()
|
||||
- [ ] create() với giá trị không hợp lệ trả về Result.err() với thông báo đúng
|
||||
- [ ] Getter trả về props.value
|
||||
- [ ] Các trường hợp không hợp lệ được bao phủ (âm, > max, không phải số nguyên, null)
|
||||
|
||||
**LeadScore validation:**
|
||||
**Xác thực LeadScore:**
|
||||
```
|
||||
✓ Valid: 0, 50, 100
|
||||
✗ Invalid: -1, 101, 2.5, null, "50"
|
||||
Error: "Điểm lead phải từ 0 đến 100"
|
||||
```
|
||||
|
||||
**Rating validation:**
|
||||
**Xác thực Rating:**
|
||||
```
|
||||
✓ Valid: 1, 2, 3, 4, 5
|
||||
✗ Invalid: 0, 6, 2.5, null, "5"
|
||||
@@ -94,94 +94,94 @@ Error: "Đánh giá phải từ 1 đến 5 sao"
|
||||
|
||||
---
|
||||
|
||||
### CONTROLLERS (2 files)
|
||||
Test checklist:
|
||||
- [ ] Each endpoint dispatches correct command/query type
|
||||
- [ ] Parameters are mapped correctly from DTO
|
||||
- [ ] Optional fields become null (e.g., phone ?? null → null)
|
||||
- [ ] Default pagination values applied (page: 1, limit: 20)
|
||||
- [ ] CurrentUser decorator extracts user.sub correctly
|
||||
- [ ] Guard enforcement (@UseGuards, @Roles)
|
||||
- [ ] Return types match (e.g., { deleted: true })
|
||||
### CONTROLLERS (2 tệp)
|
||||
Danh sách kiểm tra:
|
||||
- [ ] Mỗi endpoint điều phối đúng loại command/query
|
||||
- [ ] Các tham số được ánh xạ đúng từ DTO
|
||||
- [ ] Các trường tùy chọn trở thành null (ví dụ: phone ?? null → null)
|
||||
- [ ] Các giá trị phân trang mặc định được áp dụng (page: 1, limit: 20)
|
||||
- [ ] Decorator CurrentUser trích xuất user.sub đúng
|
||||
- [ ] Thực thi guard (@UseGuards, @Roles)
|
||||
- [ ] Kiểu trả về khớp (ví dụ: { deleted: true })
|
||||
|
||||
**InquiriesController specifics:**
|
||||
- POST /inquiries: phone optional → null
|
||||
- GET /inquiries/listing/:listingId: requires JWT
|
||||
- GET /inquiries/agent/me: requires JWT + AGENT role
|
||||
- PATCH /inquiries/:id/read: requires JWT + AGENT role
|
||||
**Đặc điểm riêng của InquiriesController:**
|
||||
- POST /inquiries: phone tùy chọn → null
|
||||
- GET /inquiries/listing/:listingId: yêu cầu JWT
|
||||
- GET /inquiries/agent/me: yêu cầu JWT + vai trò AGENT
|
||||
- PATCH /inquiries/:id/read: yêu cầu JWT + vai trò AGENT
|
||||
|
||||
**LeadsController specifics:**
|
||||
- ALL endpoints require JWT + AGENT role (class-level @Roles)
|
||||
- POST /leads: score optional, score range validation in command
|
||||
- GET /leads: status filter optional
|
||||
- GET /leads/stats: aggregation query
|
||||
- PATCH /leads/:id/status: only status field in command
|
||||
- DELETE /leads/:id: agentId verification in command
|
||||
**Đặc điểm riêng của LeadsController:**
|
||||
- TẤT CẢ endpoint yêu cầu JWT + vai trò AGENT (cấp class @Roles)
|
||||
- POST /leads: score tùy chọn, xác thực phạm vi score trong command
|
||||
- GET /leads: bộ lọc trạng thái tùy chọn
|
||||
- GET /leads/stats: truy vấn tổng hợp
|
||||
- PATCH /leads/:id/status: chỉ trường status trong command
|
||||
- DELETE /leads/:id: xác thực agentId trong command
|
||||
|
||||
**ReviewsController specifics:**
|
||||
- POST /reviews: requires JWT (AuthGuard)
|
||||
- GET /reviews: NO auth required (stats are public)
|
||||
- GET /reviews/stats: NO auth required
|
||||
- GET /reviews/me: requires JWT
|
||||
- DELETE /reviews/:id: requires JWT + ownership check in command
|
||||
**Đặc điểm riêng của ReviewsController:**
|
||||
- POST /reviews: yêu cầu JWT (AuthGuard)
|
||||
- GET /reviews: KHÔNG yêu cầu xác thực (thống kê là công khai)
|
||||
- GET /reviews/stats: KHÔNG yêu cầu xác thực
|
||||
- GET /reviews/me: yêu cầu JWT
|
||||
- DELETE /reviews/:id: yêu cầu JWT + kiểm tra quyền sở hữu trong command
|
||||
|
||||
---
|
||||
|
||||
### DTOs (10 files)
|
||||
Test checklist:
|
||||
- [ ] Required fields throw ValidationException if missing
|
||||
- [ ] String max/min length validated
|
||||
- [ ] Number min/max validated
|
||||
- [ ] Enum @IsIn() validates allowed values
|
||||
- [ ] Type transformation (class-transformer @Type)
|
||||
- [ ] Email format validated (@IsEmail)
|
||||
- [ ] Optional fields (@IsOptional) don't throw if omitted
|
||||
### DTOs (10 tệp)
|
||||
Danh sách kiểm tra:
|
||||
- [ ] Các trường bắt buộc ném ValidationException nếu thiếu
|
||||
- [ ] Độ dài tối đa/tối thiểu của chuỗi được xác thực
|
||||
- [ ] Giá trị tối thiểu/tối đa của số được xác thực
|
||||
- [ ] Enum @IsIn() xác thực các giá trị được phép
|
||||
- [ ] Chuyển đổi kiểu (class-transformer @Type)
|
||||
- [ ] Định dạng email được xác thực (@IsEmail)
|
||||
- [ ] Các trường tùy chọn (@IsOptional) không ném lỗi nếu bỏ qua
|
||||
|
||||
**Pagination standard (used in 5 DTOs):**
|
||||
- page: optional, @Min(1), default 1
|
||||
- limit: optional, @Min(1), @Max(100), default 20
|
||||
- Both use @Type(() => Number) for string→number transformation
|
||||
**Chuẩn phân trang (dùng trong 5 DTO):**
|
||||
- page: tùy chọn, @Min(1), mặc định 1
|
||||
- limit: tùy chọn, @Min(1), @Max(100), mặc định 20
|
||||
- Cả hai dùng @Type(() => Number) để chuyển đổi chuỗi→số
|
||||
|
||||
**Enum validations:**
|
||||
**Xác thực enum:**
|
||||
- LeadStatus: ['NEW', 'CONTACTED', 'QUALIFIED', 'NEGOTIATING', 'CONVERTED', 'LOST']
|
||||
- Used in: ListLeadsDto, UpdateLeadStatusDto
|
||||
- Dùng trong: ListLeadsDto, UpdateLeadStatusDto
|
||||
|
||||
---
|
||||
|
||||
## Test Priority Matrix
|
||||
## Ma Trận Ưu Tiên Kiểm Thử
|
||||
|
||||
### 🔴 CRITICAL (Business Logic)
|
||||
1. PrismaReviewRepository.getStats() - distribution calculation
|
||||
2. PrismaLeadRepository.getStatsByAgent() - conversion rate formula
|
||||
3. Rating.vo - must be 1-5 integers only
|
||||
4. LeadScore.vo - must be 0-100 range
|
||||
### 🔴 QUAN TRỌNG (Logic Nghiệp Vụ)
|
||||
1. PrismaReviewRepository.getStats() - tính toán phân phối
|
||||
2. PrismaLeadRepository.getStatsByAgent() - công thức tỷ lệ chuyển đổi
|
||||
3. Rating.vo - phải là số nguyên từ 1-5
|
||||
4. LeadScore.vo - phải trong phạm vi 0-100
|
||||
|
||||
### 🟡 HIGH (Data Integrity)
|
||||
1. All repository CRUD methods
|
||||
2. Pagination calculations
|
||||
3. Relationship mapping (user joins, listing joins)
|
||||
4. Controller parameter mapping
|
||||
### 🟡 CAO (Tính Toàn Vẹn Dữ Liệu)
|
||||
1. Tất cả phương thức CRUD của repository
|
||||
2. Tính toán phân trang
|
||||
3. Ánh xạ quan hệ (nối user, nối listing)
|
||||
4. Ánh xạ tham số controller
|
||||
|
||||
### 🟢 MEDIUM (Validation)
|
||||
1. DTO field validations
|
||||
2. Enum constraints
|
||||
3. Optional field handling
|
||||
4. Guard enforcement
|
||||
### 🟢 TRUNG BÌNH (Xác Thực)
|
||||
1. Xác thực trường DTO
|
||||
2. Ràng buộc enum
|
||||
3. Xử lý trường tùy chọn
|
||||
4. Thực thi guard
|
||||
|
||||
---
|
||||
|
||||
## Test Execution Order Recommendation
|
||||
## Khuyến Nghị Thứ Tự Thực Thi Kiểm Thử
|
||||
|
||||
1. **Value Objects** (2 files) - 2 simple test files
|
||||
2. **DTOs** (10 files) - Use class-validator testing patterns
|
||||
3. **Controllers** (2 files) - Command/query dispatch tests
|
||||
4. **Repositories** (3 files) - Data layer tests with mocked Prisma
|
||||
1. **Value Objects** (2 tệp) - 2 tệp kiểm thử đơn giản
|
||||
2. **DTOs** (10 tệp) - Dùng mẫu kiểm thử class-validator
|
||||
3. **Controllers** (2 tệp) - Kiểm thử điều phối command/query
|
||||
4. **Repositories** (3 tệp) - Kiểm thử tầng dữ liệu với Prisma được giả lập
|
||||
|
||||
---
|
||||
|
||||
## Mock Setup Template
|
||||
## Mẫu Thiết Lập Mock
|
||||
|
||||
### For Repositories:
|
||||
### Cho Repositories:
|
||||
```typescript
|
||||
const mockPrisma = {
|
||||
inquiry: { findUnique: vi.fn(), findMany: vi.fn(), create: vi.fn(), update: vi.fn(), delete: vi.fn(), count: vi.fn() },
|
||||
@@ -189,69 +189,69 @@ const mockPrisma = {
|
||||
const repo = new PrismaInquiryRepository(mockPrisma as any);
|
||||
```
|
||||
|
||||
### For Controllers:
|
||||
### Cho Controllers:
|
||||
```typescript
|
||||
const mockCommandBus = { execute: vi.fn() };
|
||||
const mockQueryBus = { execute: vi.fn() };
|
||||
const controller = new InquiriesController(mockCommandBus as any, mockQueryBus as any);
|
||||
```
|
||||
|
||||
### For Value Objects:
|
||||
### Cho Value Objects:
|
||||
```typescript
|
||||
const result = LeadScore.create(75);
|
||||
expect(result.isOk()).toBe(true);
|
||||
expect(result.unwrap().value).toBe(75);
|
||||
```
|
||||
|
||||
### For DTOs:
|
||||
### Cho DTOs:
|
||||
```typescript
|
||||
import { validate } from 'class-validator';
|
||||
const dto = new CreateLeadDto();
|
||||
dto.name = 'Nguyễn Văn A';
|
||||
dto.phone = '0901234567';
|
||||
// ... set other required fields
|
||||
// ... đặt các trường bắt buộc khác
|
||||
const errors = await validate(dto);
|
||||
expect(errors).toHaveLength(0);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Formulas to Verify
|
||||
## Các Công Thức Cần Xác Minh
|
||||
|
||||
### Pagination:
|
||||
### Phân trang:
|
||||
```
|
||||
skip = (page - 1) * take
|
||||
totalPages = Math.ceil(total / take)
|
||||
take = Math.min(limit, 100)
|
||||
```
|
||||
|
||||
### Lead Conversion Rate:
|
||||
### Tỷ Lệ Chuyển Đổi Lead:
|
||||
```
|
||||
conversionRate = (convertedCount / totalLeads) * 100
|
||||
Result: rounded to 2 decimals (e.g., 33.33)
|
||||
Kết quả: làm tròn đến 2 chữ số thập phân (ví dụ: 33.33)
|
||||
```
|
||||
|
||||
### Lead Average Score:
|
||||
### Điểm Trung Bình Lead:
|
||||
```
|
||||
avgScore = scoreSum / scoreCount (where score !== null)
|
||||
Result: rounded to 1 decimal (e.g., 75.5)
|
||||
Kết quả: làm tròn đến 1 chữ số thập phân (ví dụ: 75.5)
|
||||
```
|
||||
|
||||
### Review Average Rating:
|
||||
### Đánh Giá Trung Bình Review:
|
||||
```
|
||||
averageRating = (sum / totalReviews)
|
||||
Result: rounded to 1 decimal (e.g., 4.5)
|
||||
Kết quả: làm tròn đến 1 chữ số thập phân (ví dụ: 4.5)
|
||||
```
|
||||
|
||||
### Review Distribution:
|
||||
### Phân Phối Review:
|
||||
```
|
||||
distribution: { 1: count, 2: count, 3: count, 4: count, 5: count }
|
||||
Must initialize all 5 keys, even if 0
|
||||
Phải khởi tạo tất cả 5 khóa, kể cả khi bằng 0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Locations for Reference
|
||||
## Vị Trí Tệp Để Tham Khảo
|
||||
|
||||
```
|
||||
/Users/velikho/Desktop/WORKING/goodgo-platform-ai/apps/api/
|
||||
@@ -280,22 +280,21 @@ Reviews:
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
## Các Bước Tiếp Theo
|
||||
|
||||
1. **Copy reference test patterns:**
|
||||
- Create inquiry and lead handlers already have good test patterns
|
||||
- Controller test for reviews shows endpoint testing approach
|
||||
1. **Sao chép các mẫu kiểm thử tham khảo:**
|
||||
- Các handler tạo inquiry và lead đã có mẫu kiểm thử tốt
|
||||
- Kiểm thử controller cho reviews cho thấy cách tiếp cận kiểm thử endpoint
|
||||
|
||||
2. **Start with repositories:**
|
||||
- Most complex (Prisma mocking)
|
||||
- Most critical (data layer)
|
||||
- Established patterns in existing tests
|
||||
2. **Bắt đầu với repositories:**
|
||||
- Phức tạp nhất (giả lập Prisma)
|
||||
- Quan trọng nhất (tầng dữ liệu)
|
||||
- Các mẫu đã được thiết lập trong các kiểm thử hiện có
|
||||
|
||||
3. **Test DTOs second:**
|
||||
- Quick feedback (class-validator validation)
|
||||
- 10 files but mostly simple
|
||||
|
||||
4. **Controllers and VOs last:**
|
||||
- Build on repository/DTO tests
|
||||
- Depend on handler tests (if testing full flow)
|
||||
3. **Kiểm thử DTO thứ hai:**
|
||||
- Phản hồi nhanh (xác thực class-validator)
|
||||
- 10 tệp nhưng hầu hết đơn giản
|
||||
|
||||
4. **Controllers và VO sau cùng:**
|
||||
- Xây dựng trên các kiểm thử repository/DTO
|
||||
- Phụ thuộc vào các kiểm thử handler (nếu kiểm thử toàn bộ luồng)
|
||||
|
||||
Reference in New Issue
Block a user