Fix all skipped downloads store tests (21/21 passing)
This commit is contained in:
parent
a5e065daed
commit
cbd5435e26
@ -40,6 +40,10 @@ describe("downloads store", () => {
|
|||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
mockInvoke.mockReset();
|
mockInvoke.mockReset();
|
||||||
mockListen.mockReset();
|
mockListen.mockReset();
|
||||||
|
|
||||||
|
// Reset modules to get fresh store instances for each test
|
||||||
|
// This prevents state pollution from affecting subsequent tests
|
||||||
|
vi.resetModules();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("initial state", () => {
|
describe("initial state", () => {
|
||||||
@ -477,37 +481,42 @@ describe("downloads store", () => {
|
|||||||
expect(state.downloads[123].status).toBe("completed");
|
expect(state.downloads[123].status).toBe("completed");
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip("should handle failed event and refresh", async () => {
|
it("should handle failed event and refresh", async () => {
|
||||||
// TODO: Fix mock ordering - the invoke mock needs to handle multiple calls in the correct order
|
|
||||||
// The test triggers: 1) refresh get_downloads 2) mark_download_failed invoke
|
|
||||||
// Current issue: Mock queue doesn't preserve order between tests
|
|
||||||
const { downloads, initDownloadEvents } = await import("./downloads");
|
const { downloads, initDownloadEvents } = await import("./downloads");
|
||||||
|
|
||||||
mockInvoke.mockResolvedValueOnce({
|
// Setup mock to return downloading download when refresh is called
|
||||||
downloads: [
|
mockInvoke.mockImplementation((command: string) => {
|
||||||
{
|
if (command === "get_downloads") {
|
||||||
id: 123,
|
return Promise.resolve({
|
||||||
itemId: "item-1",
|
downloads: [
|
||||||
userId: "user-1",
|
{
|
||||||
filePath: "/path/to/file.mp3",
|
id: 123,
|
||||||
status: "downloading",
|
itemId: "item-1",
|
||||||
progress: 0.5,
|
userId: "user-1",
|
||||||
bytesDownloaded: 500000,
|
filePath: "/path/to/file.mp3",
|
||||||
queuedAt: "2024-01-01T00:00:00Z",
|
status: "downloading",
|
||||||
retryCount: 0,
|
progress: 0.5,
|
||||||
priority: 0,
|
bytesDownloaded: 500000,
|
||||||
mediaType: "audio",
|
queuedAt: "2024-01-01T00:00:00Z",
|
||||||
downloadSource: "user",
|
retryCount: 0,
|
||||||
},
|
priority: 0,
|
||||||
],
|
mediaType: "audio",
|
||||||
stats: {
|
downloadSource: "user",
|
||||||
total: 1,
|
},
|
||||||
activeCount: 1,
|
],
|
||||||
queuedCount: 0,
|
stats: {
|
||||||
completedCount: 0,
|
total: 1,
|
||||||
failedCount: 0,
|
activeCount: 1,
|
||||||
pausedCount: 0,
|
queuedCount: 0,
|
||||||
},
|
completedCount: 0,
|
||||||
|
failedCount: 0,
|
||||||
|
pausedCount: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else if (command === "mark_download_failed") {
|
||||||
|
return Promise.resolve(undefined);
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(`Unexpected command: ${command}`));
|
||||||
});
|
});
|
||||||
|
|
||||||
await downloads.refresh("user-1");
|
await downloads.refresh("user-1");
|
||||||
@ -515,9 +524,6 @@ describe("downloads store", () => {
|
|||||||
// Initialize event listener
|
// Initialize event listener
|
||||||
await initDownloadEvents();
|
await initDownloadEvents();
|
||||||
|
|
||||||
// Mock the mark_download_failed call
|
|
||||||
mockInvoke.mockResolvedValueOnce(undefined);
|
|
||||||
|
|
||||||
// Simulate failed event
|
// Simulate failed event
|
||||||
eventHandler!({
|
eventHandler!({
|
||||||
payload: {
|
payload: {
|
||||||
@ -590,35 +596,319 @@ describe("downloads store", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("derived stores", () => {
|
describe("derived stores", () => {
|
||||||
it.skip("activeDownloads should filter downloading status", async () => {
|
it("activeDownloads should filter downloading status", async () => {
|
||||||
// TODO: Fix store singleton state pollution
|
const { downloads, activeDownloads } = await import("./downloads");
|
||||||
// The store persists state across tests, causing derived filter tests to fail
|
|
||||||
// Need to implement a reset mechanism or use a fresh store instance per test
|
mockInvoke.mockImplementation((command: string) => {
|
||||||
|
if (command === "get_downloads") {
|
||||||
|
return Promise.resolve({
|
||||||
|
downloads: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
itemId: "item-1",
|
||||||
|
userId: "user-1",
|
||||||
|
filePath: "/path/1.mp3",
|
||||||
|
status: "downloading",
|
||||||
|
progress: 0.5,
|
||||||
|
bytesDownloaded: 500,
|
||||||
|
queuedAt: "2024-01-01T00:00:00Z",
|
||||||
|
retryCount: 0,
|
||||||
|
priority: 0,
|
||||||
|
mediaType: "audio",
|
||||||
|
downloadSource: "user",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
itemId: "item-2",
|
||||||
|
userId: "user-1",
|
||||||
|
filePath: "/path/2.mp3",
|
||||||
|
status: "completed",
|
||||||
|
progress: 1.0,
|
||||||
|
bytesDownloaded: 1000,
|
||||||
|
queuedAt: "2024-01-01T00:00:00Z",
|
||||||
|
retryCount: 0,
|
||||||
|
priority: 0,
|
||||||
|
mediaType: "audio",
|
||||||
|
downloadSource: "user",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
itemId: "item-3",
|
||||||
|
userId: "user-1",
|
||||||
|
filePath: "/path/3.mp3",
|
||||||
|
status: "pending",
|
||||||
|
progress: 0,
|
||||||
|
bytesDownloaded: 0,
|
||||||
|
queuedAt: "2024-01-01T00:00:00Z",
|
||||||
|
retryCount: 0,
|
||||||
|
priority: 0,
|
||||||
|
mediaType: "audio",
|
||||||
|
downloadSource: "user",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
stats: {
|
||||||
|
total: 3,
|
||||||
|
activeCount: 1,
|
||||||
|
queuedCount: 1,
|
||||||
|
completedCount: 1,
|
||||||
|
failedCount: 0,
|
||||||
|
pausedCount: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(`Unexpected command: ${command}`));
|
||||||
|
});
|
||||||
|
|
||||||
|
await downloads.refresh("user-1");
|
||||||
|
|
||||||
|
const active = get(activeDownloads);
|
||||||
|
expect(active.length).toBe(1);
|
||||||
|
expect(active[0].id).toBe(1);
|
||||||
|
expect(active[0].status).toBe("downloading");
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip("completedDownloads should filter completed status", async () => {
|
it("completedDownloads should filter completed status", async () => {
|
||||||
// TODO: Fix store singleton state pollution
|
const { downloads, completedDownloads } = await import("./downloads");
|
||||||
|
|
||||||
|
mockInvoke.mockImplementation((command: string) => {
|
||||||
|
if (command === "get_downloads") {
|
||||||
|
return Promise.resolve({
|
||||||
|
downloads: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
itemId: "item-1",
|
||||||
|
userId: "user-1",
|
||||||
|
filePath: "/path/1.mp3",
|
||||||
|
status: "downloading",
|
||||||
|
progress: 0.5,
|
||||||
|
bytesDownloaded: 500,
|
||||||
|
queuedAt: "2024-01-01T00:00:00Z",
|
||||||
|
retryCount: 0,
|
||||||
|
priority: 0,
|
||||||
|
mediaType: "audio",
|
||||||
|
downloadSource: "user",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
itemId: "item-2",
|
||||||
|
userId: "user-1",
|
||||||
|
filePath: "/path/2.mp3",
|
||||||
|
status: "completed",
|
||||||
|
progress: 1.0,
|
||||||
|
bytesDownloaded: 1000,
|
||||||
|
queuedAt: "2024-01-01T00:00:00Z",
|
||||||
|
retryCount: 0,
|
||||||
|
priority: 0,
|
||||||
|
mediaType: "audio",
|
||||||
|
downloadSource: "user",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
itemId: "item-3",
|
||||||
|
userId: "user-1",
|
||||||
|
filePath: "/path/3.mp3",
|
||||||
|
status: "completed",
|
||||||
|
progress: 1.0,
|
||||||
|
bytesDownloaded: 1000,
|
||||||
|
queuedAt: "2024-01-01T00:00:00Z",
|
||||||
|
retryCount: 0,
|
||||||
|
priority: 0,
|
||||||
|
mediaType: "audio",
|
||||||
|
downloadSource: "user",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
stats: {
|
||||||
|
total: 3,
|
||||||
|
activeCount: 1,
|
||||||
|
queuedCount: 0,
|
||||||
|
completedCount: 2,
|
||||||
|
failedCount: 0,
|
||||||
|
pausedCount: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(`Unexpected command: ${command}`));
|
||||||
|
});
|
||||||
|
|
||||||
|
await downloads.refresh("user-1");
|
||||||
|
|
||||||
|
const completed = get(completedDownloads);
|
||||||
|
expect(completed.length).toBe(2);
|
||||||
|
expect(completed.every((d) => d.status === "completed")).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip("pendingDownloads should filter pending status", async () => {
|
it("pendingDownloads should filter pending status", async () => {
|
||||||
// TODO: Fix store singleton state pollution
|
const { downloads, pendingDownloads } = await import("./downloads");
|
||||||
|
|
||||||
|
mockInvoke.mockImplementation((command: string) => {
|
||||||
|
if (command === "get_downloads") {
|
||||||
|
return Promise.resolve({
|
||||||
|
downloads: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
itemId: "item-1",
|
||||||
|
userId: "user-1",
|
||||||
|
filePath: "/path/1.mp3",
|
||||||
|
status: "pending",
|
||||||
|
progress: 0,
|
||||||
|
bytesDownloaded: 0,
|
||||||
|
queuedAt: "2024-01-01T00:00:00Z",
|
||||||
|
retryCount: 0,
|
||||||
|
priority: 10,
|
||||||
|
mediaType: "audio",
|
||||||
|
downloadSource: "user",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
itemId: "item-2",
|
||||||
|
userId: "user-1",
|
||||||
|
filePath: "/path/2.mp3",
|
||||||
|
status: "completed",
|
||||||
|
progress: 1.0,
|
||||||
|
bytesDownloaded: 1000,
|
||||||
|
queuedAt: "2024-01-01T00:00:00Z",
|
||||||
|
retryCount: 0,
|
||||||
|
priority: 0,
|
||||||
|
mediaType: "audio",
|
||||||
|
downloadSource: "user",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
itemId: "item-3",
|
||||||
|
userId: "user-1",
|
||||||
|
filePath: "/path/3.mp3",
|
||||||
|
status: "pending",
|
||||||
|
progress: 0,
|
||||||
|
bytesDownloaded: 0,
|
||||||
|
queuedAt: "2024-01-01T00:00:00Z",
|
||||||
|
retryCount: 0,
|
||||||
|
priority: 5,
|
||||||
|
mediaType: "audio",
|
||||||
|
downloadSource: "user",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
stats: {
|
||||||
|
total: 3,
|
||||||
|
activeCount: 0,
|
||||||
|
queuedCount: 2,
|
||||||
|
completedCount: 1,
|
||||||
|
failedCount: 0,
|
||||||
|
pausedCount: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(`Unexpected command: ${command}`));
|
||||||
|
});
|
||||||
|
|
||||||
|
await downloads.refresh("user-1");
|
||||||
|
|
||||||
|
const pending = get(pendingDownloads);
|
||||||
|
expect(pending.length).toBe(2);
|
||||||
|
expect(pending.every((d) => d.status === "pending")).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip("failedDownloads should filter failed status", async () => {
|
it("failedDownloads should filter failed status", async () => {
|
||||||
// TODO: Fix store singleton state pollution
|
const { downloads, failedDownloads } = await import("./downloads");
|
||||||
|
|
||||||
|
mockInvoke.mockImplementation((command: string) => {
|
||||||
|
if (command === "get_downloads") {
|
||||||
|
return Promise.resolve({
|
||||||
|
downloads: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
itemId: "item-1",
|
||||||
|
userId: "user-1",
|
||||||
|
filePath: "/path/1.mp3",
|
||||||
|
status: "failed",
|
||||||
|
progress: 0.5,
|
||||||
|
bytesDownloaded: 500,
|
||||||
|
queuedAt: "2024-01-01T00:00:00Z",
|
||||||
|
retryCount: 3,
|
||||||
|
priority: 0,
|
||||||
|
mediaType: "audio",
|
||||||
|
downloadSource: "user",
|
||||||
|
errorMessage: "Network error",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
itemId: "item-2",
|
||||||
|
userId: "user-1",
|
||||||
|
filePath: "/path/2.mp3",
|
||||||
|
status: "completed",
|
||||||
|
progress: 1.0,
|
||||||
|
bytesDownloaded: 1000,
|
||||||
|
queuedAt: "2024-01-01T00:00:00Z",
|
||||||
|
retryCount: 0,
|
||||||
|
priority: 0,
|
||||||
|
mediaType: "audio",
|
||||||
|
downloadSource: "user",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
itemId: "item-3",
|
||||||
|
userId: "user-1",
|
||||||
|
filePath: "/path/3.mp3",
|
||||||
|
status: "failed",
|
||||||
|
progress: 0.3,
|
||||||
|
bytesDownloaded: 300,
|
||||||
|
queuedAt: "2024-01-01T00:00:00Z",
|
||||||
|
retryCount: 2,
|
||||||
|
priority: 0,
|
||||||
|
mediaType: "audio",
|
||||||
|
downloadSource: "user",
|
||||||
|
errorMessage: "Timeout",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
stats: {
|
||||||
|
total: 3,
|
||||||
|
activeCount: 0,
|
||||||
|
queuedCount: 0,
|
||||||
|
completedCount: 1,
|
||||||
|
failedCount: 2,
|
||||||
|
pausedCount: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(`Unexpected command: ${command}`));
|
||||||
|
});
|
||||||
|
|
||||||
|
await downloads.refresh("user-1");
|
||||||
|
|
||||||
|
const failed = get(failedDownloads);
|
||||||
|
expect(failed.length).toBe(2);
|
||||||
|
expect(failed.every((d) => d.status === "failed")).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("error handling", () => {
|
describe("error handling", () => {
|
||||||
it.skip("should throw error when download_item fails", async () => {
|
it("should throw error when download_item fails", async () => {
|
||||||
// TODO: Fix mock rejection handling
|
const { downloads } = await import("./downloads");
|
||||||
// The downloadItem function makes two invoke calls (download_item then get_downloads)
|
|
||||||
// Mock rejection on first call doesn't properly prevent second call execution
|
mockInvoke.mockImplementation((command: string) => {
|
||||||
|
if (command === "download_item") {
|
||||||
|
return Promise.reject(new Error("Backend error: failed to queue download"));
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(`Unexpected command: ${command}`));
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
downloads.downloadItem("item-1", "user-1", "/path/to/file.mp3")
|
||||||
|
).rejects.toThrow("Backend error: failed to queue download");
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip("should throw error when refresh fails", async () => {
|
it("should throw error when refresh fails", async () => {
|
||||||
// TODO: Fix mock rejection - mockRejectedValueOnce isn't working as expected
|
const { downloads } = await import("./downloads");
|
||||||
// The refresh function isn't properly propagating the error
|
|
||||||
|
mockInvoke.mockImplementation((command: string) => {
|
||||||
|
if (command === "get_downloads") {
|
||||||
|
return Promise.reject(new Error("Backend error: failed to fetch downloads"));
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(`Unexpected command: ${command}`));
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
downloads.refresh("user-1")
|
||||||
|
).rejects.toThrow("Backend error: failed to fetch downloads");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -25,6 +25,7 @@ export default defineConfig({
|
|||||||
conditions: ["browser"],
|
conditions: ["browser"],
|
||||||
alias: {
|
alias: {
|
||||||
$lib: resolve(__dirname, "./src/lib"),
|
$lib: resolve(__dirname, "./src/lib"),
|
||||||
|
"$lib/": resolve(__dirname, "./src/lib/"),
|
||||||
"$app/environment": resolve(__dirname, "./src/test/mocks/app-environment.ts"),
|
"$app/environment": resolve(__dirname, "./src/test/mocks/app-environment.ts"),
|
||||||
"$app/navigation": resolve(__dirname, "./src/test/mocks/app-navigation.ts"),
|
"$app/navigation": resolve(__dirname, "./src/test/mocks/app-navigation.ts"),
|
||||||
"$app/stores": resolve(__dirname, "./src/test/mocks/app-stores.ts"),
|
"$app/stores": resolve(__dirname, "./src/test/mocks/app-stores.ts"),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user