fix(account): keep download record pending through retry

This commit is contained in:
2026-05-19 00:54:36 +08:00
parent 4c2225290c
commit 4b81869b6e
2 changed files with 85 additions and 3 deletions
+2 -1
View File
@@ -1265,13 +1265,14 @@ const handleInstallCompleteForDownloadRecord = async (
const pendingRecord = pendingDownloadRecords.get(result.id);
if (!pendingRecord) return;
pendingDownloadRecords.delete(result.id);
if (!result.success || !isLoggedIn.value) return;
try {
await recordDownloadedApp(pendingRecord);
} catch (error: unknown) {
logger.warn({ err: error }, "记录下载应用失败");
} finally {
pendingDownloadRecords.delete(result.id);
}
};
@@ -1,9 +1,16 @@
import { fireEvent, render, screen, waitFor } from "@testing-library/vue";
import { beforeEach, describe, expect, it, vi } from "vitest";
import {
cleanup,
fireEvent,
render,
screen,
waitFor,
} from "@testing-library/vue";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import App from "@/App.vue";
import { recordDownloadedApp } from "@/modules/backendApi";
import { setAuthSession } from "@/global/authState";
import { downloads } from "@/global/downloadStatus";
import type { DownloadResult } from "@/global/typedefinition";
const invoke = vi.fn();
@@ -88,9 +95,14 @@ vi.mock("@/modules/backendApi", () => ({
}));
describe("App download records", () => {
afterEach(() => {
cleanup();
});
beforeEach(() => {
vi.clearAllMocks();
ipcHandlers.clear();
downloads.value = [];
invoke.mockImplementation(async (channel: string) => {
if (channel === "get-store-filter") return "apm";
if (channel === "check-spark-available") return false;
@@ -188,4 +200,73 @@ describe("App download records", () => {
);
});
});
it("keeps a pending download record through a failed install retry", async () => {
render(App);
await fireEvent.click(
await screen.findByRole("button", { name: "全部应用 1" }),
);
await fireEvent.click(await screen.findByText("WPS"));
await fireEvent.click(await screen.findByRole("button", { name: "安装" }));
await waitFor(() => {
expect(send).toHaveBeenCalledWith(
"queue-install",
expect.stringContaining('"pkgname":"wps"'),
);
});
const queuedPayload = vi
.mocked(send)
.mock.calls.find(
([channel]) => channel === "queue-install",
)?.[1] as string;
const queuedDownload = JSON.parse(queuedPayload) as { id: number };
const failedCompletion: DownloadResult = {
id: queuedDownload.id,
time: Date.now(),
message: "failed",
success: false,
exitCode: 1,
status: "failed",
origin: "apm",
};
ipcHandlers.get("install-complete")?.({}, failedCompletion);
downloads.value[0].status = "failed";
await waitFor(() => {
expect(recordDownloadedApp).not.toHaveBeenCalled();
expect(screen.getByTitle("重试")).toBeInTheDocument();
});
await fireEvent.click(screen.getByTitle("重试"));
const successfulCompletion: DownloadResult = {
id: queuedDownload.id,
time: Date.now(),
message: "installed",
success: true,
exitCode: 0,
status: "completed",
origin: "apm",
};
ipcHandlers.get("install-complete")?.({}, successfulCompletion);
await waitFor(() => {
expect(recordDownloadedApp).toHaveBeenCalledTimes(1);
expect(recordDownloadedApp).toHaveBeenCalledWith(
expect.objectContaining({
appKey: "app:office:wps",
pkgname: "wps",
name: "WPS",
category: "office",
selectedOrigin: "apm",
version: "1.0.0",
}),
);
});
});
});