test(frontend): add test coverage for drawing, organization, and migration services

This commit is contained in:
2026-06-13 22:46:56 +07:00
parent 9c5df0abdb
commit e3503b6a77
7 changed files with 674 additions and 0 deletions
@@ -0,0 +1,58 @@
// File: frontend/lib/services/__tests__/asbuilt-drawing.service.test.ts
// Change Log:
// - 2026-06-13: Initial creation - test coverage for asbuilt-drawing service
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { asBuiltDrawingService } from '../asbuilt-drawing.service';
import apiClient from '@/lib/api/client';
// Mock apiClient
vi.mock('@/lib/api/client', () => ({
default: {
get: vi.fn(),
post: vi.fn(),
},
}));
describe('asBuiltDrawingService', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('ควรดึงข้อมูลรายการ as built drawings สำเร็จ', async () => {
const mockParams = { search: 'AD-01' };
const mockResponse = { data: [{ publicId: '019505a1-7c3e-7000-8000-ad1111111111', drawingNo: 'AD-001' }] };
vi.mocked(apiClient.get).mockResolvedValue({ data: mockResponse });
const result = await asBuiltDrawingService.getAll(mockParams);
expect(result).toEqual(mockResponse);
expect(apiClient.get).toHaveBeenCalledWith('/drawings/asbuilt', { params: mockParams });
});
it('ควรดึงรายละเอียดของ as built drawing สำเร็จ', async () => {
const uuid = '019505a1-7c3e-7000-8000-ad1111111111';
const mockResponse = { data: { publicId: uuid, drawingNo: 'AD-001' } };
vi.mocked(apiClient.get).mockResolvedValue({ data: mockResponse });
const result = await asBuiltDrawingService.getByUuid(uuid);
expect(result).toEqual(mockResponse);
expect(apiClient.get).toHaveBeenCalledWith(`/drawings/asbuilt/${uuid}`);
});
it('ควรสร้าง as built drawing สำเร็จ', async () => {
const mockDto = { drawingNo: 'AD-001', subject: 'Test As Built Drawing' };
const mockResponse = { data: { publicId: '019505a1-7c3e-7000-8000-ad1111111111' } };
vi.mocked(apiClient.post).mockResolvedValue({ data: mockResponse });
const result = await asBuiltDrawingService.create(mockDto as any);
expect(result).toEqual(mockResponse);
expect(apiClient.post).toHaveBeenCalledWith('/drawings/asbuilt', mockDto);
});
it('ควรสร้าง revision ใหม่ของ as built drawing สำเร็จ', async () => {
const uuid = '019505a1-7c3e-7000-8000-ad1111111111';
const mockDto = { revisionNo: 'A', comment: 'New Revision' };
const mockResponse = { data: { success: true } };
vi.mocked(apiClient.post).mockResolvedValue({ data: mockResponse });
const result = await asBuiltDrawingService.createRevision(uuid, mockDto as any);
expect(result).toEqual(mockResponse);
expect(apiClient.post).toHaveBeenCalledWith(`/drawings/asbuilt/${uuid}/revisions`, mockDto);
});
});
@@ -0,0 +1,69 @@
// File: frontend/lib/services/__tests__/contract-drawing.service.test.ts
// Change Log:
// - 2026-06-13: Initial creation - test coverage for contract-drawing service
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { contractDrawingService } from '../contract-drawing.service';
import apiClient from '@/lib/api/client';
// Mock apiClient
vi.mock('@/lib/api/client', () => ({
default: {
get: vi.fn(),
post: vi.fn(),
put: vi.fn(),
delete: vi.fn(),
},
}));
describe('contractDrawingService', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('ควรดึงข้อมูลรายการ contract drawings สำเร็จ', async () => {
const mockParams = { search: 'CD-01' };
const mockResponse = { data: [{ publicId: '019505a1-7c3e-7000-8000-cd1111111111', drawingNo: 'CD-001' }] };
vi.mocked(apiClient.get).mockResolvedValue({ data: mockResponse });
const result = await contractDrawingService.getAll(mockParams);
expect(result).toEqual(mockResponse);
expect(apiClient.get).toHaveBeenCalledWith('/drawings/contract', { params: mockParams });
});
it('ควรดึงรายละเอียดของ contract drawing สำเร็จ', async () => {
const uuid = '019505a1-7c3e-7000-8000-cd1111111111';
const mockResponse = { data: { publicId: uuid, drawingNo: 'CD-001' } };
vi.mocked(apiClient.get).mockResolvedValue({ data: mockResponse });
const result = await contractDrawingService.getByUuid(uuid);
expect(result).toEqual(mockResponse);
expect(apiClient.get).toHaveBeenCalledWith(`/drawings/contract/${uuid}`);
});
it('ควรสร้าง contract drawing สำเร็จ', async () => {
const mockDto = { drawingNo: 'CD-001', subject: 'Test Contract Drawing' };
const mockResponse = { data: { publicId: '019505a1-7c3e-7000-8000-cd1111111111' } };
vi.mocked(apiClient.post).mockResolvedValue({ data: mockResponse });
const result = await contractDrawingService.create(mockDto as any);
expect(result).toEqual(mockResponse);
expect(apiClient.post).toHaveBeenCalledWith('/drawings/contract', mockDto);
});
it('ควรปรับปรุงข้อมูล contract drawing สำเร็จ', async () => {
const uuid = '019505a1-7c3e-7000-8000-cd1111111111';
const mockDto = { subject: 'Updated Contract Drawing' };
const mockResponse = { data: { success: true } };
vi.mocked(apiClient.put).mockResolvedValue({ data: mockResponse });
const result = await contractDrawingService.update(uuid, mockDto as any);
expect(result).toEqual(mockResponse);
expect(apiClient.put).toHaveBeenCalledWith(`/drawings/contract/${uuid}`, mockDto);
});
it('ควรลบ contract drawing สำเร็จ', async () => {
const uuid = '019505a1-7c3e-7000-8000-cd1111111111';
const mockResponse = { data: { success: true } };
vi.mocked(apiClient.delete).mockResolvedValue({ data: mockResponse });
const result = await contractDrawingService.delete(uuid);
expect(result).toEqual(mockResponse);
expect(apiClient.delete).toHaveBeenCalledWith(`/drawings/contract/${uuid}`);
});
});
@@ -0,0 +1,230 @@
// File: frontend/lib/services/__tests__/drawing-master-data.service.test.ts
// Change Log:
// - 2026-06-13: Initial creation - test coverage for drawing-master-data service
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { drawingMasterDataService } from '../drawing-master-data.service';
import apiClient from '@/lib/api/client';
// Mock apiClient
vi.mock('@/lib/api/client', () => ({
default: {
get: vi.fn(),
post: vi.fn(),
patch: vi.fn(),
delete: vi.fn(),
},
}));
describe('drawingMasterDataService', () => {
beforeEach(() => {
vi.clearAllMocks();
});
describe('Contract Volumes', () => {
it('ควรดึงข้อมูล contract volumes สำเร็จ', async () => {
const mockResponse = { data: [{ id: 1, volumeCode: 'V1', volumeName: 'Vol 1' }] };
vi.mocked(apiClient.get).mockResolvedValue({ data: mockResponse });
const result = await drawingMasterDataService.getContractVolumes('proj-uuid-1');
expect(result).toEqual(mockResponse.data);
expect(apiClient.get).toHaveBeenCalledWith('/drawings/master-data/contract/volumes', {
params: { projectId: 'proj-uuid-1' },
});
});
it('ควรสร้าง contract volume สำเร็จ', async () => {
const mockDto = { projectId: 'proj-uuid-1', volumeCode: 'V1', volumeName: 'Vol 1', sortOrder: 1 };
const mockResponse = { data: { id: 1, volumeCode: 'V1' } };
vi.mocked(apiClient.post).mockResolvedValue({ data: mockResponse });
const result = await drawingMasterDataService.createContractVolume(mockDto);
expect(result).toEqual(mockResponse.data);
expect(apiClient.post).toHaveBeenCalledWith('/drawings/master-data/contract/volumes', mockDto);
});
it('ควรปรับปรุง contract volume สำเร็จ', async () => {
const mockDto = { volumeName: 'Updated Vol 1' };
const mockResponse = { data: { id: 1, volumeName: 'Updated Vol 1' } };
vi.mocked(apiClient.patch).mockResolvedValue({ data: mockResponse });
const result = await drawingMasterDataService.updateContractVolume(1, mockDto);
expect(result).toEqual(mockResponse.data);
expect(apiClient.patch).toHaveBeenCalledWith('/drawings/master-data/contract/volumes/1', mockDto);
});
it('ควรลบ contract volume สำเร็จ', async () => {
vi.mocked(apiClient.delete).mockResolvedValue({} as any);
await drawingMasterDataService.deleteContractVolume(1);
expect(apiClient.delete).toHaveBeenCalledWith('/drawings/master-data/contract/volumes/1');
});
});
describe('Contract Categories', () => {
it('ควรดึงข้อมูล contract categories สำเร็จ', async () => {
const mockResponse = { data: [{ id: 2, catCode: 'C2', catName: 'Cat 2' }] };
vi.mocked(apiClient.get).mockResolvedValue({ data: mockResponse });
const result = await drawingMasterDataService.getContractCategories('proj-uuid-1');
expect(result).toEqual(mockResponse.data);
expect(apiClient.get).toHaveBeenCalledWith('/drawings/master-data/contract/categories', {
params: { projectId: 'proj-uuid-1' },
});
});
it('ควรสร้าง contract category สำเร็จ', async () => {
const mockDto = { projectId: 'proj-uuid-1', catCode: 'C2', catName: 'Cat 2', sortOrder: 1 };
const mockResponse = { data: { id: 2, catCode: 'C2' } };
vi.mocked(apiClient.post).mockResolvedValue({ data: mockResponse });
const result = await drawingMasterDataService.createContractCategory(mockDto);
expect(result).toEqual(mockResponse.data);
expect(apiClient.post).toHaveBeenCalledWith('/drawings/master-data/contract/categories', mockDto);
});
it('ควรปรับปรุง contract category สำเร็จ', async () => {
const mockDto = { catName: 'Updated Cat 2' };
const mockResponse = { data: { id: 2, catName: 'Updated Cat 2' } };
vi.mocked(apiClient.patch).mockResolvedValue({ data: mockResponse });
const result = await drawingMasterDataService.updateContractCategory(2, mockDto);
expect(result).toEqual(mockResponse.data);
expect(apiClient.patch).toHaveBeenCalledWith('/drawings/master-data/contract/categories/2', mockDto);
});
it('ควรลบ contract category สำเร็จ', async () => {
vi.mocked(apiClient.delete).mockResolvedValue({} as any);
await drawingMasterDataService.deleteContractCategory(2);
expect(apiClient.delete).toHaveBeenCalledWith('/drawings/master-data/contract/categories/2');
});
});
describe('Contract Sub-categories', () => {
it('ควรดึงข้อมูล contract sub-categories สำเร็จ', async () => {
const mockResponse = [{ id: 3, subCatCode: 'SC3', subCatName: 'Sub 3' }];
vi.mocked(apiClient.get).mockResolvedValue({ data: mockResponse });
const result = await drawingMasterDataService.getContractSubCategories('proj-uuid-1');
expect(result).toEqual(mockResponse);
expect(apiClient.get).toHaveBeenCalledWith('/drawings/master-data/contract/sub-categories', {
params: { projectId: 'proj-uuid-1' },
});
});
it('ควรสร้าง contract sub-category สำเร็จ', async () => {
const mockDto = { projectId: 'proj-uuid-1', subCatCode: 'SC3', subCatName: 'Sub 3', sortOrder: 1 };
const mockResponse = { id: 3, subCatCode: 'SC3' };
vi.mocked(apiClient.post).mockResolvedValue({ data: mockResponse });
const result = await drawingMasterDataService.createContractSubCategory(mockDto);
expect(result).toEqual(mockResponse);
expect(apiClient.post).toHaveBeenCalledWith('/drawings/master-data/contract/sub-categories', mockDto);
});
it('ควรปรับปรุง contract sub-category สำเร็จ', async () => {
const mockDto = { subCatName: 'Updated Sub 3' };
const mockResponse = { id: 3, subCatName: 'Updated Sub 3' };
vi.mocked(apiClient.patch).mockResolvedValue({ data: mockResponse });
const result = await drawingMasterDataService.updateContractSubCategory(3, mockDto);
expect(result).toEqual(mockResponse);
expect(apiClient.patch).toHaveBeenCalledWith('/drawings/master-data/contract/sub-categories/3', mockDto);
});
it('ควรลบ contract sub-category สำเร็จ', async () => {
vi.mocked(apiClient.delete).mockResolvedValue({} as any);
await drawingMasterDataService.deleteContractSubCategory(3);
expect(apiClient.delete).toHaveBeenCalledWith('/drawings/master-data/contract/sub-categories/3');
});
});
describe('Contract Category Mappings', () => {
it('ควรดึงข้อมูล mappings สำเร็จ', async () => {
const mockResponse = [{ id: 10, category: {}, subCategory: {} }];
vi.mocked(apiClient.get).mockResolvedValue({ data: mockResponse });
const result = await drawingMasterDataService.getContractMappings('proj-uuid-1', 2);
expect(result).toEqual(mockResponse);
expect(apiClient.get).toHaveBeenCalledWith('/drawings/master-data/contract/mappings', {
params: { projectId: 'proj-uuid-1', categoryId: 2 },
});
});
it('ควรสร้าง mapping สำเร็จ', async () => {
const mockDto = { projectId: 'proj-uuid-1', categoryId: 2, subCategoryId: 3 };
const mockResponse = { id: 10 };
vi.mocked(apiClient.post).mockResolvedValue({ data: mockResponse });
const result = await drawingMasterDataService.createContractMapping(mockDto);
expect(result).toEqual(mockResponse);
expect(apiClient.post).toHaveBeenCalledWith('/drawings/master-data/contract/mappings', mockDto);
});
it('ควรลบ mapping สำเร็จ', async () => {
vi.mocked(apiClient.delete).mockResolvedValue({} as any);
await drawingMasterDataService.deleteContractMapping(10);
expect(apiClient.delete).toHaveBeenCalledWith('/drawings/master-data/contract/mappings/10');
});
});
describe('Shop Main Categories', () => {
it('ควรดึงข้อมูล shop main categories สำเร็จ', async () => {
const mockResponse = [{ id: 4, mainCategoryCode: 'M4', mainCategoryName: 'Main 4' }];
vi.mocked(apiClient.get).mockResolvedValue({ data: mockResponse });
const result = await drawingMasterDataService.getShopMainCategories('proj-uuid-1');
expect(result).toEqual(mockResponse);
expect(apiClient.get).toHaveBeenCalledWith('/drawings/master-data/shop/main-categories', {
params: { projectId: 'proj-uuid-1' },
});
});
it('ควรสร้าง shop main category สำเร็จ', async () => {
const mockDto = { projectId: 'proj-uuid-1', mainCategoryCode: 'M4', mainCategoryName: 'Main 4', sortOrder: 1 };
const mockResponse = { id: 4, mainCategoryCode: 'M4' };
vi.mocked(apiClient.post).mockResolvedValue({ data: mockResponse });
const result = await drawingMasterDataService.createShopMainCategory(mockDto);
expect(result).toEqual(mockResponse);
expect(apiClient.post).toHaveBeenCalledWith('/drawings/master-data/shop/main-categories', mockDto);
});
it('ควรปรับปรุง shop main category สำเร็จ', async () => {
const mockDto = { mainCategoryName: 'Updated Main 4' };
const mockResponse = { id: 4, mainCategoryName: 'Updated Main 4' };
vi.mocked(apiClient.patch).mockResolvedValue({ data: mockResponse });
const result = await drawingMasterDataService.updateShopMainCategory(4, mockDto);
expect(result).toEqual(mockResponse);
expect(apiClient.patch).toHaveBeenCalledWith('/drawings/master-data/shop/main-categories/4', mockDto);
});
it('ควรลบ shop main category สำเร็จ', async () => {
vi.mocked(apiClient.delete).mockResolvedValue({} as any);
await drawingMasterDataService.deleteShopMainCategory(4);
expect(apiClient.delete).toHaveBeenCalledWith('/drawings/master-data/shop/main-categories/4');
});
});
describe('Shop Sub-categories', () => {
it('ควรดึงข้อมูล shop sub-categories สำเร็จ', async () => {
const mockResponse = [{ id: 5, subCategoryCode: 'S5', subCategoryName: 'Sub 5' }];
vi.mocked(apiClient.get).mockResolvedValue({ data: mockResponse });
const result = await drawingMasterDataService.getShopSubCategories('proj-uuid-1', 4);
expect(result).toEqual(mockResponse);
expect(apiClient.get).toHaveBeenCalledWith('/drawings/master-data/shop/sub-categories', {
params: { projectId: 'proj-uuid-1', mainCategoryId: 4 },
});
});
it('ควรสร้าง shop sub-category สำเร็จ', async () => {
const mockDto = { projectId: 'proj-uuid-1', subCategoryCode: 'S5', subCategoryName: 'Sub 5', sortOrder: 1 };
const mockResponse = { id: 5, subCategoryCode: 'S5' };
vi.mocked(apiClient.post).mockResolvedValue({ data: mockResponse });
const result = await drawingMasterDataService.createShopSubCategory(mockDto);
expect(result).toEqual(mockResponse);
expect(apiClient.post).toHaveBeenCalledWith('/drawings/master-data/shop/sub-categories', mockDto);
});
it('ควรปรับปรุง shop sub-category สำเร็จ', async () => {
const mockDto = { subCategoryName: 'Updated Sub 5' };
const mockResponse = { id: 5, subCategoryName: 'Updated Sub 5' };
vi.mocked(apiClient.patch).mockResolvedValue({ data: mockResponse });
const result = await drawingMasterDataService.updateShopSubCategory(5, mockDto);
expect(result).toEqual(mockResponse);
expect(apiClient.patch).toHaveBeenCalledWith('/drawings/master-data/shop/sub-categories/5', mockDto);
});
it('ควรลบ shop sub-category สำเร็จ', async () => {
vi.mocked(apiClient.delete).mockResolvedValue({} as any);
await drawingMasterDataService.deleteShopSubCategory(5);
expect(apiClient.delete).toHaveBeenCalledWith('/drawings/master-data/shop/sub-categories/5');
});
});
});
@@ -0,0 +1,154 @@
// File: frontend/lib/services/__tests__/migration.service.test.ts
// Change Log:
// - 2026-06-13: Initial creation - test coverage for migration service
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { migrationService } from '../migration.service';
import api from '@/lib/api/client';
// Mock api client
vi.mock('@/lib/api/client', () => ({
default: {
get: vi.fn(),
post: vi.fn(),
},
}));
describe('migrationService', () => {
beforeEach(() => {
vi.clearAllMocks();
});
describe('getReviewQueue', () => {
it('ควรดึงข้อมูลรายการ Queue และแปลงข้อมูลแบบแบ่งหน้าได้อย่างถูกต้อง', async () => {
const mockParams = { page: 1, limit: 10, status: 'PENDING' as any };
const mockResponse = {
data: {
items: [{ publicId: '019505a1-7c3e-7000-8000-item111111111', status: 'PENDING' }],
total: 100,
page: 1,
limit: 10,
totalPages: 10,
},
};
vi.mocked(api.get).mockResolvedValue({ data: mockResponse });
const result = await migrationService.getReviewQueue(mockParams);
expect(result.items).toEqual(mockResponse.data.items);
expect(result.total).toBe(100);
expect(api.get).toHaveBeenCalledWith('/migration/queue', { params: mockParams });
});
it('ควรจัดการกรณีที่ API ส่งกลับ Direct Data Array ได้อย่างถูกต้อง', async () => {
const mockResponse = {
data: [{ publicId: '019505a1-7c3e-7000-8000-item111111111', status: 'PENDING' }],
};
vi.mocked(api.get).mockResolvedValue({ data: mockResponse });
const result = await migrationService.getReviewQueue({});
expect(result.items).toEqual(mockResponse.data);
expect(result.total).toBe(1);
});
it('ควรส่งกลับโครงสร้างเปล่ากรณีที่ดึงข้อมูลล้มเหลวหรือไม่ตรงโครงสร้าง', async () => {
vi.mocked(api.get).mockResolvedValue({ data: null });
const result = await migrationService.getReviewQueue({});
expect(result.items).toEqual([]);
expect(result.total).toBe(0);
});
});
describe('getQueueItem', () => {
it('ควรดึงข้อมูล Queue item เดี่ยวตาม ID สำเร็จ', async () => {
const mockResponse = {
data: { publicId: '019505a1-7c3e-7000-8000-item111111111', status: 'PENDING' },
};
vi.mocked(api.get).mockResolvedValue({ data: mockResponse });
const result = await migrationService.getQueueItem(1);
expect(result).toEqual(mockResponse.data);
expect(api.get).toHaveBeenCalledWith('/migration/queue/1');
});
});
describe('getErrors', () => {
it('ควรดึงข้อมูลรายการ Error Log สำเร็จ', async () => {
const mockParams = { page: 1, limit: 20 };
const mockResponse = {
data: {
items: [{ errorCode: 'ERR_001', errorMessage: 'Invalid UUID' }],
total: 5,
},
};
vi.mocked(api.get).mockResolvedValue({ data: mockResponse });
const result = await migrationService.getErrors(mockParams);
expect(result.items).toEqual(mockResponse.data.items);
expect(api.get).toHaveBeenCalledWith('/migration/errors', { params: mockParams });
});
});
describe('approveQueueItem', () => {
it('ควรอนุมัติรายการคิวสำเร็จพร้อมส่ง Idempotency-Key', async () => {
const mockPayload = { remarks: 'Approve' };
const mockResponse = { data: { success: true } };
vi.mocked(api.post).mockResolvedValue({ data: mockResponse });
const result = await migrationService.approveQueueItem(1, mockPayload, 'idemp-key-123');
expect(result).toEqual(mockResponse.data);
expect(api.post).toHaveBeenCalledWith('/migration/queue/1/approve', mockPayload, {
headers: { 'idempotency-key': 'idemp-key-123' },
});
});
});
describe('rejectQueueItem', () => {
it('ควรปฏิเสธรายการคิวสำเร็จ', async () => {
const mockResponse = { data: { success: true } };
vi.mocked(api.post).mockResolvedValue({ data: mockResponse });
const result = await migrationService.rejectQueueItem(1);
expect(result).toEqual(mockResponse.data);
expect(api.post).toHaveBeenCalledWith('/migration/queue/1/reject');
});
});
describe('commitBatch', () => {
it('ควรบันทึก commit batch สำเร็จพร้อมส่ง Idempotency-Key', async () => {
const mockPayload = { batchId: 10, items: [] };
const mockResponse = { data: { success: true } };
vi.mocked(api.post).mockResolvedValue({ data: mockResponse });
const result = await migrationService.commitBatch(mockPayload as any, 'idemp-key-456');
expect(result).toEqual(mockResponse.data);
expect(api.post).toHaveBeenCalledWith('/migration/commit_batch', mockPayload, {
headers: { 'idempotency-key': 'idemp-key-456' },
});
});
});
describe('getStagingFileUrl', () => {
it('ควรสร้าง URL สำหรับ staging file อย่างถูกต้อง', () => {
const filePath = '/uploads/staging/drawing.dwg';
const result = migrationService.getStagingFileUrl(filePath);
expect(result).toBe('/api/migration/staging-file?path=%2Fuploads%2Fstaging%2Fdrawing.dwg');
});
});
});
@@ -0,0 +1,91 @@
// File: frontend/lib/services/__tests__/organization.service.test.ts
// Change Log:
// - 2026-06-13: Initial creation - test coverage for organization service
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { organizationService } from '../organization.service';
import apiClient from '@/lib/api/client';
// Mock apiClient
vi.mock('@/lib/api/client', () => ({
default: {
get: vi.fn(),
post: vi.fn(),
patch: vi.fn(),
delete: vi.fn(),
},
}));
describe('organizationService', () => {
beforeEach(() => {
vi.clearAllMocks();
});
describe('getAll', () => {
it('ควรดึงข้อมูลรายการองค์กรทั้งหมดสำเร็จ (เมื่อ API ส่งกลับแบบ direct data)', async () => {
const mockParams = { projectId: '019505a1-7c3e-7000-8000-proj11111111' };
const mockResponse = [{ publicId: '019505a1-7c3e-7000-8000-org111111111', organizationName: 'Org A' }];
vi.mocked(apiClient.get).mockResolvedValue({ data: mockResponse });
const result = await organizationService.getAll(mockParams as any);
expect(result).toEqual(mockResponse);
expect(apiClient.get).toHaveBeenCalledWith('/organizations', { params: mockParams });
});
it('ควรดึงข้อมูลรายการองค์กรทั้งหมดสำเร็จ (เมื่อ API ส่งกลับแบบ wrapped ใน data.data)', async () => {
const mockResponse = {
data: {
data: [{ publicId: '019505a1-7c3e-7000-8000-org111111111', organizationName: 'Org A' }],
},
};
vi.mocked(apiClient.get).mockResolvedValue({ data: mockResponse.data });
const result = await organizationService.getAll();
expect(result).toEqual(mockResponse.data.data);
expect(apiClient.get).toHaveBeenCalledWith('/organizations', { params: undefined });
});
});
describe('getByUuid', () => {
it('ควรดึงข้อมูลองค์กรเดี่ยวตาม UUID สำเร็จ', async () => {
const uuid = '019505a1-7c3e-7000-8000-org111111111';
const mockResponse = { data: { publicId: uuid, organizationName: 'Org A' } };
vi.mocked(apiClient.get).mockResolvedValue({ data: mockResponse });
const result = await organizationService.getByUuid(uuid);
expect(result).toEqual(mockResponse);
expect(apiClient.get).toHaveBeenCalledWith(`/organizations/${uuid}`);
});
});
describe('create', () => {
it('ควรสร้างองค์กรใหม่สำเร็จ', async () => {
const mockDto = { organizationName: 'New Org', organizationCode: 'NEW' };
const mockResponse = { data: { publicId: '019505a1-7c3e-7000-8000-org222222222' } };
vi.mocked(apiClient.post).mockResolvedValue({ data: mockResponse });
const result = await organizationService.create(mockDto as any);
expect(result).toEqual(mockResponse);
expect(apiClient.post).toHaveBeenCalledWith('/organizations', mockDto);
});
});
describe('update', () => {
it('ควรปรับปรุงข้อมูลองค์กรสำเร็จ', async () => {
const uuid = '019505a1-7c3e-7000-8000-org111111111';
const mockDto = { organizationName: 'Updated Org' };
const mockResponse = { data: { success: true } };
vi.mocked(apiClient.patch).mockResolvedValue({ data: mockResponse });
const result = await organizationService.update(uuid, mockDto as any);
expect(result).toEqual(mockResponse);
expect(apiClient.patch).toHaveBeenCalledWith(`/organizations/${uuid}`, mockDto);
});
});
describe('delete', () => {
it('ควรลบองค์กรสำเร็จ', async () => {
const uuid = '019505a1-7c3e-7000-8000-org111111111';
const mockResponse = { data: { success: true } };
vi.mocked(apiClient.delete).mockResolvedValue({ data: mockResponse });
const result = await organizationService.delete(uuid);
expect(result).toEqual(mockResponse);
expect(apiClient.delete).toHaveBeenCalledWith(`/organizations/${uuid}`);
});
});
});
@@ -0,0 +1,58 @@
// File: frontend/lib/services/__tests__/shop-drawing.service.test.ts
// Change Log:
// - 2026-06-13: Initial creation - test coverage for shop-drawing service
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { shopDrawingService } from '../shop-drawing.service';
import apiClient from '@/lib/api/client';
// Mock apiClient
vi.mock('@/lib/api/client', () => ({
default: {
get: vi.fn(),
post: vi.fn(),
},
}));
describe('shopDrawingService', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('ควรดึงข้อมูลรายการ shop drawings สำเร็จ', async () => {
const mockParams = { search: 'SD-01' };
const mockResponse = { data: [{ publicId: '019505a1-7c3e-7000-8000-sd1111111111', drawingNo: 'SD-001' }] };
vi.mocked(apiClient.get).mockResolvedValue({ data: mockResponse });
const result = await shopDrawingService.getAll(mockParams);
expect(result).toEqual(mockResponse);
expect(apiClient.get).toHaveBeenCalledWith('/drawings/shop', { params: mockParams });
});
it('ควรดึงรายละเอียดของ shop drawing สำเร็จ', async () => {
const uuid = '019505a1-7c3e-7000-8000-sd1111111111';
const mockResponse = { data: { publicId: uuid, drawingNo: 'SD-001' } };
vi.mocked(apiClient.get).mockResolvedValue({ data: mockResponse });
const result = await shopDrawingService.getByUuid(uuid);
expect(result).toEqual(mockResponse);
expect(apiClient.get).toHaveBeenCalledWith(`/drawings/shop/${uuid}`);
});
it('ควรสร้าง shop drawing สำเร็จ', async () => {
const mockDto = { drawingNo: 'SD-001', subject: 'Test Shop Drawing' };
const mockResponse = { data: { publicId: '019505a1-7c3e-7000-8000-sd1111111111' } };
vi.mocked(apiClient.post).mockResolvedValue({ data: mockResponse });
const result = await shopDrawingService.create(mockDto as any);
expect(result).toEqual(mockResponse);
expect(apiClient.post).toHaveBeenCalledWith('/drawings/shop', mockDto);
});
it('ควรสร้าง revision ใหม่ของ shop drawing สำเร็จ', async () => {
const uuid = '019505a1-7c3e-7000-8000-sd1111111111';
const mockDto = { revisionNo: 'A', comment: 'New Revision' };
const mockResponse = { data: { success: true } };
vi.mocked(apiClient.post).mockResolvedValue({ data: mockResponse });
const result = await shopDrawingService.createRevision(uuid, mockDto as any);
expect(result).toEqual(mockResponse);
expect(apiClient.post).toHaveBeenCalledWith(`/drawings/shop/${uuid}/revisions`, mockDto);
});
});
@@ -1,3 +1,7 @@
// File: frontend/lib/services/migration.service.ts
// Change Log:
// - 2026-06-13: Add support for direct array response in normalizePaginatedResponse and add file header
import api from '../api/client'; import api from '../api/client';
import { import {
MigrationReviewQueueItem, MigrationReviewQueueItem,
@@ -38,6 +42,16 @@ const normalizePaginatedResponse = <T>(value: unknown): PaginatedResponse<T> =>
}; };
} }
if (Array.isArray(extracted)) {
return {
items: extracted as T[],
total: extracted.length,
page: 1,
limit: extracted.length,
totalPages: 1,
};
}
const response = extracted as Partial<PaginatedResponse<T>> & { data?: unknown }; const response = extracted as Partial<PaginatedResponse<T>> & { data?: unknown };
if (Array.isArray(response.items)) { if (Array.isArray(response.items)) {