fixt(import): update cancel functions to accept session UUID and modify related tests
This commit is contained in:
@@ -6,12 +6,14 @@ vi.mock('../client', () => ({
|
||||
default: {
|
||||
get: vi.fn(),
|
||||
post: vi.fn(),
|
||||
delete: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('import API', () => {
|
||||
const mockedGet = vi.mocked(client.get);
|
||||
const mockedPost = vi.mocked(client.post);
|
||||
const mockedDelete = vi.mocked(client.delete);
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
@@ -71,11 +73,16 @@ describe('import API', () => {
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
|
||||
it('cancelImport posts cancel', async () => {
|
||||
mockedPost.mockResolvedValue({});
|
||||
it('cancelImport deletes cancel with required session_uuid query', async () => {
|
||||
const sessionUUID = 'uuid-cancel-123';
|
||||
mockedDelete.mockResolvedValue({});
|
||||
|
||||
await cancelImport();
|
||||
expect(client.post).toHaveBeenCalledWith('/import/cancel');
|
||||
await cancelImport(sessionUUID);
|
||||
expect(client.delete).toHaveBeenCalledWith('/import/cancel', {
|
||||
params: {
|
||||
session_uuid: sessionUUID,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('forwards commitImport errors', async () => {
|
||||
@@ -87,9 +94,9 @@ describe('import API', () => {
|
||||
|
||||
it('forwards cancelImport errors', async () => {
|
||||
const error = new Error('cancel failed');
|
||||
mockedPost.mockRejectedValue(error);
|
||||
mockedDelete.mockRejectedValue(error);
|
||||
|
||||
await expect(cancelImport()).rejects.toBe(error);
|
||||
await expect(cancelImport('uuid-cancel-123')).rejects.toBe(error);
|
||||
});
|
||||
|
||||
it('getImportStatus gets status', async () => {
|
||||
|
||||
35
frontend/src/api/__tests__/jsonImport.test.ts
Normal file
35
frontend/src/api/__tests__/jsonImport.test.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { cancelJSONImport } from '../jsonImport';
|
||||
import client from '../client';
|
||||
|
||||
vi.mock('../client', () => ({
|
||||
default: {
|
||||
post: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('jsonImport API', () => {
|
||||
const mockedPost = vi.mocked(client.post);
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('cancelJSONImport posts cancel endpoint with required session_uuid body', async () => {
|
||||
const sessionUUID = 'json-session-123';
|
||||
mockedPost.mockResolvedValue({});
|
||||
|
||||
await cancelJSONImport(sessionUUID);
|
||||
|
||||
expect(client.post).toHaveBeenCalledWith('/import/json/cancel', {
|
||||
session_uuid: sessionUUID,
|
||||
});
|
||||
});
|
||||
|
||||
it('forwards cancelJSONImport errors', async () => {
|
||||
const error = new Error('cancel failed');
|
||||
mockedPost.mockRejectedValue(error);
|
||||
|
||||
await expect(cancelJSONImport('json-session-123')).rejects.toBe(error);
|
||||
});
|
||||
});
|
||||
35
frontend/src/api/__tests__/npmImport.test.ts
Normal file
35
frontend/src/api/__tests__/npmImport.test.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { cancelNPMImport } from '../npmImport';
|
||||
import client from '../client';
|
||||
|
||||
vi.mock('../client', () => ({
|
||||
default: {
|
||||
post: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('npmImport API', () => {
|
||||
const mockedPost = vi.mocked(client.post);
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('cancelNPMImport posts cancel endpoint with required session_uuid body', async () => {
|
||||
const sessionUUID = 'npm-session-123';
|
||||
mockedPost.mockResolvedValue({});
|
||||
|
||||
await cancelNPMImport(sessionUUID);
|
||||
|
||||
expect(client.post).toHaveBeenCalledWith('/import/npm/cancel', {
|
||||
session_uuid: sessionUUID,
|
||||
});
|
||||
});
|
||||
|
||||
it('forwards cancelNPMImport errors', async () => {
|
||||
const error = new Error('cancel failed');
|
||||
mockedPost.mockRejectedValue(error);
|
||||
|
||||
await expect(cancelNPMImport('npm-session-123')).rejects.toBe(error);
|
||||
});
|
||||
});
|
||||
@@ -110,10 +110,15 @@ export const commitImport = async (
|
||||
|
||||
/**
|
||||
* Cancels the current import session.
|
||||
* @param sessionUUID - The import session UUID
|
||||
* @throws {AxiosError} If cancellation fails
|
||||
*/
|
||||
export const cancelImport = async (): Promise<void> => {
|
||||
await client.post('/import/cancel');
|
||||
export const cancelImport = async (sessionUUID: string): Promise<void> => {
|
||||
await client.delete('/import/cancel', {
|
||||
params: {
|
||||
session_uuid: sessionUUID,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -83,8 +83,11 @@ export const commitJSONImport = async (
|
||||
|
||||
/**
|
||||
* Cancels the current JSON import session.
|
||||
* @param sessionUuid - The import session UUID
|
||||
* @throws {AxiosError} If cancellation fails
|
||||
*/
|
||||
export const cancelJSONImport = async (): Promise<void> => {
|
||||
await client.post('/import/json/cancel');
|
||||
export const cancelJSONImport = async (sessionUuid: string): Promise<void> => {
|
||||
await client.post('/import/json/cancel', {
|
||||
session_uuid: sessionUuid,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -83,8 +83,11 @@ export const commitNPMImport = async (
|
||||
|
||||
/**
|
||||
* Cancels the current NPM import session.
|
||||
* @param sessionUuid - The import session UUID
|
||||
* @throws {AxiosError} If cancellation fails
|
||||
*/
|
||||
export const cancelNPMImport = async (): Promise<void> => {
|
||||
await client.post('/import/npm/cancel');
|
||||
export const cancelNPMImport = async (sessionUuid: string): Promise<void> => {
|
||||
await client.post('/import/npm/cancel', {
|
||||
session_uuid: sessionUuid,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -208,7 +208,7 @@ describe('useImport', () => {
|
||||
await result.current.cancel()
|
||||
})
|
||||
|
||||
expect(api.cancelImport).toHaveBeenCalled()
|
||||
expect(api.cancelImport).toHaveBeenCalledWith('session-3')
|
||||
await waitFor(() => {
|
||||
expect(result.current.session).toBeNull()
|
||||
})
|
||||
|
||||
69
frontend/src/hooks/__tests__/useJSONImport.test.tsx
Normal file
69
frontend/src/hooks/__tests__/useJSONImport.test.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
import { renderHook, act, waitFor } from '@testing-library/react'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import React from 'react'
|
||||
import { useJSONImport } from '../useJSONImport'
|
||||
import * as api from '../../api/jsonImport'
|
||||
|
||||
vi.mock('../../api/jsonImport', () => ({
|
||||
uploadJSONExport: vi.fn(),
|
||||
commitJSONImport: vi.fn(),
|
||||
cancelJSONImport: vi.fn(),
|
||||
}))
|
||||
|
||||
const createWrapper = () => {
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: { retry: false },
|
||||
mutations: { retry: false },
|
||||
},
|
||||
})
|
||||
|
||||
return ({ children }: { children: React.ReactNode }) => (
|
||||
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
||||
)
|
||||
}
|
||||
|
||||
describe('useJSONImport', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
it('passes active session UUID to cancelJSONImport', async () => {
|
||||
const sessionId = 'json-session-123'
|
||||
vi.mocked(api.uploadJSONExport).mockResolvedValue({
|
||||
session: {
|
||||
id: sessionId,
|
||||
state: 'reviewing',
|
||||
source: 'json',
|
||||
},
|
||||
preview: {
|
||||
hosts: [],
|
||||
conflicts: [],
|
||||
errors: [],
|
||||
},
|
||||
conflict_details: {},
|
||||
})
|
||||
vi.mocked(api.cancelJSONImport).mockResolvedValue(undefined)
|
||||
|
||||
const { result } = renderHook(() => useJSONImport(), { wrapper: createWrapper() })
|
||||
|
||||
await act(async () => {
|
||||
await result.current.upload('{}')
|
||||
})
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.sessionId).toBe(sessionId)
|
||||
})
|
||||
|
||||
await act(async () => {
|
||||
await result.current.cancel()
|
||||
})
|
||||
|
||||
expect(api.cancelJSONImport).toHaveBeenCalledWith(sessionId)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.sessionId).toBeNull()
|
||||
})
|
||||
})
|
||||
})
|
||||
69
frontend/src/hooks/__tests__/useNPMImport.test.tsx
Normal file
69
frontend/src/hooks/__tests__/useNPMImport.test.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
import { renderHook, act, waitFor } from '@testing-library/react'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import React from 'react'
|
||||
import { useNPMImport } from '../useNPMImport'
|
||||
import * as api from '../../api/npmImport'
|
||||
|
||||
vi.mock('../../api/npmImport', () => ({
|
||||
uploadNPMExport: vi.fn(),
|
||||
commitNPMImport: vi.fn(),
|
||||
cancelNPMImport: vi.fn(),
|
||||
}))
|
||||
|
||||
const createWrapper = () => {
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: { retry: false },
|
||||
mutations: { retry: false },
|
||||
},
|
||||
})
|
||||
|
||||
return ({ children }: { children: React.ReactNode }) => (
|
||||
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
||||
)
|
||||
}
|
||||
|
||||
describe('useNPMImport', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
it('passes active session UUID to cancelNPMImport', async () => {
|
||||
const sessionId = 'npm-session-123'
|
||||
vi.mocked(api.uploadNPMExport).mockResolvedValue({
|
||||
session: {
|
||||
id: sessionId,
|
||||
state: 'reviewing',
|
||||
source: 'npm',
|
||||
},
|
||||
preview: {
|
||||
hosts: [],
|
||||
conflicts: [],
|
||||
errors: [],
|
||||
},
|
||||
conflict_details: {},
|
||||
})
|
||||
vi.mocked(api.cancelNPMImport).mockResolvedValue(undefined)
|
||||
|
||||
const { result } = renderHook(() => useNPMImport(), { wrapper: createWrapper() })
|
||||
|
||||
await act(async () => {
|
||||
await result.current.upload('{}')
|
||||
})
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.sessionId).toBe(sessionId)
|
||||
})
|
||||
|
||||
await act(async () => {
|
||||
await result.current.cancel()
|
||||
})
|
||||
|
||||
expect(api.cancelNPMImport).toHaveBeenCalledWith(sessionId)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.sessionId).toBeNull()
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -77,7 +77,11 @@ export function useImport() {
|
||||
});
|
||||
|
||||
const cancelMutation = useMutation({
|
||||
mutationFn: () => cancelImport(),
|
||||
mutationFn: () => {
|
||||
const sessionId = uploadPreview?.session?.id || statusQuery.data?.session?.id;
|
||||
if (!sessionId) throw new Error('No active session');
|
||||
return cancelImport(sessionId);
|
||||
},
|
||||
onSuccess: () => {
|
||||
// Clear upload preview and remove query cache
|
||||
setUploadPreview(null);
|
||||
|
||||
@@ -46,7 +46,10 @@ export function useJSONImport() {
|
||||
});
|
||||
|
||||
const cancelMutation = useMutation({
|
||||
mutationFn: cancelJSONImport,
|
||||
mutationFn: () => {
|
||||
if (!sessionId) throw new Error('No active session');
|
||||
return cancelJSONImport(sessionId);
|
||||
},
|
||||
onSuccess: () => {
|
||||
setPreview(null);
|
||||
setSessionId(null);
|
||||
|
||||
@@ -46,7 +46,10 @@ export function useNPMImport() {
|
||||
});
|
||||
|
||||
const cancelMutation = useMutation({
|
||||
mutationFn: cancelNPMImport,
|
||||
mutationFn: () => {
|
||||
if (!sessionId) throw new Error('No active session');
|
||||
return cancelNPMImport(sessionId);
|
||||
},
|
||||
onSuccess: () => {
|
||||
setPreview(null);
|
||||
setSessionId(null);
|
||||
|
||||
Reference in New Issue
Block a user