From a2952a32a46c0d58e68130f332ad60de0633dda5 Mon Sep 17 00:00:00 2001 From: admin Date: Thu, 21 May 2026 21:51:52 +0700 Subject: [PATCH] test(backend): fix all typescript compiler type errors in test suites --- .../intent-admin.controller.spec.ts | 10 ++++-- .../services/intent-analytics.service.spec.ts | 4 ++- backend/tests/e2e/rfa-workflow.e2e-spec.ts | 3 ++ .../cross-spec/qdrant-isolation.spec.ts | 5 ++- .../performance/approval-matrix.perf-spec.ts | 31 +++++++++++++------ .../performance/review-tasks.perf-spec.ts | 16 +++++++--- 6 files changed, 50 insertions(+), 19 deletions(-) diff --git a/backend/src/modules/ai/intent-classifier/controllers/intent-admin.controller.spec.ts b/backend/src/modules/ai/intent-classifier/controllers/intent-admin.controller.spec.ts index 7c02221f..d71354f2 100644 --- a/backend/src/modules/ai/intent-classifier/controllers/intent-admin.controller.spec.ts +++ b/backend/src/modules/ai/intent-classifier/controllers/intent-admin.controller.spec.ts @@ -1,5 +1,6 @@ // File: src/modules/ai/intent-classifier/controllers/intent-admin.controller.spec.ts // Change Log +// - 2026-05-21: แก้ไขไทป์ให้ตรงกับ Enum ล่าสุด // - 2026-05-19: สร้าง Integration test สำหรับ Admin API (T016, US1). import { Test, TestingModule } from '@nestjs/testing'; @@ -10,7 +11,10 @@ import { } from './intent-admin.controller'; import { IntentDefinitionService } from '../services/intent-definition.service'; import { IntentPatternService } from '../services/intent-pattern.service'; -import { IntentCategory } from '../interfaces/intent-category.enum'; +import { + IntentCategory, + PatternType, +} from '../interfaces/intent-category.enum'; import { JwtAuthGuard } from '../../../../common/guards/jwt-auth.guard'; import { RbacGuard } from '../../../../common/guards/rbac.guard'; @@ -60,7 +64,7 @@ describe('IntentAdminController', () => { describe('findAll', () => { it('ควรเรียก service.findAll พร้อม filter', async () => { - await controller.findAll('read', 'true'); + await controller.findAll(IntentCategory.READ, 'true'); expect(definitionService.findAll).toHaveBeenCalledWith({ category: 'read', @@ -135,7 +139,7 @@ describe('IntentAdminController', () => { describe('createPattern', () => { it('ควร merge intentCode กับ dto', async () => { - const dto = { patternType: 'keyword' as const, patternValue: 'rfa' }; + const dto = { patternType: PatternType.KEYWORD, patternValue: 'rfa' }; patternService.create.mockResolvedValue({ publicId: 'p-1' } as never); await controller.createPattern('GET_RFA', dto); diff --git a/backend/src/modules/ai/intent-classifier/services/intent-analytics.service.spec.ts b/backend/src/modules/ai/intent-classifier/services/intent-analytics.service.spec.ts index b180569a..625de25d 100644 --- a/backend/src/modules/ai/intent-classifier/services/intent-analytics.service.spec.ts +++ b/backend/src/modules/ai/intent-classifier/services/intent-analytics.service.spec.ts @@ -1,5 +1,6 @@ // File: src/modules/ai/intent-classifier/services/intent-analytics.service.spec.ts // Change Log +// - 2026-05-21: แก้ไขการทำ Type Casting ของ AiAuditLog ใน Mock ให้สมบูรณ์ขึ้นด้วย unknown // - 2026-05-19: สร้าง Unit tests สำหรับ IntentAnalyticsService (T033, US3). import { Test, TestingModule } from '@nestjs/testing'; @@ -21,6 +22,7 @@ function mockLog( const intentCode = overrides.intentCode ?? 'GET_RFA'; return { id: Math.floor(Math.random() * 1000), + publicId: 'mock-public-id', aiModel: 'intent-classifier', modelName: method === 'llm_fallback' ? 'gemma4:e4b' : 'pattern-match', aiSuggestionJson: { @@ -33,7 +35,7 @@ function mockLog( confidenceScore: overrides.confidence ?? 1.0, status: overrides.status ?? AiAuditStatus.SUCCESS, createdAt: new Date(), - } as AiAuditLog; + } as unknown as AiAuditLog; } describe('IntentAnalyticsService', () => { diff --git a/backend/tests/e2e/rfa-workflow.e2e-spec.ts b/backend/tests/e2e/rfa-workflow.e2e-spec.ts index e8856ad1..bb22f355 100644 --- a/backend/tests/e2e/rfa-workflow.e2e-spec.ts +++ b/backend/tests/e2e/rfa-workflow.e2e-spec.ts @@ -1,5 +1,6 @@ // File: backend/tests/e2e/rfa-workflow.e2e-spec.ts // Change Log +// - 2026-05-21: แก้ไขไทป์ Record ให้ครอบคลุม ReviewTaskStatus ทั้งหมด (EXPIRED, CANCELLED) // - 2026-05-15: Initial E2E test scaffolding // - 2026-05-16: Simplified to use unit test approach - full E2E requires database // - Note: Full E2E tests require running database and full infrastructure setup @@ -37,6 +38,8 @@ describe('RFA Approval Workflow (E2E)', () => { ], [ReviewTaskStatus.COMPLETED]: [], [ReviewTaskStatus.DELEGATED]: [ReviewTaskStatus.IN_PROGRESS], + [ReviewTaskStatus.EXPIRED]: [], + [ReviewTaskStatus.CANCELLED]: [], }; // Verify status enum values exist diff --git a/backend/tests/integration/cross-spec/qdrant-isolation.spec.ts b/backend/tests/integration/cross-spec/qdrant-isolation.spec.ts index 745a9cd6..b0741c99 100644 --- a/backend/tests/integration/cross-spec/qdrant-isolation.spec.ts +++ b/backend/tests/integration/cross-spec/qdrant-isolation.spec.ts @@ -1,5 +1,6 @@ // File: backend/tests/integration/cross-spec/qdrant-isolation.spec.ts // Change Log: +// - 2026-05-21: แก้ไข Type Casting ของ AiQdrantService ด้วย unknown // - 2026-05-16: Cross-spec integration test for QdrantService projectPublicId isolation // - 2026-05-16: Fixed mocking strategy to use factory pattern with proper method exposure @@ -132,7 +133,9 @@ describe('Cross-Spec: QdrantService Isolation', () => { it('should verify no rawSearch method exists (security)', () => { // Assert: No rawSearch method that bypasses projectPublicId filtering - expect((service as Record).rawSearch).toBeUndefined(); + expect( + (service as unknown as Record).rawSearch + ).toBeUndefined(); }); it('should handle RFA cross-spec usage correctly', async () => { diff --git a/backend/tests/performance/approval-matrix.perf-spec.ts b/backend/tests/performance/approval-matrix.perf-spec.ts index 2ba87fd0..15801336 100644 --- a/backend/tests/performance/approval-matrix.perf-spec.ts +++ b/backend/tests/performance/approval-matrix.perf-spec.ts @@ -1,5 +1,6 @@ // File: backend/tests/performance/approval-matrix.perf-spec.ts // Change Log: +// - 2026-05-21: แก้ไขการจำลองข้อมูลและการคอมไพล์ไทป์ใน ResponseCodeRule // - 2026-05-16: Performance test for Approval Matrix Service with 1000+ rules import { Test, TestingModule } from '@nestjs/testing'; @@ -46,20 +47,25 @@ describe('ApprovalMatrixService Performance', () => { (_, i) => ({ id: i + 1, responseCodeId: (i % 10) + 1, - documentTypeId: (i % 5) + 1, + documentTypeId: 1, isRequired: i % 3 === 0, priority: (i % 5) + 1, + responseCode: { + id: (i % 10) + 1, + code: `CODE-${i % 10}`, + isActive: true, + } as unknown as ResponseCode, }) ); + jest.spyOn(responseCodeRepo, 'find').mockResolvedValue([]); jest - .spyOn(responseCodeRepo, 'find') + .spyOn(responseCodeRuleRepo, 'find') .mockResolvedValue(mockRules as ResponseCodeRule[]); - jest.spyOn(responseCodeRuleRepo, 'find').mockResolvedValue([]); // Act: Measure lookup time const startTime = Date.now(); - const _result = await service.findByDocumentType(1, 'SHOP_DRAWING'); + const _result = await service.findByDocumentType(1, 100); const endTime = Date.now(); // Assert: Must complete within 100ms @@ -81,19 +87,26 @@ describe('ApprovalMatrixService Performance', () => { category: ( ['ENGINEERING', 'CONTRACT', 'QUALITY'] as ResponseCodeCategory[] )[i % 3], - description: `Description for code ${i}`, + descriptionTh: `Description for code ${i}`, }) ); + const mockRules: Partial[] = mockCodes.map((code, i) => ({ + id: i + 1, + responseCodeId: code.id, + documentTypeId: 1, + responseCode: code as ResponseCode, + })); + + jest.spyOn(responseCodeRepo, 'find').mockResolvedValue([]); jest - .spyOn(responseCodeRepo, 'find') - .mockResolvedValue(mockCodes as ResponseCode[]); - jest.spyOn(responseCodeRuleRepo, 'find').mockResolvedValue([]); + .spyOn(responseCodeRuleRepo, 'find') + .mockResolvedValue(mockRules as ResponseCodeRule[]); // Act: Run 10 concurrent lookups const startTime = Date.now(); const promises = Array.from({ length: 10 }, () => - service.findByDocumentType(1, 'SHOP_DRAWING') + service.findByDocumentType(1, 100) ); await Promise.all(promises); const endTime = Date.now(); diff --git a/backend/tests/performance/review-tasks.perf-spec.ts b/backend/tests/performance/review-tasks.perf-spec.ts index d9f54908..2408c3be 100644 --- a/backend/tests/performance/review-tasks.perf-spec.ts +++ b/backend/tests/performance/review-tasks.perf-spec.ts @@ -1,11 +1,13 @@ // File: backend/tests/performance/review-tasks.perf-spec.ts // Change Log: +// - 2026-05-21: แก้ไขไทป์ ReviewTaskStatus ในข้อมูลจำลองและสเปก // - 2026-05-16: Performance test for Review Tasks Query with 10,000+ tasks import { ReviewTask } from '../../src/modules/review-team/entities/review-task.entity'; +import { ReviewTaskStatus } from '../../src/modules/common/enums/review.enums'; interface FindAllOptions { - status?: string; + status?: ReviewTaskStatus; assignedToUserId?: number; disciplineId?: number; page?: number; @@ -69,7 +71,11 @@ describe('ReviewTaskService Query Performance', () => { (_, i) => ({ id: i + 1, uuid: `task-${i}`, - status: ['PENDING', 'IN_PROGRESS', 'COMPLETED'][i % 3], + status: [ + ReviewTaskStatus.PENDING, + ReviewTaskStatus.IN_PROGRESS, + ReviewTaskStatus.COMPLETED, + ][i % 3], assignedToUserId: (i % 100) + 1, rfaRevisionId: (i % 500) + 1, disciplineId: (i % 20) + 1, @@ -81,7 +87,7 @@ describe('ReviewTaskService Query Performance', () => { const startTime = Date.now(); const result = service.findAll({ - status: 'PENDING', + status: ReviewTaskStatus.PENDING, page: 1, limit: 20, }); @@ -99,7 +105,7 @@ describe('ReviewTaskService Query Performance', () => { (_, i) => ({ id: i + 1, uuid: `task-${i}`, - status: 'PENDING', + status: ReviewTaskStatus.PENDING, assignedToUserId: 42, disciplineId: 5, }) @@ -109,7 +115,7 @@ describe('ReviewTaskService Query Performance', () => { const startTime = Date.now(); const result = service.findAll({ - status: 'PENDING', + status: ReviewTaskStatus.PENDING, assignedToUserId: 42, disciplineId: 5, page: 1,