test(frontend): raise overall statement coverage to 30.42% for Phase 1 MVP
This commit is contained in:
@@ -0,0 +1,286 @@
|
||||
// File: frontend/hooks/__tests__/use-master-data.test.ts
|
||||
// Change Log:
|
||||
// - 2026-06-13: Initial creation - test coverage for use-master-data hooks
|
||||
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { renderHook, waitFor, act } from '@testing-library/react';
|
||||
import { createTestQueryClient } from '@/lib/test-utils';
|
||||
import {
|
||||
useOrganizations,
|
||||
useCreateOrganization,
|
||||
useUpdateOrganization,
|
||||
useDeleteOrganization,
|
||||
useDisciplines,
|
||||
useProjects,
|
||||
useContracts,
|
||||
useCorrespondenceTypes,
|
||||
useContractDrawingCategories,
|
||||
useShopMainCategories,
|
||||
useShopSubCategories,
|
||||
masterDataKeys,
|
||||
} from '../use-master-data';
|
||||
import { masterDataService } from '@/lib/services/master-data.service';
|
||||
import { organizationService } from '@/lib/services/organization.service';
|
||||
import { projectService } from '@/lib/services/project.service';
|
||||
import { contractService } from '@/lib/services/contract.service';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
// Mock services
|
||||
vi.mock('@/lib/services/master-data.service', () => ({
|
||||
masterDataService: {
|
||||
createOrganization: vi.fn(),
|
||||
updateOrganization: vi.fn(),
|
||||
deleteOrganization: vi.fn(),
|
||||
getDisciplines: vi.fn(),
|
||||
getCorrespondenceTypes: vi.fn(),
|
||||
getContractDrawingCategories: vi.fn(),
|
||||
getShopMainCategories: vi.fn(),
|
||||
getShopSubCategories: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('@/lib/services/organization.service', () => ({
|
||||
organizationService: {
|
||||
getAll: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('@/lib/services/project.service', () => ({
|
||||
projectService: {
|
||||
getAll: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('@/lib/services/contract.service', () => ({
|
||||
contractService: {
|
||||
getAll: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('use-master-data hooks', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('masterDataKeys', () => {
|
||||
it('ควรสร้าง cache keys ที่ถูกต้อง', () => {
|
||||
expect(masterDataKeys.all).toEqual(['masterData']);
|
||||
expect(masterDataKeys.organizations()).toEqual(['masterData', 'organizations']);
|
||||
expect(masterDataKeys.correspondenceTypes()).toEqual(['masterData', 'correspondenceTypes']);
|
||||
expect(masterDataKeys.disciplines('uuid-1')).toEqual(['masterData', 'disciplines', 'uuid-1']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('useOrganizations', () => {
|
||||
it('ควรดึงข้อมูลองค์กรสำเร็จ', async () => {
|
||||
const mockData = [{ publicId: 'uuid-org-1', organizationName: 'Org A' }];
|
||||
vi.mocked(organizationService.getAll).mockResolvedValue(mockData);
|
||||
const { wrapper } = createTestQueryClient();
|
||||
const { result } = renderHook(() => useOrganizations({ isActive: true }), { wrapper });
|
||||
await waitFor(() => {
|
||||
expect(result.current.isSuccess).toBe(true);
|
||||
});
|
||||
expect(result.current.data).toEqual(mockData);
|
||||
expect(organizationService.getAll).toHaveBeenCalledWith({ isActive: true });
|
||||
});
|
||||
});
|
||||
|
||||
describe('useCreateOrganization', () => {
|
||||
it('ควรสร้างองค์กรสำเร็จและแสดง toast success', async () => {
|
||||
const mockResponse = { publicId: 'uuid-org-1', organizationName: 'New Org' };
|
||||
vi.mocked(masterDataService.createOrganization).mockResolvedValue(mockResponse);
|
||||
const { wrapper } = createTestQueryClient();
|
||||
const { result } = renderHook(() => useCreateOrganization(), { wrapper });
|
||||
await act(async () => {
|
||||
await result.current.mutateAsync({ organizationName: 'New Org', organizationCode: 'ORG' });
|
||||
});
|
||||
expect(masterDataService.createOrganization).toHaveBeenCalledWith({ organizationName: 'New Org', organizationCode: 'ORG' });
|
||||
expect(toast.success).toHaveBeenCalledWith('Organization created successfully');
|
||||
});
|
||||
|
||||
it('ควรแสดง toast error เมื่อสร้างไม่สำเร็จ', async () => {
|
||||
const mockError = {
|
||||
message: 'Error',
|
||||
response: { data: { message: 'Duplicate code' } },
|
||||
};
|
||||
vi.mocked(masterDataService.createOrganization).mockRejectedValue(mockError);
|
||||
const { wrapper } = createTestQueryClient();
|
||||
const { result } = renderHook(() => useCreateOrganization(), { wrapper });
|
||||
await act(async () => {
|
||||
try {
|
||||
await result.current.mutateAsync({ organizationName: 'New Org', organizationCode: 'ORG' });
|
||||
} catch {
|
||||
// คาดหวังว่าจะเกิด error
|
||||
}
|
||||
});
|
||||
expect(toast.error).toHaveBeenCalledWith('Failed to create organization', {
|
||||
description: 'Duplicate code',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('useUpdateOrganization', () => {
|
||||
it('ควรแก้ไของค์กรสำเร็จและแสดง toast success', async () => {
|
||||
const mockResponse = { publicId: 'uuid-org-1', organizationName: 'Updated Org' };
|
||||
vi.mocked(masterDataService.updateOrganization).mockResolvedValue(mockResponse);
|
||||
const { wrapper } = createTestQueryClient();
|
||||
const { result } = renderHook(() => useUpdateOrganization(), { wrapper });
|
||||
await act(async () => {
|
||||
await result.current.mutateAsync({ uuid: 'uuid-org-1', data: { organizationName: 'Updated Org' } });
|
||||
});
|
||||
expect(masterDataService.updateOrganization).toHaveBeenCalledWith('uuid-org-1', { organizationName: 'Updated Org' });
|
||||
expect(toast.success).toHaveBeenCalledWith('Organization updated successfully');
|
||||
});
|
||||
|
||||
it('ควรแสดง toast error เมื่อแก้ไขไม่สำเร็จ', async () => {
|
||||
const mockError = {
|
||||
message: 'Error',
|
||||
response: { data: { message: 'Not found' } },
|
||||
};
|
||||
vi.mocked(masterDataService.updateOrganization).mockRejectedValue(mockError);
|
||||
const { wrapper } = createTestQueryClient();
|
||||
const { result } = renderHook(() => useUpdateOrganization(), { wrapper });
|
||||
await act(async () => {
|
||||
try {
|
||||
await result.current.mutateAsync({ uuid: 'uuid-org-1', data: { organizationName: 'Updated Org' } });
|
||||
} catch {
|
||||
// คาดหวังว่าจะเกิด error
|
||||
}
|
||||
});
|
||||
expect(toast.error).toHaveBeenCalledWith('Failed to update organization', {
|
||||
description: 'Not found',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('useDeleteOrganization', () => {
|
||||
it('ควรลบองค์กรสำเร็จและแสดง toast success', async () => {
|
||||
vi.mocked(masterDataService.deleteOrganization).mockResolvedValue({});
|
||||
const { wrapper } = createTestQueryClient();
|
||||
const { result } = renderHook(() => useDeleteOrganization(), { wrapper });
|
||||
await act(async () => {
|
||||
await result.current.mutateAsync('uuid-org-1');
|
||||
});
|
||||
expect(masterDataService.deleteOrganization).toHaveBeenCalledWith('uuid-org-1');
|
||||
expect(toast.success).toHaveBeenCalledWith('Organization deleted successfully');
|
||||
});
|
||||
|
||||
it('ควรแสดง toast error เมื่อลบไม่สำเร็จ', async () => {
|
||||
const mockError = {
|
||||
message: 'Error',
|
||||
response: { data: { message: 'Constraint violation' } },
|
||||
};
|
||||
vi.mocked(masterDataService.deleteOrganization).mockRejectedValue(mockError);
|
||||
const { wrapper } = createTestQueryClient();
|
||||
const { result } = renderHook(() => useDeleteOrganization(), { wrapper });
|
||||
await act(async () => {
|
||||
try {
|
||||
await result.current.mutateAsync('uuid-org-1');
|
||||
} catch {
|
||||
// คาดหวังว่าจะเกิด error
|
||||
}
|
||||
});
|
||||
expect(toast.error).toHaveBeenCalledWith('Failed to delete organization', {
|
||||
description: 'Constraint violation',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('useDisciplines', () => {
|
||||
it('ควรดึงข้อมูลสาขา (Disciplines) สำเร็จ', async () => {
|
||||
const mockData = [{ publicId: 'uuid-disp-1', disciplineCode: 'CIV' }];
|
||||
vi.mocked(masterDataService.getDisciplines).mockResolvedValue(mockData);
|
||||
const { wrapper } = createTestQueryClient();
|
||||
const { result } = renderHook(() => useDisciplines('uuid-contract-1'), { wrapper });
|
||||
await waitFor(() => {
|
||||
expect(result.current.isSuccess).toBe(true);
|
||||
});
|
||||
expect(result.current.data).toEqual(mockData);
|
||||
expect(masterDataService.getDisciplines).toHaveBeenCalledWith('uuid-contract-1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('useProjects', () => {
|
||||
it('ควรดึงข้อมูลโครงการ (Projects) สำเร็จ', async () => {
|
||||
const mockData = [{ publicId: 'uuid-proj-1', projectName: 'Project A' }];
|
||||
vi.mocked(projectService.getAll).mockResolvedValue(mockData);
|
||||
const { wrapper } = createTestQueryClient();
|
||||
const { result } = renderHook(() => useProjects(true), { wrapper });
|
||||
await waitFor(() => {
|
||||
expect(result.current.isSuccess).toBe(true);
|
||||
});
|
||||
expect(result.current.data).toEqual(mockData);
|
||||
expect(projectService.getAll).toHaveBeenCalledWith({ isActive: true });
|
||||
});
|
||||
});
|
||||
|
||||
describe('useContracts', () => {
|
||||
it('ควรดึงข้อมูลสัญญา (Contracts) สำเร็จ', async () => {
|
||||
const mockData = [{ publicId: 'uuid-cont-1', name: 'Contract A' }];
|
||||
vi.mocked(contractService.getAll).mockResolvedValue(mockData);
|
||||
const { wrapper } = createTestQueryClient();
|
||||
const { result } = renderHook(() => useContracts('uuid-proj-1'), { wrapper });
|
||||
await waitFor(() => {
|
||||
expect(result.current.isSuccess).toBe(true);
|
||||
});
|
||||
expect(result.current.data).toEqual(mockData);
|
||||
expect(contractService.getAll).toHaveBeenCalledWith({ projectId: 'uuid-proj-1' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('useCorrespondenceTypes', () => {
|
||||
it('ควรดึงข้อมูลชนิดจดหมายนำส่งสำเร็จ', async () => {
|
||||
const mockData = [{ publicId: 'uuid-corr-1', typeCode: 'RFA' }];
|
||||
vi.mocked(masterDataService.getCorrespondenceTypes).mockResolvedValue(mockData);
|
||||
const { wrapper } = createTestQueryClient();
|
||||
const { result } = renderHook(() => useCorrespondenceTypes(), { wrapper });
|
||||
await waitFor(() => {
|
||||
expect(result.current.isSuccess).toBe(true);
|
||||
});
|
||||
expect(result.current.data).toEqual(mockData);
|
||||
expect(masterDataService.getCorrespondenceTypes).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('useContractDrawingCategories', () => {
|
||||
it('ควรดึงข้อมูลหมวดหมู่แบบคู่สัญญาสำเร็จ', async () => {
|
||||
const mockData = [{ id: 1, categoryName: 'Design Drawing' }];
|
||||
vi.mocked(masterDataService.getContractDrawingCategories).mockResolvedValue(mockData);
|
||||
const { wrapper } = createTestQueryClient();
|
||||
const { result } = renderHook(() => useContractDrawingCategories('uuid-proj-1'), { wrapper });
|
||||
await waitFor(() => {
|
||||
expect(result.current.isSuccess).toBe(true);
|
||||
});
|
||||
expect(result.current.data).toEqual(mockData);
|
||||
expect(masterDataService.getContractDrawingCategories).toHaveBeenCalledWith('uuid-proj-1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('useShopMainCategories', () => {
|
||||
it('ควรดึงข้อมูลหมวดหมู่หลักแบบรายละเอียดก่อสร้างสำเร็จ', async () => {
|
||||
const mockData = [{ id: 1, mainCategoryName: 'Structural' }];
|
||||
vi.mocked(masterDataService.getShopMainCategories).mockResolvedValue(mockData);
|
||||
const { wrapper } = createTestQueryClient();
|
||||
const { result } = renderHook(() => useShopMainCategories(123), { wrapper });
|
||||
await waitFor(() => {
|
||||
expect(result.current.isSuccess).toBe(true);
|
||||
});
|
||||
expect(result.current.data).toEqual(mockData);
|
||||
expect(masterDataService.getShopMainCategories).toHaveBeenCalledWith(123);
|
||||
});
|
||||
});
|
||||
|
||||
describe('useShopSubCategories', () => {
|
||||
it('ควรดึงข้อมูลหมวดหมู่ย่อยสำเร็จ', async () => {
|
||||
const mockData = [{ id: 10, subCategoryName: 'Foundation' }];
|
||||
vi.mocked(masterDataService.getShopSubCategories).mockResolvedValue(mockData);
|
||||
const { wrapper } = createTestQueryClient();
|
||||
const { result } = renderHook(() => useShopSubCategories(123, 1), { wrapper });
|
||||
await waitFor(() => {
|
||||
expect(result.current.isSuccess).toBe(true);
|
||||
});
|
||||
expect(result.current.data).toEqual(mockData);
|
||||
expect(masterDataService.getShopSubCategories).toHaveBeenCalledWith(123, 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user