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,29 +1,29 @@
|
||||
# Test Coverage Analysis Report
|
||||
## GoodGo Platform API — Untested Source Files
|
||||
# Báo Cáo Phân Tích Độ Phủ Kiểm Thử
|
||||
## GoodGo Platform API — Các Tệp Nguồn Chưa Được Kiểm Thử
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Working Directory:** `/Users/velikho/Desktop/WORKING/goodgo-platform-ai/apps/api/`
|
||||
**Ngày tạo:** 2026-04-11
|
||||
**Thư mục làm việc:** `/Users/velikho/Desktop/WORKING/goodgo-platform-ai/apps/api/`
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
## Tóm Tắt Điều Hành
|
||||
|
||||
This report catalogs **17 untested source files** across the inquiries, leads, and reviews modules, along with their full implementations. The files fall into four categories:
|
||||
Báo cáo này liệt kê **17 tệp nguồn chưa được kiểm thử** trong các module inquiries, leads, và reviews, cùng toàn bộ phần triển khai của chúng. Các tệp được phân thành bốn nhóm:
|
||||
|
||||
1. **Infrastructure Repositories** (3 files) - Prisma data access layer
|
||||
2. **Domain Value Objects** (2 files) - LeadScore and Rating validation objects
|
||||
3. **Presentation DTOs** (10 files) - Request/response validation classes
|
||||
4. **Presentation Controllers** (2 files) - HTTP endpoint handlers
|
||||
1. **Repository Hạ Tầng** (3 tệp) - Lớp truy cập dữ liệu Prisma
|
||||
2. **Value Object Miền** (2 tệp) - Đối tượng xác thực LeadScore và Rating
|
||||
3. **DTO Trình Bày** (10 tệp) - Các lớp xác thực request/response
|
||||
4. **Controller Trình Bày** (2 tệp) - Bộ xử lý endpoint HTTP
|
||||
|
||||
Two existing test files are provided as reference patterns demonstrating best practices for unit testing handlers and controllers.
|
||||
Hai tệp kiểm thử hiện có được cung cấp như các mẫu tham khảo, minh họa các phương pháp hay nhất cho kiểm thử đơn vị handler và controller.
|
||||
|
||||
---
|
||||
|
||||
# PART 1: INQUIRIES MODULE
|
||||
# PHẦN 1: MODULE INQUIRIES
|
||||
|
||||
## 1.1 Prisma Inquiry Repository
|
||||
|
||||
**File:** `src/modules/inquiries/infrastructure/repositories/prisma-inquiry.repository.ts`
|
||||
**Tệp:** `src/modules/inquiries/infrastructure/repositories/prisma-inquiry.repository.ts`
|
||||
|
||||
```typescript
|
||||
import { Injectable } from '@nestjs/common';
|
||||
@@ -173,26 +173,26 @@ export class PrismaInquiryRepository implements IInquiryRepository {
|
||||
}
|
||||
```
|
||||
|
||||
**Key Methods to Test:**
|
||||
- `findById()` - Returns inquiry by ID or null if not found
|
||||
- `save()` - Creates new inquiry record
|
||||
- `markAsRead()` - Updates isRead flag
|
||||
- `findByListing()` - Paginated query by listing, includes relationships
|
||||
- `findByAgent()` - Paginated query through listing agent relationship
|
||||
- `countUnreadByAgent()` - Aggregation query for unread count
|
||||
- `toDomain()` - Private mapper converting Prisma model to domain entity
|
||||
**Các Phương Thức Cần Kiểm Thử:**
|
||||
- `findById()` - Trả về inquiry theo ID hoặc null nếu không tìm thấy
|
||||
- `save()` - Tạo bản ghi inquiry mới
|
||||
- `markAsRead()` - Cập nhật cờ isRead
|
||||
- `findByListing()` - Truy vấn phân trang theo listing, bao gồm các quan hệ
|
||||
- `findByAgent()` - Truy vấn phân trang qua quan hệ agent của listing
|
||||
- `countUnreadByAgent()` - Truy vấn tổng hợp đếm số lượng chưa đọc
|
||||
- `toDomain()` - Bộ ánh xạ riêng tư chuyển đổi model Prisma sang domain entity
|
||||
|
||||
**Test Scenarios:**
|
||||
- All methods with valid inputs
|
||||
- Null returns (no matching records)
|
||||
- Pagination edge cases (page bounds, limit clamping)
|
||||
- Data mapping accuracy (ISO dates, relationship joins)
|
||||
**Các Kịch Bản Kiểm Thử:**
|
||||
- Tất cả phương thức với đầu vào hợp lệ
|
||||
- Trả về null (không có bản ghi phù hợp)
|
||||
- Các trường hợp biên của phân trang (giới hạn trang, giới hạn số lượng)
|
||||
- Độ chính xác ánh xạ dữ liệu (ngày ISO, kết nối quan hệ)
|
||||
|
||||
---
|
||||
|
||||
## 1.2 Inquiries Controller
|
||||
|
||||
**File:** `src/modules/inquiries/presentation/controllers/inquiries.controller.ts`
|
||||
**Tệp:** `src/modules/inquiries/presentation/controllers/inquiries.controller.ts`
|
||||
|
||||
```typescript
|
||||
import {
|
||||
@@ -317,23 +317,23 @@ export class InquiriesController {
|
||||
}
|
||||
```
|
||||
|
||||
**Key Endpoints to Test:**
|
||||
- `POST /inquiries` - Create inquiry with phone optional
|
||||
- `GET /inquiries/listing/:listingId` - List by listing with pagination
|
||||
- `GET /inquiries/agent/me` - List for authenticated agent with AGENT role guard
|
||||
- `PATCH /inquiries/:id/read` - Mark as read with role guard
|
||||
**Các Endpoint Cần Kiểm Thử:**
|
||||
- `POST /inquiries` - Tạo inquiry với số điện thoại tùy chọn
|
||||
- `GET /inquiries/listing/:listingId` - Danh sách theo listing có phân trang
|
||||
- `GET /inquiries/agent/me` - Danh sách cho agent đã xác thực với guard vai trò AGENT
|
||||
- `PATCH /inquiries/:id/read` - Đánh dấu đã đọc với guard vai trò
|
||||
|
||||
**Test Scenarios:**
|
||||
- Command/query bus dispatch with correct parameters
|
||||
- Default pagination values (page: 1, limit: 20)
|
||||
- Null phone handling (converts to null when not provided)
|
||||
- Guard/decorator enforcement (JwtAuthGuard, RolesGuard, @Roles('AGENT'))
|
||||
**Các Kịch Bản Kiểm Thử:**
|
||||
- Gửi lệnh/truy vấn đến bus với các tham số đúng
|
||||
- Giá trị phân trang mặc định (page: 1, limit: 20)
|
||||
- Xử lý phone null (chuyển thành null khi không cung cấp)
|
||||
- Kiểm tra thực thi guard/decorator (JwtAuthGuard, RolesGuard, @Roles('AGENT'))
|
||||
|
||||
---
|
||||
|
||||
## 1.3 Create Inquiry DTO
|
||||
|
||||
**File:** `src/modules/inquiries/presentation/dto/create-inquiry.dto.ts`
|
||||
**Tệp:** `src/modules/inquiries/presentation/dto/create-inquiry.dto.ts`
|
||||
|
||||
```typescript
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
@@ -358,22 +358,22 @@ export class CreateInquiryDto {
|
||||
}
|
||||
```
|
||||
|
||||
**Validations:**
|
||||
- `listingId` - Required string
|
||||
- `message` - Required string, max 2000 characters
|
||||
- `phone` - Optional string
|
||||
**Các Quy Tắc Xác Thực:**
|
||||
- `listingId` - Chuỗi bắt buộc
|
||||
- `message` - Chuỗi bắt buộc, tối đa 2000 ký tự
|
||||
- `phone` - Chuỗi tùy chọn
|
||||
|
||||
**Test Scenarios:**
|
||||
- Valid input with all fields
|
||||
- Valid input without phone
|
||||
- Missing required fields
|
||||
- Message exceeding 2000 characters
|
||||
**Các Kịch Bản Kiểm Thử:**
|
||||
- Đầu vào hợp lệ với tất cả các trường
|
||||
- Đầu vào hợp lệ không có phone
|
||||
- Thiếu các trường bắt buộc
|
||||
- Message vượt quá 2000 ký tự
|
||||
|
||||
---
|
||||
|
||||
## 1.4 List Inquiries DTO
|
||||
|
||||
**File:** `src/modules/inquiries/presentation/dto/list-inquiries.dto.ts`
|
||||
**Tệp:** `src/modules/inquiries/presentation/dto/list-inquiries.dto.ts`
|
||||
|
||||
```typescript
|
||||
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||
@@ -398,23 +398,23 @@ export class ListInquiriesDto {
|
||||
}
|
||||
```
|
||||
|
||||
**Validations:**
|
||||
- `page` - Optional integer, minimum 1
|
||||
- `limit` - Optional integer, min 1, max 100
|
||||
**Các Quy Tắc Xác Thực:**
|
||||
- `page` - Số nguyên tùy chọn, tối thiểu 1
|
||||
- `limit` - Số nguyên tùy chọn, tối thiểu 1, tối đa 100
|
||||
|
||||
**Test Scenarios:**
|
||||
- Valid pagination (page: 1, limit: 20)
|
||||
- Custom pagination
|
||||
- Invalid: page < 1, limit < 1, limit > 100
|
||||
- Type transformation (string to number)
|
||||
**Các Kịch Bản Kiểm Thử:**
|
||||
- Phân trang hợp lệ (page: 1, limit: 20)
|
||||
- Phân trang tùy chỉnh
|
||||
- Không hợp lệ: page < 1, limit < 1, limit > 100
|
||||
- Chuyển đổi kiểu dữ liệu (chuỗi sang số)
|
||||
|
||||
---
|
||||
|
||||
# PART 2: LEADS MODULE
|
||||
# PHẦN 2: MODULE LEADS
|
||||
|
||||
## 2.1 Prisma Lead Repository
|
||||
|
||||
**File:** `src/modules/leads/infrastructure/repositories/prisma-lead.repository.ts`
|
||||
**Tệp:** `src/modules/leads/infrastructure/repositories/prisma-lead.repository.ts`
|
||||
|
||||
```typescript
|
||||
import { Injectable } from '@nestjs/common';
|
||||
@@ -570,27 +570,27 @@ export class PrismaLeadRepository implements ILeadRepository {
|
||||
}
|
||||
```
|
||||
|
||||
**Key Methods to Test:**
|
||||
- `findById()` - Returns lead or null
|
||||
- `save()` - Creates lead with optional score
|
||||
- `update()` - Updates status, score, notes
|
||||
- `delete()` - Deletes lead
|
||||
- `findByAgent()` - Paginated with optional status filter
|
||||
- `getStatsByAgent()` - Aggregates by status, calculates conversion rate and avg score
|
||||
- `toDomain()` - Maps Prisma model including LeadScore VO instantiation
|
||||
**Các Phương Thức Cần Kiểm Thử:**
|
||||
- `findById()` - Trả về lead hoặc null
|
||||
- `save()` - Tạo lead với điểm tùy chọn
|
||||
- `update()` - Cập nhật trạng thái, điểm, ghi chú
|
||||
- `delete()` - Xóa lead
|
||||
- `findByAgent()` - Phân trang với bộ lọc trạng thái tùy chọn
|
||||
- `getStatsByAgent()` - Tổng hợp theo trạng thái, tính tỷ lệ chuyển đổi và điểm trung bình
|
||||
- `toDomain()` - Ánh xạ model Prisma bao gồm khởi tạo LeadScore VO
|
||||
|
||||
**Test Scenarios:**
|
||||
- CRUD operations
|
||||
- Optional score handling (null and valid values)
|
||||
- Status filtering in paginated query
|
||||
- Stats calculations (zero leads, no scores, conversion rate precision)
|
||||
- Pagination edge cases
|
||||
**Các Kịch Bản Kiểm Thử:**
|
||||
- Các thao tác CRUD
|
||||
- Xử lý điểm tùy chọn (null và giá trị hợp lệ)
|
||||
- Lọc trạng thái trong truy vấn phân trang
|
||||
- Tính toán thống kê (không có lead, không có điểm, độ chính xác tỷ lệ chuyển đổi)
|
||||
- Các trường hợp biên của phân trang
|
||||
|
||||
---
|
||||
|
||||
## 2.2 Lead Score Value Object
|
||||
|
||||
**File:** `src/modules/leads/domain/value-objects/lead-score.vo.ts`
|
||||
**Tệp:** `src/modules/leads/domain/value-objects/lead-score.vo.ts`
|
||||
|
||||
```typescript
|
||||
import { Result, ValueObject } from '@modules/shared';
|
||||
@@ -611,20 +611,20 @@ export class LeadScore extends ValueObject<LeadScoreProps> {
|
||||
}
|
||||
```
|
||||
|
||||
**Validation Rules:**
|
||||
- Value must be integer between 0 and 100 inclusive
|
||||
**Các Quy Tắc Xác Thực:**
|
||||
- Giá trị phải là số nguyên trong khoảng từ 0 đến 100 (bao gồm hai đầu)
|
||||
|
||||
**Test Scenarios:**
|
||||
- Valid scores (0, 50, 100)
|
||||
- Invalid: negative, > 100, null, string
|
||||
- Error message in Vietnamese
|
||||
- Value object equality (should be comparable)
|
||||
**Các Kịch Bản Kiểm Thử:**
|
||||
- Điểm hợp lệ (0, 50, 100)
|
||||
- Không hợp lệ: âm, > 100, null, chuỗi
|
||||
- Thông báo lỗi bằng tiếng Việt
|
||||
- Tính bằng nhau của value object (phải có thể so sánh)
|
||||
|
||||
---
|
||||
|
||||
## 2.3 Leads Controller
|
||||
|
||||
**File:** `src/modules/leads/presentation/controllers/leads.controller.ts`
|
||||
**Tệp:** `src/modules/leads/presentation/controllers/leads.controller.ts`
|
||||
|
||||
```typescript
|
||||
import {
|
||||
@@ -755,25 +755,25 @@ export class LeadsController {
|
||||
}
|
||||
```
|
||||
|
||||
**Key Endpoints to Test:**
|
||||
- `POST /leads` - Create lead with optional email, score, notes
|
||||
- `GET /leads` - List agent's leads with optional status filter
|
||||
- `GET /leads/stats` - Stats aggregation
|
||||
- `PATCH /leads/:id/status` - Update lead status
|
||||
- `DELETE /leads/:id` - Delete lead
|
||||
**Các Endpoint Cần Kiểm Thử:**
|
||||
- `POST /leads` - Tạo lead với email, điểm, ghi chú tùy chọn
|
||||
- `GET /leads` - Danh sách lead của agent với bộ lọc trạng thái tùy chọn
|
||||
- `GET /leads/stats` - Tổng hợp thống kê
|
||||
- `PATCH /leads/:id/status` - Cập nhật trạng thái lead
|
||||
- `DELETE /leads/:id` - Xóa lead
|
||||
|
||||
**Test Scenarios:**
|
||||
- Class-level guard (@Roles('AGENT') applies to all methods)
|
||||
- Optional field handling (email, score, notes → null)
|
||||
- Status filtering (null passes through, specific status filters)
|
||||
- Command/query parameter mapping
|
||||
- Return types verify (updated: true, deleted: true)
|
||||
**Các Kịch Bản Kiểm Thử:**
|
||||
- Guard cấp lớp (@Roles('AGENT') áp dụng cho tất cả phương thức)
|
||||
- Xử lý trường tùy chọn (email, score, notes → null)
|
||||
- Lọc trạng thái (null truyền qua, trạng thái cụ thể lọc kết quả)
|
||||
- Ánh xạ tham số lệnh/truy vấn
|
||||
- Xác minh kiểu trả về (updated: true, deleted: true)
|
||||
|
||||
---
|
||||
|
||||
## 2.4 Create Lead DTO
|
||||
|
||||
**File:** `src/modules/leads/presentation/dto/create-lead.dto.ts`
|
||||
**Tệp:** `src/modules/leads/presentation/dto/create-lead.dto.ts`
|
||||
|
||||
```typescript
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
@@ -813,26 +813,26 @@ export class CreateLeadDto {
|
||||
}
|
||||
```
|
||||
|
||||
**Validations:**
|
||||
- `name` - Required string
|
||||
- `phone` - Required string
|
||||
- `email` - Optional, must be valid email format
|
||||
- `source` - Required string
|
||||
- `score` - Optional number, 0-100
|
||||
- `notes` - Optional object
|
||||
**Các Quy Tắc Xác Thực:**
|
||||
- `name` - Chuỗi bắt buộc
|
||||
- `phone` - Chuỗi bắt buộc
|
||||
- `email` - Tùy chọn, phải đúng định dạng email
|
||||
- `source` - Chuỗi bắt buộc
|
||||
- `score` - Số tùy chọn, 0-100
|
||||
- `notes` - Đối tượng tùy chọn
|
||||
|
||||
**Test Scenarios:**
|
||||
- All required fields present
|
||||
- Optional fields omitted
|
||||
- Invalid email format
|
||||
- Score out of range
|
||||
- Invalid note type
|
||||
**Các Kịch Bản Kiểm Thử:**
|
||||
- Tất cả các trường bắt buộc có mặt
|
||||
- Bỏ qua các trường tùy chọn
|
||||
- Định dạng email không hợp lệ
|
||||
- Điểm ngoài phạm vi
|
||||
- Kiểu notes không hợp lệ
|
||||
|
||||
---
|
||||
|
||||
## 2.5 List Leads DTO
|
||||
|
||||
**File:** `src/modules/leads/presentation/dto/list-leads.dto.ts`
|
||||
**Tệp:** `src/modules/leads/presentation/dto/list-leads.dto.ts`
|
||||
|
||||
```typescript
|
||||
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||
@@ -867,23 +867,23 @@ export class ListLeadsDto {
|
||||
}
|
||||
```
|
||||
|
||||
**Validations:**
|
||||
- `status` - Optional, must be one of: NEW, CONTACTED, QUALIFIED, NEGOTIATING, CONVERTED, LOST
|
||||
- `page` - Optional integer, minimum 1
|
||||
- `limit` - Optional integer, 1-100
|
||||
**Các Quy Tắc Xác Thực:**
|
||||
- `status` - Tùy chọn, phải là một trong: NEW, CONTACTED, QUALIFIED, NEGOTIATING, CONVERTED, LOST
|
||||
- `page` - Số nguyên tùy chọn, tối thiểu 1
|
||||
- `limit` - Số nguyên tùy chọn, 1-100
|
||||
|
||||
**Test Scenarios:**
|
||||
- Valid pagination
|
||||
- Valid status values
|
||||
- Invalid status
|
||||
- Type transformation (string to number)
|
||||
- Boundary checks
|
||||
**Các Kịch Bản Kiểm Thử:**
|
||||
- Phân trang hợp lệ
|
||||
- Giá trị trạng thái hợp lệ
|
||||
- Trạng thái không hợp lệ
|
||||
- Chuyển đổi kiểu dữ liệu (chuỗi sang số)
|
||||
- Kiểm tra biên
|
||||
|
||||
---
|
||||
|
||||
## 2.6 Update Lead Status DTO
|
||||
|
||||
**File:** `src/modules/leads/presentation/dto/update-lead-status.dto.ts`
|
||||
**Tệp:** `src/modules/leads/presentation/dto/update-lead-status.dto.ts`
|
||||
|
||||
```typescript
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
@@ -902,21 +902,21 @@ export class UpdateLeadStatusDto {
|
||||
}
|
||||
```
|
||||
|
||||
**Validations:**
|
||||
- `status` - Required, must be valid lead status
|
||||
**Các Quy Tắc Xác Thực:**
|
||||
- `status` - Bắt buộc, phải là trạng thái lead hợp lệ
|
||||
|
||||
**Test Scenarios:**
|
||||
- Valid status transitions
|
||||
- Invalid status
|
||||
- Missing status field
|
||||
**Các Kịch Bản Kiểm Thử:**
|
||||
- Các chuyển đổi trạng thái hợp lệ
|
||||
- Trạng thái không hợp lệ
|
||||
- Thiếu trường status
|
||||
|
||||
---
|
||||
|
||||
# PART 3: REVIEWS MODULE
|
||||
# PHẦN 3: MODULE REVIEWS
|
||||
|
||||
## 3.1 Prisma Review Repository
|
||||
|
||||
**File:** `src/modules/reviews/infrastructure/repositories/prisma-review.repository.ts`
|
||||
**Tệp:** `src/modules/reviews/infrastructure/repositories/prisma-review.repository.ts`
|
||||
|
||||
```typescript
|
||||
import { Injectable } from '@nestjs/common';
|
||||
@@ -1083,29 +1083,29 @@ export class PrismaReviewRepository implements IReviewRepository {
|
||||
}
|
||||
```
|
||||
|
||||
**Key Methods to Test:**
|
||||
- `findById()` - Returns review or null
|
||||
- `findByUserAndTarget()` - Unique constraint check
|
||||
- `save()` - Creates review with optional comment
|
||||
- `delete()` - Deletes review
|
||||
- `findByTarget()` - Paginated list with user join
|
||||
- `findByUserId()` - Paginated list by user
|
||||
- `getStats()` - Calculates average rating and distribution
|
||||
- `toDomain()` - Maps Prisma model including Rating VO
|
||||
**Các Phương Thức Cần Kiểm Thử:**
|
||||
- `findById()` - Trả về review hoặc null
|
||||
- `findByUserAndTarget()` - Kiểm tra ràng buộc duy nhất
|
||||
- `save()` - Tạo review với bình luận tùy chọn
|
||||
- `delete()` - Xóa review
|
||||
- `findByTarget()` - Danh sách phân trang với kết nối user
|
||||
- `findByUserId()` - Danh sách phân trang theo user
|
||||
- `getStats()` - Tính điểm đánh giá trung bình và phân phối
|
||||
- `toDomain()` - Ánh xạ model Prisma bao gồm Rating VO
|
||||
|
||||
**Test Scenarios:**
|
||||
- All CRUD operations
|
||||
- Optional comment handling
|
||||
- Pagination with relationships (user fullName join)
|
||||
- Stats with distribution calculation (1-5 scale)
|
||||
- Zero reviews edge case
|
||||
- Data accuracy (ISO dates, decimal rounding)
|
||||
**Các Kịch Bản Kiểm Thử:**
|
||||
- Tất cả các thao tác CRUD
|
||||
- Xử lý bình luận tùy chọn
|
||||
- Phân trang với quan hệ (kết nối fullName của user)
|
||||
- Thống kê với tính toán phân phối (thang 1-5)
|
||||
- Trường hợp biên không có review
|
||||
- Độ chính xác dữ liệu (ngày ISO, làm tròn thập phân)
|
||||
|
||||
---
|
||||
|
||||
## 3.2 Rating Value Object
|
||||
|
||||
**File:** `src/modules/reviews/domain/value-objects/rating.vo.ts`
|
||||
**Tệp:** `src/modules/reviews/domain/value-objects/rating.vo.ts`
|
||||
|
||||
```typescript
|
||||
import { Result, ValueObject } from '@modules/shared';
|
||||
@@ -1126,20 +1126,20 @@ export class Rating extends ValueObject<RatingProps> {
|
||||
}
|
||||
```
|
||||
|
||||
**Validation Rules:**
|
||||
- Must be integer between 1 and 5 inclusive
|
||||
**Các Quy Tắc Xác Thực:**
|
||||
- Phải là số nguyên trong khoảng từ 1 đến 5 (bao gồm hai đầu)
|
||||
|
||||
**Test Scenarios:**
|
||||
- Valid ratings (1-5)
|
||||
- Invalid: 0, 6, -1, null, float (2.5), non-integer
|
||||
- Error message verification
|
||||
- Value object creation and equality
|
||||
**Các Kịch Bản Kiểm Thử:**
|
||||
- Đánh giá hợp lệ (1-5)
|
||||
- Không hợp lệ: 0, 6, -1, null, số thực (2.5), không phải số nguyên
|
||||
- Xác minh thông báo lỗi
|
||||
- Tạo value object và kiểm tra tính bằng nhau
|
||||
|
||||
---
|
||||
|
||||
## 3.3 Create Review DTO
|
||||
|
||||
**File:** `src/modules/reviews/presentation/dto/create-review.dto.ts`
|
||||
**Tệp:** `src/modules/reviews/presentation/dto/create-review.dto.ts`
|
||||
|
||||
```typescript
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
@@ -1170,24 +1170,24 @@ export class CreateReviewDto {
|
||||
}
|
||||
```
|
||||
|
||||
**Validations:**
|
||||
- `targetType` - Required string (e.g. "agent", "property")
|
||||
- `targetId` - Required string
|
||||
- `rating` - Required integer, 1-5
|
||||
- `comment` - Optional string, max 2000 characters
|
||||
**Các Quy Tắc Xác Thực:**
|
||||
- `targetType` - Chuỗi bắt buộc (ví dụ: "agent", "property")
|
||||
- `targetId` - Chuỗi bắt buộc
|
||||
- `rating` - Số nguyên bắt buộc, 1-5
|
||||
- `comment` - Chuỗi tùy chọn, tối đa 2000 ký tự
|
||||
|
||||
**Test Scenarios:**
|
||||
- Valid review with all fields
|
||||
- Valid without comment
|
||||
- Missing required fields
|
||||
- Invalid rating (0, 6, 2.5)
|
||||
- Comment exceeding max length
|
||||
**Các Kịch Bản Kiểm Thử:**
|
||||
- Review hợp lệ với tất cả các trường
|
||||
- Hợp lệ không có bình luận
|
||||
- Thiếu các trường bắt buộc
|
||||
- Đánh giá không hợp lệ (0, 6, 2.5)
|
||||
- Bình luận vượt quá độ dài tối đa
|
||||
|
||||
---
|
||||
|
||||
## 3.4 List Reviews DTOs
|
||||
|
||||
**File:** `src/modules/reviews/presentation/dto/list-reviews.dto.ts`
|
||||
**Tệp:** `src/modules/reviews/presentation/dto/list-reviews.dto.ts`
|
||||
|
||||
```typescript
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
@@ -1234,26 +1234,26 @@ export class ReviewStatsDto {
|
||||
}
|
||||
```
|
||||
|
||||
**ListReviewsByTargetDto Validations:**
|
||||
- `targetType` - Required string
|
||||
- `targetId` - Required string
|
||||
- `page` - Optional, min 1
|
||||
- `limit` - Optional, 1-100
|
||||
**Các Quy Tắc Xác Thực của ListReviewsByTargetDto:**
|
||||
- `targetType` - Chuỗi bắt buộc
|
||||
- `targetId` - Chuỗi bắt buộc
|
||||
- `page` - Tùy chọn, tối thiểu 1
|
||||
- `limit` - Tùy chọn, 1-100
|
||||
|
||||
**ReviewStatsDto Validations:**
|
||||
- `targetType` - Required string
|
||||
- `targetId` - Required string
|
||||
**Các Quy Tắc Xác Thực của ReviewStatsDto:**
|
||||
- `targetType` - Chuỗi bắt buộc
|
||||
- `targetId` - Chuỗi bắt buộc
|
||||
|
||||
**Test Scenarios:**
|
||||
- Valid pagination with required target fields
|
||||
- Type transformation
|
||||
- Boundary checks on pagination
|
||||
**Các Kịch Bản Kiểm Thử:**
|
||||
- Phân trang hợp lệ với các trường target bắt buộc
|
||||
- Chuyển đổi kiểu dữ liệu
|
||||
- Kiểm tra biên phân trang
|
||||
|
||||
---
|
||||
|
||||
## 3.5 Reviews Controller
|
||||
|
||||
**File:** `src/modules/reviews/presentation/controllers/reviews.controller.ts`
|
||||
**Tệp:** `src/modules/reviews/presentation/controllers/reviews.controller.ts`
|
||||
|
||||
```typescript
|
||||
import {
|
||||
@@ -1380,27 +1380,27 @@ export class ReviewsController {
|
||||
}
|
||||
```
|
||||
|
||||
**Key Endpoints to Test:**
|
||||
- `POST /reviews` - Create with optional comment
|
||||
- `GET /reviews` - List by target (no auth required)
|
||||
- `GET /reviews/stats` - Stats for target (no auth required)
|
||||
- `GET /reviews/me` - List user's reviews (requires auth)
|
||||
- `DELETE /reviews/:id` - Delete review (requires auth)
|
||||
**Các Endpoint Cần Kiểm Thử:**
|
||||
- `POST /reviews` - Tạo với bình luận tùy chọn
|
||||
- `GET /reviews` - Danh sách theo target (không yêu cầu xác thực)
|
||||
- `GET /reviews/stats` - Thống kê cho target (không yêu cầu xác thực)
|
||||
- `GET /reviews/me` - Danh sách review của user (yêu cầu xác thực)
|
||||
- `DELETE /reviews/:id` - Xóa review (yêu cầu xác thực)
|
||||
|
||||
**Test Scenarios:**
|
||||
- Command/query dispatch with correct parameters
|
||||
- Default pagination (1, 20)
|
||||
- Null comment handling
|
||||
- Auth requirements (JWT for POST, GET /me, DELETE; no auth for GET, GET/stats)
|
||||
- Return types (deleted: true)
|
||||
**Các Kịch Bản Kiểm Thử:**
|
||||
- Gửi lệnh/truy vấn với các tham số đúng
|
||||
- Phân trang mặc định (1, 20)
|
||||
- Xử lý bình luận null
|
||||
- Yêu cầu xác thực (JWT cho POST, GET /me, DELETE; không xác thực cho GET, GET/stats)
|
||||
- Kiểu trả về (deleted: true)
|
||||
|
||||
---
|
||||
|
||||
# PART 4: REFERENCE TEST PATTERNS
|
||||
# PHẦN 4: CÁC MẪU KIỂM THỬ THAM KHẢO
|
||||
|
||||
## 4.1 Example Handler Test: Create Inquiry Handler
|
||||
## 4.1 Ví Dụ Kiểm Thử Handler: Create Inquiry Handler
|
||||
|
||||
**File:** `src/modules/inquiries/application/__tests__/create-inquiry.handler.spec.ts`
|
||||
**Tệp:** `src/modules/inquiries/application/__tests__/create-inquiry.handler.spec.ts`
|
||||
|
||||
```typescript
|
||||
import type { EventBus } from '@nestjs/cqrs';
|
||||
@@ -1503,19 +1503,19 @@ describe('CreateInquiryHandler', () => {
|
||||
});
|
||||
```
|
||||
|
||||
**Pattern Insights:**
|
||||
- Uses `vi.fn()` from Vitest for mocking
|
||||
- Mock all repository methods in beforeEach
|
||||
- Test happy path with all dependencies mocked
|
||||
- Test error scenarios (NotFoundException)
|
||||
- Verify side effects (event publishing)
|
||||
- Uses exact parameter checking or matchers (`expect.objectContaining`)
|
||||
**Nhận Xét về Mẫu:**
|
||||
- Sử dụng `vi.fn()` từ Vitest để mock
|
||||
- Mock tất cả các phương thức repository trong beforeEach
|
||||
- Kiểm tra đường dẫn thành công với tất cả dependencies đã được mock
|
||||
- Kiểm tra các kịch bản lỗi (NotFoundException)
|
||||
- Xác minh các hiệu ứng phụ (publishing sự kiện)
|
||||
- Sử dụng kiểm tra tham số chính xác hoặc matcher (`expect.objectContaining`)
|
||||
|
||||
---
|
||||
|
||||
## 4.2 Example Handler Test: Create Lead Handler
|
||||
## 4.2 Ví Dụ Kiểm Thử Handler: Create Lead Handler
|
||||
|
||||
**File:** `src/modules/leads/application/__tests__/create-lead.handler.spec.ts`
|
||||
**Tệp:** `src/modules/leads/application/__tests__/create-lead.handler.spec.ts`
|
||||
|
||||
```typescript
|
||||
import type { EventBus } from '@nestjs/cqrs';
|
||||
@@ -1640,16 +1640,16 @@ describe('CreateLeadHandler', () => {
|
||||
});
|
||||
```
|
||||
|
||||
**Additional Pattern Notes:**
|
||||
- Tests optional parameter handling (score: null)
|
||||
- Tests validation errors from value objects (LeadScore)
|
||||
- Uses same mock setup structure as inquiry handler
|
||||
**Ghi Chú Bổ Sung về Mẫu:**
|
||||
- Kiểm tra xử lý tham số tùy chọn (score: null)
|
||||
- Kiểm tra lỗi xác thực từ value object (LeadScore)
|
||||
- Sử dụng cấu trúc mock thiết lập giống như inquiry handler
|
||||
|
||||
---
|
||||
|
||||
## 4.3 Example Controller Test: Reviews Controller
|
||||
## 4.3 Ví Dụ Kiểm Thử Controller: Reviews Controller
|
||||
|
||||
**File:** `src/modules/reviews/presentation/__tests__/reviews.controller.spec.ts`
|
||||
**Tệp:** `src/modules/reviews/presentation/__tests__/reviews.controller.spec.ts`
|
||||
|
||||
```typescript
|
||||
import { CreateReviewCommand } from '../../application/commands/create-review/create-review.command';
|
||||
@@ -1788,19 +1788,19 @@ describe('ReviewsController', () => {
|
||||
});
|
||||
```
|
||||
|
||||
**Controller Test Pattern Insights:**
|
||||
- Organized by endpoint using describe blocks
|
||||
- Tests dispatch with correct command/query types
|
||||
- Verifies individual command properties after dispatch
|
||||
- Tests default parameter handling
|
||||
- Tests optional field handling (comment null)
|
||||
- Tests return type verification
|
||||
**Nhận Xét về Mẫu Kiểm Thử Controller:**
|
||||
- Tổ chức theo endpoint sử dụng các khối describe
|
||||
- Kiểm tra việc gửi với đúng kiểu lệnh/truy vấn
|
||||
- Xác minh từng thuộc tính lệnh sau khi gửi
|
||||
- Kiểm tra xử lý tham số mặc định
|
||||
- Kiểm tra xử lý trường tùy chọn (comment null)
|
||||
- Kiểm tra xác minh kiểu trả về
|
||||
|
||||
---
|
||||
|
||||
# SUMMARY TABLE
|
||||
# BẢNG TÓM TẮT
|
||||
|
||||
| File | Module | Type | Key Tests |
|
||||
| Tệp | Module | Loại | Các Kiểm Thử Chính |
|
||||
|------|--------|------|-----------|
|
||||
| prisma-inquiry.repository.ts | Inquiries | Repository | findById, save, markAsRead, findByListing, findByAgent, countUnreadByAgent, toDomain |
|
||||
| inquiries.controller.ts | Inquiries | Controller | POST create, GET by listing, GET by agent, PATCH mark read, guard enforcement |
|
||||
@@ -1820,22 +1820,21 @@ describe('ReviewsController', () => {
|
||||
|
||||
---
|
||||
|
||||
# TESTING PRIORITIES
|
||||
# ƯU TIÊN KIỂM THỬ
|
||||
|
||||
**High Priority (Critical Business Logic):**
|
||||
1. Repository methods - data integrity, pagination accuracy
|
||||
2. Value objects - validation, error messages
|
||||
3. Controllers - command dispatch, parameter mapping
|
||||
4. DTOs - validation rules, type transformation
|
||||
**Ưu Tiên Cao (Logic Nghiệp Vụ Quan Trọng):**
|
||||
1. Các phương thức Repository - tính toàn vẹn dữ liệu, độ chính xác phân trang
|
||||
2. Value Object - xác thực, thông báo lỗi
|
||||
3. Controller - gửi lệnh, ánh xạ tham số
|
||||
4. DTO - quy tắc xác thực, chuyển đổi kiểu dữ liệu
|
||||
|
||||
**Medium Priority (Guard Rails):**
|
||||
1. Optional field handling
|
||||
2. Null/undefined coercion (→ null)
|
||||
3. Pagination boundary checks
|
||||
4. Aggregation calculations (avg, sum, distribution)
|
||||
|
||||
**Low Priority (Framework):**
|
||||
1. Decorator validation (framework responsibility)
|
||||
2. Error serialization
|
||||
3. Swagger documentation
|
||||
**Ưu Tiên Trung Bình (Bảo Vệ An Toàn):**
|
||||
1. Xử lý trường tùy chọn
|
||||
2. Ép kiểu null/undefined (→ null)
|
||||
3. Kiểm tra biên phân trang
|
||||
4. Tính toán tổng hợp (trung bình, tổng, phân phối)
|
||||
|
||||
**Ưu Tiên Thấp (Framework):**
|
||||
1. Xác thực decorator (trách nhiệm của framework)
|
||||
2. Tuần tự hóa lỗi
|
||||
3. Tài liệu Swagger
|
||||
|
||||
Reference in New Issue
Block a user