test: add dual-parameter support and sync mocks for import/export tests
Update test infrastructure to support the dual app type parameter pattern
(app_type enum + app string) introduced in 590be4e:
- Add toast.warning mock for partial-success status handling
- Add syncCurrentProvidersLive mock to test post-import sync behavior
- Update MSW handlers to accept both app_type and app parameters with
fallback resolution (app ?? app_type) across 7 provider endpoints
- Add sync_current_providers_live endpoint mock returning success
This ensures test compatibility during the app_type → app parameter
migration and enables testing of the new partial-success import flow.
This commit is contained in:
@@ -4,11 +4,13 @@ import { useImportExport } from "@/hooks/useImportExport";
|
|||||||
|
|
||||||
const toastSuccessMock = vi.fn();
|
const toastSuccessMock = vi.fn();
|
||||||
const toastErrorMock = vi.fn();
|
const toastErrorMock = vi.fn();
|
||||||
|
const toastWarningMock = vi.fn();
|
||||||
|
|
||||||
vi.mock("sonner", () => ({
|
vi.mock("sonner", () => ({
|
||||||
toast: {
|
toast: {
|
||||||
success: (...args: unknown[]) => toastSuccessMock(...args),
|
success: (...args: unknown[]) => toastSuccessMock(...args),
|
||||||
error: (...args: unknown[]) => toastErrorMock(...args),
|
error: (...args: unknown[]) => toastErrorMock(...args),
|
||||||
|
warning: (...args: unknown[]) => toastWarningMock(...args),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -16,6 +18,7 @@ const openFileDialogMock = vi.fn();
|
|||||||
const importConfigMock = vi.fn();
|
const importConfigMock = vi.fn();
|
||||||
const saveFileDialogMock = vi.fn();
|
const saveFileDialogMock = vi.fn();
|
||||||
const exportConfigMock = vi.fn();
|
const exportConfigMock = vi.fn();
|
||||||
|
const syncCurrentProvidersLiveMock = vi.fn();
|
||||||
|
|
||||||
vi.mock("@/lib/api", () => ({
|
vi.mock("@/lib/api", () => ({
|
||||||
settingsApi: {
|
settingsApi: {
|
||||||
@@ -23,6 +26,7 @@ vi.mock("@/lib/api", () => ({
|
|||||||
importConfigFromFile: (...args: unknown[]) => importConfigMock(...args),
|
importConfigFromFile: (...args: unknown[]) => importConfigMock(...args),
|
||||||
saveFileDialog: (...args: unknown[]) => saveFileDialogMock(...args),
|
saveFileDialog: (...args: unknown[]) => saveFileDialogMock(...args),
|
||||||
exportConfigToFile: (...args: unknown[]) => exportConfigMock(...args),
|
exportConfigToFile: (...args: unknown[]) => exportConfigMock(...args),
|
||||||
|
syncCurrentProvidersLive: (...args: unknown[]) => syncCurrentProvidersLiveMock(...args),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -34,6 +38,8 @@ describe("useImportExport Hook (edge cases)", () => {
|
|||||||
exportConfigMock.mockReset();
|
exportConfigMock.mockReset();
|
||||||
toastSuccessMock.mockReset();
|
toastSuccessMock.mockReset();
|
||||||
toastErrorMock.mockReset();
|
toastErrorMock.mockReset();
|
||||||
|
toastWarningMock.mockReset();
|
||||||
|
syncCurrentProvidersLiveMock.mockReset();
|
||||||
vi.useFakeTimers();
|
vi.useFakeTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,13 @@ import { useImportExport } from "@/hooks/useImportExport";
|
|||||||
|
|
||||||
const toastSuccessMock = vi.fn();
|
const toastSuccessMock = vi.fn();
|
||||||
const toastErrorMock = vi.fn();
|
const toastErrorMock = vi.fn();
|
||||||
|
const toastWarningMock = vi.fn();
|
||||||
|
|
||||||
vi.mock("sonner", () => ({
|
vi.mock("sonner", () => ({
|
||||||
toast: {
|
toast: {
|
||||||
success: (...args: unknown[]) => toastSuccessMock(...args),
|
success: (...args: unknown[]) => toastSuccessMock(...args),
|
||||||
error: (...args: unknown[]) => toastErrorMock(...args),
|
error: (...args: unknown[]) => toastErrorMock(...args),
|
||||||
|
warning: (...args: unknown[]) => toastWarningMock(...args),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -16,6 +18,7 @@ const openFileDialogMock = vi.fn();
|
|||||||
const importConfigMock = vi.fn();
|
const importConfigMock = vi.fn();
|
||||||
const saveFileDialogMock = vi.fn();
|
const saveFileDialogMock = vi.fn();
|
||||||
const exportConfigMock = vi.fn();
|
const exportConfigMock = vi.fn();
|
||||||
|
const syncCurrentProvidersLiveMock = vi.fn();
|
||||||
|
|
||||||
vi.mock("@/lib/api", () => ({
|
vi.mock("@/lib/api", () => ({
|
||||||
settingsApi: {
|
settingsApi: {
|
||||||
@@ -23,6 +26,7 @@ vi.mock("@/lib/api", () => ({
|
|||||||
importConfigFromFile: (...args: unknown[]) => importConfigMock(...args),
|
importConfigFromFile: (...args: unknown[]) => importConfigMock(...args),
|
||||||
saveFileDialog: (...args: unknown[]) => saveFileDialogMock(...args),
|
saveFileDialog: (...args: unknown[]) => saveFileDialogMock(...args),
|
||||||
exportConfigToFile: (...args: unknown[]) => exportConfigMock(...args),
|
exportConfigToFile: (...args: unknown[]) => exportConfigMock(...args),
|
||||||
|
syncCurrentProvidersLive: (...args: unknown[]) => syncCurrentProvidersLiveMock(...args),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -33,6 +37,8 @@ beforeEach(() => {
|
|||||||
exportConfigMock.mockReset();
|
exportConfigMock.mockReset();
|
||||||
toastSuccessMock.mockReset();
|
toastSuccessMock.mockReset();
|
||||||
toastErrorMock.mockReset();
|
toastErrorMock.mockReset();
|
||||||
|
toastWarningMock.mockReset();
|
||||||
|
syncCurrentProvidersLiveMock.mockReset();
|
||||||
vi.useFakeTimers();
|
vi.useFakeTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -37,63 +37,81 @@ const success = <T>(payload: T) => HttpResponse.json(payload as any);
|
|||||||
|
|
||||||
export const handlers = [
|
export const handlers = [
|
||||||
http.post(`${TAURI_ENDPOINT}/get_providers`, async ({ request }) => {
|
http.post(`${TAURI_ENDPOINT}/get_providers`, async ({ request }) => {
|
||||||
const { app_type } = await withJson<{ app_type: AppType }>(request);
|
const { app_type, app } = await withJson<{ app_type?: AppType; app?: AppType }>(
|
||||||
return success(getProviders(app_type));
|
request,
|
||||||
|
);
|
||||||
|
const appType = app ?? app_type!;
|
||||||
|
return success(getProviders(appType));
|
||||||
}),
|
}),
|
||||||
|
|
||||||
http.post(`${TAURI_ENDPOINT}/get_current_provider`, async ({ request }) => {
|
http.post(`${TAURI_ENDPOINT}/get_current_provider`, async ({ request }) => {
|
||||||
const { app_type } = await withJson<{ app_type: AppType }>(request);
|
const { app_type, app } = await withJson<{ app_type?: AppType; app?: AppType }>(
|
||||||
return success(getCurrentProviderId(app_type));
|
request,
|
||||||
|
);
|
||||||
|
const appType = app ?? app_type!;
|
||||||
|
return success(getCurrentProviderId(appType));
|
||||||
}),
|
}),
|
||||||
|
|
||||||
http.post(`${TAURI_ENDPOINT}/update_providers_sort_order`, async ({ request }) => {
|
http.post(`${TAURI_ENDPOINT}/update_providers_sort_order`, async ({ request }) => {
|
||||||
const { updates = [], app_type } = await withJson<{
|
const { updates = [], app_type, app } = await withJson<{
|
||||||
updates: { id: string; sortIndex: number }[];
|
updates: { id: string; sortIndex: number }[];
|
||||||
app_type: AppType;
|
app_type?: AppType;
|
||||||
|
app?: AppType;
|
||||||
}>(request);
|
}>(request);
|
||||||
updateSortOrder(app_type, updates);
|
const appType = app ?? app_type!;
|
||||||
|
updateSortOrder(appType, updates);
|
||||||
return success(true);
|
return success(true);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
http.post(`${TAURI_ENDPOINT}/update_tray_menu`, () => success(true)),
|
http.post(`${TAURI_ENDPOINT}/update_tray_menu`, () => success(true)),
|
||||||
|
|
||||||
http.post(`${TAURI_ENDPOINT}/switch_provider`, async ({ request }) => {
|
http.post(`${TAURI_ENDPOINT}/switch_provider`, async ({ request }) => {
|
||||||
const { id, app_type } = await withJson<{ id: string; app_type: AppType }>(
|
const { id, app_type, app } = await withJson<{
|
||||||
request,
|
id: string;
|
||||||
);
|
app_type?: AppType;
|
||||||
const providers = listProviders(app_type);
|
app?: AppType;
|
||||||
|
}>(request);
|
||||||
|
const appType = app ?? app_type!;
|
||||||
|
const providers = listProviders(appType);
|
||||||
if (!providers[id]) {
|
if (!providers[id]) {
|
||||||
return HttpResponse.json(false, { status: 404 });
|
return HttpResponse.json(false, { status: 404 });
|
||||||
}
|
}
|
||||||
setCurrentProviderId(app_type, id);
|
setCurrentProviderId(appType, id);
|
||||||
return success(true);
|
return success(true);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
http.post(`${TAURI_ENDPOINT}/add_provider`, async ({ request }) => {
|
http.post(`${TAURI_ENDPOINT}/add_provider`, async ({ request }) => {
|
||||||
const { provider, app_type } = await withJson<{
|
const { provider, app_type, app } = await withJson<{
|
||||||
provider: Provider & { id?: string };
|
provider: Provider & { id?: string };
|
||||||
app_type: AppType;
|
app_type?: AppType;
|
||||||
|
app?: AppType;
|
||||||
}>(request);
|
}>(request);
|
||||||
|
|
||||||
const newId = provider.id ?? `mock-${Date.now()}`;
|
const newId = provider.id ?? `mock-${Date.now()}`;
|
||||||
addProvider(app_type, { ...provider, id: newId });
|
const appType = app ?? app_type!;
|
||||||
|
addProvider(appType, { ...provider, id: newId });
|
||||||
return success(true);
|
return success(true);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
http.post(`${TAURI_ENDPOINT}/update_provider`, async ({ request }) => {
|
http.post(`${TAURI_ENDPOINT}/update_provider`, async ({ request }) => {
|
||||||
const { provider, app_type } = await withJson<{
|
const { provider, app_type, app } = await withJson<{
|
||||||
provider: Provider;
|
provider: Provider;
|
||||||
app_type: AppType;
|
app_type?: AppType;
|
||||||
|
app?: AppType;
|
||||||
}>(request);
|
}>(request);
|
||||||
updateProvider(app_type, provider);
|
const appType = app ?? app_type!;
|
||||||
|
updateProvider(appType, provider);
|
||||||
return success(true);
|
return success(true);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
http.post(`${TAURI_ENDPOINT}/delete_provider`, async ({ request }) => {
|
http.post(`${TAURI_ENDPOINT}/delete_provider`, async ({ request }) => {
|
||||||
const { id, app_type } = await withJson<{ id: string; app_type: AppType }>(
|
const { id, app_type, app } = await withJson<{
|
||||||
request,
|
id: string;
|
||||||
);
|
app_type?: AppType;
|
||||||
deleteProvider(app_type, id);
|
app?: AppType;
|
||||||
|
}>(request);
|
||||||
|
const appType = app ?? app_type!;
|
||||||
|
deleteProvider(appType, id);
|
||||||
return success(true);
|
return success(true);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@@ -206,4 +224,9 @@ export const handlers = [
|
|||||||
http.post(`${TAURI_ENDPOINT}/save_file_dialog`, () =>
|
http.post(`${TAURI_ENDPOINT}/save_file_dialog`, () =>
|
||||||
success("/mock/export-settings.json"),
|
success("/mock/export-settings.json"),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// Sync current providers live (no-op success)
|
||||||
|
http.post(`${TAURI_ENDPOINT}/sync_current_providers_live`, () =>
|
||||||
|
success({ success: true }),
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|||||||
Reference in New Issue
Block a user