260324:2133 Refactor correspondence & rfa
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { renderHook, waitFor } from '@testing-library/react';
|
||||
import { createTestQueryClient } from '@/lib/test-utils';
|
||||
import {
|
||||
useCirculationsByCorrespondence,
|
||||
circulationKeys,
|
||||
} from '../use-circulation';
|
||||
import { circulationService } from '@/lib/services/circulation.service';
|
||||
|
||||
vi.mock('@/lib/services/circulation.service', () => ({
|
||||
circulationService: {
|
||||
getByCorrespondenceUuid: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('use-circulation hooks', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('circulationKeys', () => {
|
||||
it('should generate correct cache keys', () => {
|
||||
expect(circulationKeys.all).toEqual(['circulations']);
|
||||
expect(circulationKeys.byCorrespondence('uuid-abc')).toEqual([
|
||||
'circulations',
|
||||
'byCorrespondence',
|
||||
'uuid-abc',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('useCirculationsByCorrespondence', () => {
|
||||
it('should fetch circulations for a correspondence UUID', async () => {
|
||||
const mockData = {
|
||||
data: [
|
||||
{
|
||||
uuid: 'circ-uuid-1',
|
||||
circulationNo: 'CIR-001',
|
||||
subject: 'Review Document',
|
||||
statusCode: 'OPEN',
|
||||
routings: [],
|
||||
},
|
||||
],
|
||||
meta: { total: 1, page: 1, limit: 50 },
|
||||
};
|
||||
|
||||
vi.mocked(circulationService.getByCorrespondenceUuid).mockResolvedValue(mockData);
|
||||
|
||||
const { wrapper } = createTestQueryClient();
|
||||
const { result } = renderHook(
|
||||
() => useCirculationsByCorrespondence('corr-uuid-1'),
|
||||
{ wrapper }
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.isSuccess).toBe(true);
|
||||
});
|
||||
|
||||
expect(circulationService.getByCorrespondenceUuid).toHaveBeenCalledWith('corr-uuid-1');
|
||||
expect(result.current.data).toEqual(mockData);
|
||||
});
|
||||
|
||||
it('should not fetch when correspondenceUuid is empty', () => {
|
||||
const { wrapper } = createTestQueryClient();
|
||||
const { result } = renderHook(
|
||||
() => useCirculationsByCorrespondence(''),
|
||||
{ wrapper }
|
||||
);
|
||||
|
||||
expect(result.current.fetchStatus).toBe('idle');
|
||||
expect(circulationService.getByCorrespondenceUuid).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle fetch error gracefully', async () => {
|
||||
vi.mocked(circulationService.getByCorrespondenceUuid).mockRejectedValue(
|
||||
new Error('Network error')
|
||||
);
|
||||
|
||||
const { wrapper } = createTestQueryClient();
|
||||
const { result } = renderHook(
|
||||
() => useCirculationsByCorrespondence('corr-uuid-error'),
|
||||
{ wrapper }
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.isError).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('should use the correct query key', () => {
|
||||
vi.mocked(circulationService.getByCorrespondenceUuid).mockResolvedValue([]);
|
||||
|
||||
const { wrapper } = createTestQueryClient();
|
||||
const { result } = renderHook(
|
||||
() => useCirculationsByCorrespondence('test-uuid'),
|
||||
{ wrapper }
|
||||
);
|
||||
|
||||
expect(result.current.status).toBeDefined();
|
||||
expect(circulationKeys.byCorrespondence('test-uuid')).toEqual([
|
||||
'circulations',
|
||||
'byCorrespondence',
|
||||
'test-uuid',
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { circulationService } from '@/lib/services/circulation.service';
|
||||
|
||||
export const circulationKeys = {
|
||||
all: ['circulations'] as const,
|
||||
byCorrespondence: (uuid: string) => ['circulations', 'byCorrespondence', uuid] as const,
|
||||
};
|
||||
|
||||
export function useCirculationsByCorrespondence(correspondenceUuid: string) {
|
||||
return useQuery({
|
||||
queryKey: circulationKeys.byCorrespondence(correspondenceUuid),
|
||||
queryFn: () => circulationService.getByCorrespondenceUuid(correspondenceUuid),
|
||||
enabled: !!correspondenceUuid,
|
||||
});
|
||||
}
|
||||
@@ -91,6 +91,25 @@ export function useDeleteCorrespondence() {
|
||||
});
|
||||
}
|
||||
|
||||
export function useCancelCorrespondence() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: ({ uuid, reason }: { uuid: string; reason: string }) =>
|
||||
correspondenceService.cancel(uuid, reason),
|
||||
onSuccess: (_, { uuid }) => {
|
||||
toast.success('Correspondence cancelled successfully');
|
||||
queryClient.invalidateQueries({ queryKey: correspondenceKeys.detail(uuid) });
|
||||
queryClient.invalidateQueries({ queryKey: correspondenceKeys.lists() });
|
||||
},
|
||||
onError: (error: ApiError) => {
|
||||
toast.error('Failed to cancel correspondence', {
|
||||
description: error.response?.data?.message || 'Something went wrong',
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useSubmitCorrespondence() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -110,6 +129,94 @@ export function useSubmitCorrespondence() {
|
||||
});
|
||||
}
|
||||
|
||||
export function useCorrespondenceTags(uuid: string) {
|
||||
return useQuery({
|
||||
queryKey: [...correspondenceKeys.detail(uuid), 'tags'] as const,
|
||||
queryFn: () => correspondenceService.getTags(uuid),
|
||||
enabled: !!uuid,
|
||||
});
|
||||
}
|
||||
|
||||
export function useAddTag() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: ({ uuid, tagId }: { uuid: string; tagId: number }) =>
|
||||
correspondenceService.addTag(uuid, tagId),
|
||||
onSuccess: (_, { uuid }) => {
|
||||
toast.success('Tag added');
|
||||
queryClient.invalidateQueries({ queryKey: [...correspondenceKeys.detail(uuid), 'tags'] });
|
||||
},
|
||||
onError: (error: ApiError) => {
|
||||
toast.error('Failed to add tag', {
|
||||
description: error.response?.data?.message || 'Something went wrong',
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useRemoveTag() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: ({ uuid, tagId }: { uuid: string; tagId: number }) =>
|
||||
correspondenceService.removeTag(uuid, tagId),
|
||||
onSuccess: (_, { uuid }) => {
|
||||
toast.success('Tag removed');
|
||||
queryClient.invalidateQueries({ queryKey: [...correspondenceKeys.detail(uuid), 'tags'] });
|
||||
},
|
||||
onError: (error: ApiError) => {
|
||||
toast.error('Failed to remove tag', {
|
||||
description: error.response?.data?.message || 'Something went wrong',
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useReferences(uuid: string) {
|
||||
return useQuery({
|
||||
queryKey: [...correspondenceKeys.detail(uuid), 'references'] as const,
|
||||
queryFn: () => correspondenceService.getReferences(uuid),
|
||||
enabled: !!uuid,
|
||||
});
|
||||
}
|
||||
|
||||
export function useAddReference() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: ({ uuid, targetUuid }: { uuid: string; targetUuid: string }) =>
|
||||
correspondenceService.addReference(uuid, { targetUuid }),
|
||||
onSuccess: (_, { uuid }) => {
|
||||
toast.success('Reference added successfully');
|
||||
queryClient.invalidateQueries({ queryKey: [...correspondenceKeys.detail(uuid), 'references'] });
|
||||
},
|
||||
onError: (error: ApiError) => {
|
||||
toast.error('Failed to add reference', {
|
||||
description: error.response?.data?.message || 'Something went wrong',
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useRemoveReference() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: ({ uuid, targetUuid }: { uuid: string; targetUuid: string }) =>
|
||||
correspondenceService.removeReference(uuid, targetUuid),
|
||||
onSuccess: (_, { uuid }) => {
|
||||
toast.success('Reference removed');
|
||||
queryClient.invalidateQueries({ queryKey: [...correspondenceKeys.detail(uuid), 'references'] });
|
||||
},
|
||||
onError: (error: ApiError) => {
|
||||
toast.error('Failed to remove reference', {
|
||||
description: error.response?.data?.message || 'Something went wrong',
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useProcessWorkflow() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user