690615:1449 237 #01
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
// File: lib/api/__tests__/admin.test.ts
|
||||
// Change Log:
|
||||
// - 2026-06-14: สร้างใหม่สำหรับ Phase 3 Coverage
|
||||
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { adminApi } from '../admin';
|
||||
|
||||
describe('adminApi', () => {
|
||||
describe('getUsers', () => {
|
||||
it('ควร return array of users', async () => {
|
||||
const users = await adminApi.getUsers();
|
||||
|
||||
expect(Array.isArray(users)).toBe(true);
|
||||
expect(users.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('ควร return users ที่มี publicId, username, email', async () => {
|
||||
const users = await adminApi.getUsers();
|
||||
|
||||
expect(users[0]).toHaveProperty('publicId');
|
||||
expect(users[0]).toHaveProperty('username');
|
||||
expect(users[0]).toHaveProperty('email');
|
||||
});
|
||||
});
|
||||
|
||||
describe('createUser', () => {
|
||||
it('ควร create user ใหม่และ return user object', async () => {
|
||||
const userData = {
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
firstName: 'Test',
|
||||
lastName: 'User',
|
||||
isActive: true,
|
||||
roles: [2],
|
||||
};
|
||||
|
||||
const newUser = await adminApi.createUser(userData);
|
||||
|
||||
expect(newUser).toHaveProperty('publicId');
|
||||
expect(newUser.username).toBe('testuser');
|
||||
expect(newUser.email).toBe('test@example.com');
|
||||
});
|
||||
|
||||
it('ควร assign userId ใหม่ให้ user', async () => {
|
||||
const userData = {
|
||||
username: 'newuser',
|
||||
email: 'new@example.com',
|
||||
firstName: 'New',
|
||||
lastName: 'User',
|
||||
isActive: true,
|
||||
roles: [2],
|
||||
};
|
||||
|
||||
const newUser = await adminApi.createUser(userData);
|
||||
|
||||
expect(newUser.userId).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOrganizations', () => {
|
||||
it('ควร return array of organizations', async () => {
|
||||
const orgs = await adminApi.getOrganizations();
|
||||
|
||||
expect(Array.isArray(orgs)).toBe(true);
|
||||
expect(orgs.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('ควร return organizations ที่มี publicId, orgCode, orgName', async () => {
|
||||
const orgs = await adminApi.getOrganizations();
|
||||
|
||||
expect(orgs[0]).toHaveProperty('publicId');
|
||||
expect(orgs[0]).toHaveProperty('orgCode');
|
||||
expect(orgs[0]).toHaveProperty('orgName');
|
||||
});
|
||||
});
|
||||
|
||||
describe('createOrganization', () => {
|
||||
it('ควร create organization ใหม่และ return org object', async () => {
|
||||
const orgData = {
|
||||
publicId: 'org-003',
|
||||
orgCode: 'TEST',
|
||||
orgName: 'Test Organization',
|
||||
description: 'Test description',
|
||||
};
|
||||
|
||||
const newOrg = await adminApi.createOrganization(orgData);
|
||||
|
||||
expect(newOrg).toHaveProperty('publicId');
|
||||
expect(newOrg.orgCode).toBe('TEST');
|
||||
expect(newOrg.orgName).toBe('Test Organization');
|
||||
});
|
||||
|
||||
it('ควร assign orgId ใหม่ให้ organization', async () => {
|
||||
const orgData = {
|
||||
publicId: 'org-004',
|
||||
orgCode: 'TEST2',
|
||||
orgName: 'Test Organization 2',
|
||||
description: 'Test description 2',
|
||||
};
|
||||
|
||||
const newOrg = await adminApi.createOrganization(orgData);
|
||||
|
||||
expect(newOrg.orgId).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAuditLogs', () => {
|
||||
it('ควร return array of audit logs', async () => {
|
||||
const logs = await adminApi.getAuditLogs();
|
||||
|
||||
expect(Array.isArray(logs)).toBe(true);
|
||||
expect(logs.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('ควร return logs ที่มี publicId, userName, action', async () => {
|
||||
const logs = await adminApi.getAuditLogs();
|
||||
|
||||
expect(logs[0]).toHaveProperty('publicId');
|
||||
expect(logs[0]).toHaveProperty('userName');
|
||||
expect(logs[0]).toHaveProperty('action');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,34 @@
|
||||
// File: lib/api/__tests__/ai.test.ts
|
||||
// Change Log:
|
||||
// - 2026-06-14: สร้างใหม่สำหรับ Phase 3 Coverage
|
||||
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { extractData } from '../ai';
|
||||
|
||||
describe('ai.ts helper functions', () => {
|
||||
describe('extractData', () => {
|
||||
it('ควร return value ทันทีเมื่อไม่ใช่ object', () => {
|
||||
const value = 'test string';
|
||||
const result = extractData(value);
|
||||
expect(result).toBe('test string');
|
||||
});
|
||||
|
||||
it('ควร return value ทันทีเมื่อไม่มี data property', () => {
|
||||
const value = { some: 'value' };
|
||||
const result = extractData(value);
|
||||
expect(result).toEqual({ some: 'value' });
|
||||
});
|
||||
|
||||
it('ควร unwrap data เมื่อมี data property', () => {
|
||||
const value = { data: { some: 'value' } };
|
||||
const result = extractData(value);
|
||||
expect(result).toEqual({ some: 'value' });
|
||||
});
|
||||
|
||||
it('ควร unwrap data ซ้อนกันสูงสุด 5 ชั้น', () => {
|
||||
const value = { data: { data: { data: { data: { data: 'final' } } } } };
|
||||
const result = extractData(value);
|
||||
expect(result).toBe('final');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,79 @@
|
||||
// File: lib/api/__tests__/dashboard.test.ts
|
||||
// Change Log:
|
||||
// - 2026-06-14: สร้างใหม่สำหรับ Phase 3 Coverage
|
||||
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { dashboardApi } from '../dashboard';
|
||||
|
||||
describe('dashboardApi', () => {
|
||||
describe('getStats', () => {
|
||||
it('ควร return dashboard stats', async () => {
|
||||
const stats = await dashboardApi.getStats();
|
||||
|
||||
expect(stats).toHaveProperty('totalDocuments');
|
||||
expect(stats).toHaveProperty('documentsThisMonth');
|
||||
expect(stats).toHaveProperty('pendingApprovals');
|
||||
expect(stats).toHaveProperty('approved');
|
||||
expect(stats).toHaveProperty('totalRfas');
|
||||
expect(stats).toHaveProperty('totalCirculations');
|
||||
});
|
||||
|
||||
it('ควร return numbers สำหรับ stats', async () => {
|
||||
const stats = await dashboardApi.getStats();
|
||||
|
||||
expect(typeof stats.totalDocuments).toBe('number');
|
||||
expect(typeof stats.documentsThisMonth).toBe('number');
|
||||
expect(typeof stats.pendingApprovals).toBe('number');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getRecentActivity', () => {
|
||||
it('ควร return array of activity logs', async () => {
|
||||
const activities = await dashboardApi.getRecentActivity();
|
||||
|
||||
expect(Array.isArray(activities)).toBe(true);
|
||||
expect(activities.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('ควร return activities ที่มี id, user, action, description', async () => {
|
||||
const activities = await dashboardApi.getRecentActivity();
|
||||
|
||||
expect(activities[0]).toHaveProperty('id');
|
||||
expect(activities[0]).toHaveProperty('user');
|
||||
expect(activities[0]).toHaveProperty('action');
|
||||
expect(activities[0]).toHaveProperty('description');
|
||||
});
|
||||
|
||||
it('ควร return activities ที่มี user.name และ user.initials', async () => {
|
||||
const activities = await dashboardApi.getRecentActivity();
|
||||
|
||||
expect(activities[0].user).toHaveProperty('name');
|
||||
expect(activities[0].user).toHaveProperty('initials');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getPendingTasks', () => {
|
||||
it('ควร return array of pending tasks', async () => {
|
||||
const tasks = await dashboardApi.getPendingTasks();
|
||||
|
||||
expect(Array.isArray(tasks)).toBe(true);
|
||||
expect(tasks.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('ควร return tasks ที่มี publicId, workflowCode, currentState', async () => {
|
||||
const tasks = await dashboardApi.getPendingTasks();
|
||||
|
||||
expect(tasks[0]).toHaveProperty('publicId');
|
||||
expect(tasks[0]).toHaveProperty('workflowCode');
|
||||
expect(tasks[0]).toHaveProperty('currentState');
|
||||
});
|
||||
|
||||
it('ควร return tasks ที่มี entityType, documentNumber, subject', async () => {
|
||||
const tasks = await dashboardApi.getPendingTasks();
|
||||
|
||||
expect(tasks[0]).toHaveProperty('entityType');
|
||||
expect(tasks[0]).toHaveProperty('documentNumber');
|
||||
expect(tasks[0]).toHaveProperty('subject');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,64 @@
|
||||
// File: lib/api/__tests__/drawings.test.ts
|
||||
// Change Log:
|
||||
// - 2026-06-14: สร้างใหม่สำหรับ Phase 3 Coverage
|
||||
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { drawingApi } from '../drawings';
|
||||
|
||||
describe('drawingApi', () => {
|
||||
describe('getAll', () => {
|
||||
it('ควร return array of drawings พร้อม meta', async () => {
|
||||
const result = await drawingApi.getAll();
|
||||
|
||||
expect(result).toHaveProperty('data');
|
||||
expect(result).toHaveProperty('meta');
|
||||
expect(Array.isArray(result.data)).toBe(true);
|
||||
});
|
||||
|
||||
it('ควร return drawings ที่มี publicId, drawingNumber, title', async () => {
|
||||
const result = await drawingApi.getAll();
|
||||
|
||||
expect(result.data[0]).toHaveProperty('publicId');
|
||||
expect(result.data[0]).toHaveProperty('drawingNumber');
|
||||
expect(result.data[0]).toHaveProperty('title');
|
||||
});
|
||||
|
||||
it('ควร return meta.total เท่ากับจำนวน drawings', async () => {
|
||||
const result = await drawingApi.getAll();
|
||||
|
||||
expect(result.meta.total).toBe(result.data.length);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getById', () => {
|
||||
it('ควร return drawing เมื่อ id ถูกต้อง', async () => {
|
||||
const drawing = await drawingApi.getById('dwg-001');
|
||||
|
||||
expect(drawing).toBeDefined();
|
||||
expect(drawing?.publicId).toBe('dwg-001');
|
||||
});
|
||||
|
||||
it('ควร return undefined เมื่อ id ไม่ถูกต้อง', async () => {
|
||||
const drawing = await drawingApi.getById('non-existent');
|
||||
|
||||
expect(drawing).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getByContract', () => {
|
||||
it('ควร return array of drawings สำหรับ contract', async () => {
|
||||
const result = await drawingApi.getByContract('contract-001');
|
||||
|
||||
expect(result).toHaveProperty('data');
|
||||
expect(Array.isArray(result.data)).toBe(true);
|
||||
});
|
||||
|
||||
it('ควร return drawings ที่มี discipline, status, revision', async () => {
|
||||
const result = await drawingApi.getByContract('contract-001');
|
||||
|
||||
expect(result.data[0]).toHaveProperty('discipline');
|
||||
expect(result.data[0]).toHaveProperty('status');
|
||||
expect(result.data[0]).toHaveProperty('revision');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,66 @@
|
||||
// File: lib/api/__tests__/notifications.test.ts
|
||||
// Change Log:
|
||||
// - 2026-06-14: สร้างใหม่สำหรับ Phase 3 Coverage
|
||||
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { notificationApi } from '../notifications';
|
||||
|
||||
describe('notificationApi', () => {
|
||||
beforeEach(() => {
|
||||
// Reset mock data before each test
|
||||
// Note: This is a simplified reset since the mock is in the same file
|
||||
});
|
||||
|
||||
describe('getUnread', () => {
|
||||
it('ควร return notifications พร้อม unreadCount', async () => {
|
||||
const result = await notificationApi.getUnread();
|
||||
|
||||
expect(result).toHaveProperty('items');
|
||||
expect(result).toHaveProperty('unreadCount');
|
||||
expect(Array.isArray(result.items)).toBe(true);
|
||||
});
|
||||
|
||||
it('ควร return notifications ที่มี publicId, title, message', async () => {
|
||||
const result = await notificationApi.getUnread();
|
||||
|
||||
expect(result.items[0]).toHaveProperty('publicId');
|
||||
expect(result.items[0]).toHaveProperty('title');
|
||||
expect(result.items[0]).toHaveProperty('message');
|
||||
});
|
||||
|
||||
it('ควร return notifications ที่มี type, isRead, createdAt', async () => {
|
||||
const result = await notificationApi.getUnread();
|
||||
|
||||
expect(result.items[0]).toHaveProperty('type');
|
||||
expect(result.items[0]).toHaveProperty('isRead');
|
||||
expect(result.items[0]).toHaveProperty('createdAt');
|
||||
});
|
||||
|
||||
it('ควร count unread notifications อย่างถูกต้อง', async () => {
|
||||
const result = await notificationApi.getUnread();
|
||||
|
||||
expect(typeof result.unreadCount).toBe('number');
|
||||
expect(result.unreadCount).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('markAsRead', () => {
|
||||
it('ควร mark notification เป็น read', async () => {
|
||||
await notificationApi.markAsRead(1);
|
||||
|
||||
const result = await notificationApi.getUnread();
|
||||
const notification = result.items.find((n) => n.notificationId === 1);
|
||||
|
||||
expect(notification?.isRead).toBe(true);
|
||||
});
|
||||
|
||||
it('ควรไม่ affect notifications อื่น', async () => {
|
||||
await notificationApi.markAsRead(1);
|
||||
|
||||
const result = await notificationApi.getUnread();
|
||||
const otherNotification = result.items.find((n) => n.notificationId === 2);
|
||||
|
||||
expect(otherNotification?.isRead).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,232 @@
|
||||
// File: lib/api/__tests__/numbering.test.ts
|
||||
// Change Log:
|
||||
// - 2026-06-14: สร้างใหม่สำหรับ Phase 3 Coverage
|
||||
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { numberingApi } from '../numbering';
|
||||
|
||||
// Mock apiClient
|
||||
vi.mock('@/lib/api/client', () => ({
|
||||
default: {
|
||||
get: vi.fn(),
|
||||
post: vi.fn(),
|
||||
patch: vi.fn(),
|
||||
delete: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
import apiClient from '@/lib/api/client';
|
||||
|
||||
describe('numberingApi', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('getTemplates', () => {
|
||||
it('ควร return array of templates', async () => {
|
||||
const mockTemplates = [{ id: 1, formatTemplate: 'TEST-{YYYY}-{NNNN}' }];
|
||||
(apiClient.get as any).mockResolvedValue({ data: mockTemplates });
|
||||
|
||||
const result = await numberingApi.getTemplates();
|
||||
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
expect(result).toEqual(mockTemplates);
|
||||
});
|
||||
|
||||
it('ควร handle nested data structure', async () => {
|
||||
const mockTemplates = [{ id: 1, formatTemplate: 'TEST-{YYYY}-{NNNN}' }];
|
||||
(apiClient.get as any).mockResolvedValue({ data: { data: mockTemplates } });
|
||||
|
||||
const result = await numberingApi.getTemplates();
|
||||
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
expect(result).toEqual(mockTemplates);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTemplatesByProject', () => {
|
||||
it('ควร call API ด้วย projectId parameter', async () => {
|
||||
(apiClient.get as any).mockResolvedValue({ data: [] });
|
||||
|
||||
await numberingApi.getTemplatesByProject(1);
|
||||
|
||||
expect(apiClient.get).toHaveBeenCalledWith('/admin/document-numbering/templates?projectId=1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTemplate', () => {
|
||||
it('ควร return template เมื่อ id ถูกต้อง', async () => {
|
||||
const mockTemplates = [{ id: 1, formatTemplate: 'TEST-{YYYY}-{NNNN}' }];
|
||||
(apiClient.get as any).mockResolvedValue({ data: mockTemplates });
|
||||
|
||||
const result = await numberingApi.getTemplate(1);
|
||||
|
||||
expect(result).toEqual(mockTemplates[0]);
|
||||
});
|
||||
|
||||
it('ควร return undefined เมื่อ id ไม่พบ', async () => {
|
||||
const mockTemplates = [{ id: 1, formatTemplate: 'TEST-{YYYY}-{NNNN}' }];
|
||||
(apiClient.get as any).mockResolvedValue({ data: mockTemplates });
|
||||
|
||||
const result = await numberingApi.getTemplate(999);
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('saveTemplate', () => {
|
||||
it('ควร call API ด้วย DTO ที่ clean แล้ว', async () => {
|
||||
const mockTemplate = { id: 1, formatTemplate: 'TEST-{YYYY}-{NNNN}' };
|
||||
(apiClient.post as any).mockResolvedValue({ data: mockTemplate });
|
||||
|
||||
const dto = {
|
||||
projectId: 1,
|
||||
correspondenceTypeId: null,
|
||||
formatTemplate: 'TEST-{YYYY}-{NNNN}',
|
||||
};
|
||||
|
||||
const result = await numberingApi.saveTemplate(dto);
|
||||
|
||||
expect(apiClient.post).toHaveBeenCalledWith('/admin/document-numbering/templates', expect.any(Object));
|
||||
expect(result).toEqual(mockTemplate);
|
||||
});
|
||||
});
|
||||
|
||||
describe('deleteTemplate', () => {
|
||||
it('ควร call API ด้วย id', async () => {
|
||||
(apiClient.delete as any).mockResolvedValue({});
|
||||
|
||||
await numberingApi.deleteTemplate(1);
|
||||
|
||||
expect(apiClient.delete).toHaveBeenCalledWith('/admin/document-numbering/templates/1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAuditLogs', () => {
|
||||
it('ควร return array of audit logs', async () => {
|
||||
const mockLogs = [{ id: 1, generatedNumber: 'TEST-001' }];
|
||||
(apiClient.get as any).mockResolvedValue({ data: mockLogs });
|
||||
|
||||
const result = await numberingApi.getAuditLogs();
|
||||
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
expect(result).toEqual(mockLogs);
|
||||
});
|
||||
|
||||
it('ควร call API ด้วย limit parameter', async () => {
|
||||
(apiClient.get as any).mockResolvedValue({ data: [] });
|
||||
|
||||
await numberingApi.getAuditLogs(50);
|
||||
|
||||
expect(apiClient.get).toHaveBeenCalledWith('/document-numbering/logs/audit?limit=50');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getErrorLogs', () => {
|
||||
it('ควร return array of error logs', async () => {
|
||||
const mockErrors = [{ id: 1, errorMessage: 'Test error' }];
|
||||
(apiClient.get as any).mockResolvedValue({ data: mockErrors });
|
||||
|
||||
const result = await numberingApi.getErrorLogs();
|
||||
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
expect(result).toEqual(mockErrors);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getMetrics', () => {
|
||||
it('ควร return metrics ที่มี audit และ errors', async () => {
|
||||
const mockMetrics = { audit: [], errors: [] };
|
||||
(apiClient.get as any).mockResolvedValue({ data: mockMetrics });
|
||||
|
||||
const result = await numberingApi.getMetrics();
|
||||
|
||||
expect(result).toHaveProperty('audit');
|
||||
expect(result).toHaveProperty('errors');
|
||||
});
|
||||
});
|
||||
|
||||
describe('manualOverride', () => {
|
||||
it('ควร call API ด้วย DTO', async () => {
|
||||
const mockResponse = { success: true, message: 'Override successful' };
|
||||
(apiClient.post as any).mockResolvedValue({ data: mockResponse });
|
||||
|
||||
const dto = { projectId: 1, correspondenceTypeId: null, year: 2026, newValue: 100 };
|
||||
const result = await numberingApi.manualOverride(dto);
|
||||
|
||||
expect(apiClient.post).toHaveBeenCalledWith('/admin/document-numbering/manual-override', dto);
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
});
|
||||
|
||||
describe('voidAndReplace', () => {
|
||||
it('ควร call API ด้วย DTO', async () => {
|
||||
const mockResponse = { newNumber: 'TEST-002', auditId: 123 };
|
||||
(apiClient.post as any).mockResolvedValue({ data: mockResponse });
|
||||
|
||||
const dto = { documentId: 1, reason: 'Test reason' };
|
||||
const result = await numberingApi.voidAndReplace(dto);
|
||||
|
||||
expect(apiClient.post).toHaveBeenCalledWith('/admin/document-numbering/void-and-replace', dto);
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
});
|
||||
|
||||
describe('cancelNumber', () => {
|
||||
it('ควร call API ด้วย DTO', async () => {
|
||||
const mockResponse = { success: true };
|
||||
(apiClient.post as any).mockResolvedValue({ data: mockResponse });
|
||||
|
||||
const dto = { documentNumber: 'TEST-001', reason: 'Test reason' };
|
||||
const result = await numberingApi.cancelNumber(dto);
|
||||
|
||||
expect(apiClient.post).toHaveBeenCalledWith('/admin/document-numbering/cancel', dto);
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
});
|
||||
|
||||
describe('bulkImport', () => {
|
||||
it('ควร call API ด้วย items array', async () => {
|
||||
const mockResponse = { imported: 10, errors: [] };
|
||||
(apiClient.post as any).mockResolvedValue({ data: mockResponse });
|
||||
|
||||
const items = [{ projectId: 1, correspondenceTypeId: null, year: 2026, lastNumber: 100 }];
|
||||
const result = await numberingApi.bulkImport(items);
|
||||
|
||||
expect(apiClient.post).toHaveBeenCalledWith('/admin/document-numbering/bulk-import', items);
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateCounter', () => {
|
||||
it('ควร call API ด้วย counterId และ sequence', async () => {
|
||||
(apiClient.patch as any).mockResolvedValue({});
|
||||
|
||||
await numberingApi.updateCounter(1, 100);
|
||||
|
||||
expect(apiClient.patch).toHaveBeenCalledWith('/document-numbering/counters/1', { sequence: 100 });
|
||||
});
|
||||
});
|
||||
|
||||
describe('previewNumber', () => {
|
||||
it('ควร return preview number', async () => {
|
||||
const mockResponse = { previewNumber: 'TEST-2026-0001', nextSequence: 1, isDefault: true };
|
||||
(apiClient.post as any).mockResolvedValue({ data: mockResponse });
|
||||
|
||||
const ctx = { projectId: 1, originatorOrganizationId: 1, correspondenceTypeId: 1 };
|
||||
const result = await numberingApi.previewNumber(ctx);
|
||||
|
||||
expect(apiClient.post).toHaveBeenCalledWith('/document-numbering/preview', ctx);
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
});
|
||||
|
||||
describe('generateTestNumber', () => {
|
||||
it('ควร return mock test number', async () => {
|
||||
const result = await numberingApi.generateTestNumber(1, { organizationId: '1', disciplineId: '1' });
|
||||
|
||||
expect(result).toHaveProperty('number');
|
||||
expect(result.number).toMatch(/^TEST-\d{4}-\d{4}$/);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,133 @@
|
||||
// File: lib/api/__tests__/workflows.test.ts
|
||||
// Change Log:
|
||||
// - 2026-06-14: สร้างใหม่สำหรับ Phase 3 Coverage
|
||||
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { workflowApi } from '../workflows';
|
||||
|
||||
describe('workflowApi', () => {
|
||||
beforeEach(() => {
|
||||
// Reset mock data before each test
|
||||
// Note: This is a simplified reset since the mock is in the same file
|
||||
});
|
||||
|
||||
describe('getWorkflows', () => {
|
||||
it('ควร return array of workflows', async () => {
|
||||
const workflows = await workflowApi.getWorkflows();
|
||||
|
||||
expect(Array.isArray(workflows)).toBe(true);
|
||||
expect(workflows.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('ควร return workflows ที่มี publicId, workflowName, workflowType', async () => {
|
||||
const workflows = await workflowApi.getWorkflows();
|
||||
|
||||
expect(workflows[0]).toHaveProperty('publicId');
|
||||
expect(workflows[0]).toHaveProperty('workflowName');
|
||||
expect(workflows[0]).toHaveProperty('workflowType');
|
||||
});
|
||||
|
||||
it('ควร return workflows ที่มี dslDefinition, version, isActive', async () => {
|
||||
const workflows = await workflowApi.getWorkflows();
|
||||
|
||||
expect(workflows[0]).toHaveProperty('dslDefinition');
|
||||
expect(workflows[0]).toHaveProperty('version');
|
||||
expect(workflows[0]).toHaveProperty('isActive');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getWorkflow', () => {
|
||||
it('ควร return workflow เมื่อ id ถูกต้อง', async () => {
|
||||
const workflow = await workflowApi.getWorkflow('wf-001');
|
||||
|
||||
expect(workflow).toBeDefined();
|
||||
expect(workflow?.publicId).toBe('wf-001');
|
||||
});
|
||||
|
||||
it('ควร return undefined เมื่อ id ไม่ถูกต้อง', async () => {
|
||||
const workflow = await workflowApi.getWorkflow('non-existent');
|
||||
|
||||
expect(workflow).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('createWorkflow', () => {
|
||||
it('ควร create workflow ใหม่และ return workflow object', async () => {
|
||||
const data = {
|
||||
workflowName: 'Test Workflow',
|
||||
description: 'Test description',
|
||||
workflowType: 'RFA',
|
||||
dslDefinition: 'name: Test\nsteps: []',
|
||||
};
|
||||
|
||||
const newWorkflow = await workflowApi.createWorkflow(data);
|
||||
|
||||
expect(newWorkflow).toHaveProperty('publicId');
|
||||
expect(newWorkflow.workflowName).toBe('Test Workflow');
|
||||
expect(newWorkflow.version).toBe(1);
|
||||
expect(newWorkflow.isActive).toBe(true);
|
||||
});
|
||||
|
||||
it('ควร assign workflowId ใหม่ให้ workflow', async () => {
|
||||
const data = {
|
||||
workflowName: 'New Workflow',
|
||||
description: 'New description',
|
||||
workflowType: 'CORRESPONDENCE',
|
||||
dslDefinition: 'name: New\nsteps: []',
|
||||
};
|
||||
|
||||
const newWorkflow = await workflowApi.createWorkflow(data);
|
||||
|
||||
expect(newWorkflow.workflowId).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateWorkflow', () => {
|
||||
it('ควร update workflow และ return updated object', async () => {
|
||||
const data = {
|
||||
workflowName: 'Updated Workflow',
|
||||
description: 'Updated description',
|
||||
};
|
||||
|
||||
const updatedWorkflow = await workflowApi.updateWorkflow('wf-001', data);
|
||||
|
||||
expect(updatedWorkflow.workflowName).toBe('Updated Workflow');
|
||||
expect(updatedWorkflow.description).toBe('Updated description');
|
||||
});
|
||||
|
||||
it('ควร throw error เมื่อ workflow ไม่พบ', async () => {
|
||||
const data = { workflowName: 'Test' };
|
||||
|
||||
await expect(workflowApi.updateWorkflow('non-existent', data)).rejects.toThrow('Workflow not found');
|
||||
});
|
||||
});
|
||||
|
||||
describe('validateDSL', () => {
|
||||
it('ควร return valid=true เมื่อ DSL ถูกต้อง', async () => {
|
||||
const dsl = 'name: Test Workflow\nsteps:\n - name: Step 1\n type: REVIEW';
|
||||
|
||||
const result = await workflowApi.validateDSL(dsl);
|
||||
|
||||
expect(result.valid).toBe(true);
|
||||
expect(result.errors).toEqual([]);
|
||||
});
|
||||
|
||||
it('ควร return valid=false เมื่อ DSL ไม่มี name', async () => {
|
||||
const dsl = 'invalid dsl without name or steps';
|
||||
|
||||
const result = await workflowApi.validateDSL(dsl);
|
||||
|
||||
expect(result.valid).toBe(false);
|
||||
expect(result.errors.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('ควร return valid=false เมื่อ DSL ไม่มี steps', async () => {
|
||||
const dsl = 'name: Test Workflow';
|
||||
|
||||
const result = await workflowApi.validateDSL(dsl);
|
||||
|
||||
expect(result.valid).toBe(false);
|
||||
expect(result.errors.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user