155 lines
5.6 KiB
TypeScript
155 lines
5.6 KiB
TypeScript
// 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');
|
|
});
|
|
});
|
|
});
|