完善桌面端端到端回归收口
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const checkForDesktopUpdateMock = vi.hoisted(() => vi.fn());
|
||||
const installPendingDesktopUpdateMock = vi.hoisted(() => vi.fn());
|
||||
const isDesktopUpdaterAvailableMock = vi.hoisted(() => vi.fn());
|
||||
const messageErrorMock = vi.hoisted(() => vi.fn());
|
||||
const confirmMock = vi.hoisted(() => vi.fn());
|
||||
|
||||
vi.mock("../runtime", () => ({
|
||||
checkForDesktopUpdate: checkForDesktopUpdateMock,
|
||||
installPendingDesktopUpdate: installPendingDesktopUpdateMock,
|
||||
isDesktopUpdaterAvailable: isDesktopUpdaterAvailableMock,
|
||||
}));
|
||||
|
||||
vi.mock("element-plus", () => ({
|
||||
ElMessage: {
|
||||
error: messageErrorMock,
|
||||
},
|
||||
ElMessageBox: {
|
||||
confirm: confirmMock,
|
||||
},
|
||||
}));
|
||||
|
||||
const createStorage = (): Storage => {
|
||||
const data = new Map<string, string>();
|
||||
return {
|
||||
get length() {
|
||||
return data.size;
|
||||
},
|
||||
clear: vi.fn(() => data.clear()),
|
||||
getItem: vi.fn((key: string) => data.get(key) ?? null),
|
||||
key: vi.fn((index: number) => Array.from(data.keys())[index] ?? null),
|
||||
removeItem: vi.fn((key: string) => data.delete(key)),
|
||||
setItem: vi.fn((key: string, value: string) => data.set(key, value)),
|
||||
};
|
||||
};
|
||||
|
||||
const update = {
|
||||
version: "0.1.1",
|
||||
currentVersion: "0.1.0",
|
||||
notes: "桌面端稳定化",
|
||||
date: "2026-07-02",
|
||||
};
|
||||
|
||||
describe("desktop update manager", () => {
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date("2026-07-02T00:00:00.000Z"));
|
||||
vi.resetModules();
|
||||
vi.clearAllMocks();
|
||||
Object.defineProperty(window, "localStorage", {
|
||||
value: createStorage(),
|
||||
configurable: true,
|
||||
});
|
||||
isDesktopUpdaterAvailableMock.mockReturnValue(true);
|
||||
checkForDesktopUpdateMock.mockResolvedValue(null);
|
||||
installPendingDesktopUpdateMock.mockResolvedValue(undefined);
|
||||
confirmMock.mockResolvedValue(undefined);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
const { stopDesktopUpdateManager } = await import("./desktopUpdateManager");
|
||||
stopDesktopUpdateManager();
|
||||
vi.clearAllTimers();
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it("records up-to-date checks without prompting", async () => {
|
||||
const { checkDesktopUpdateAndPrompt, getDesktopUpdateStatus } = await import("./desktopUpdateManager");
|
||||
|
||||
const status = await checkDesktopUpdateAndPrompt({ notifyWhenCurrent: true, promptWhenAvailable: true });
|
||||
|
||||
expect(status).toBe("up-to-date");
|
||||
expect(confirmMock).not.toHaveBeenCalled();
|
||||
expect(getDesktopUpdateStatus()).toMatchObject({
|
||||
lastStatus: "up-to-date",
|
||||
pendingUpdate: null,
|
||||
lastError: "",
|
||||
});
|
||||
});
|
||||
|
||||
it("suppresses the same postponed version for 24 hours", async () => {
|
||||
checkForDesktopUpdateMock.mockResolvedValue(update);
|
||||
confirmMock.mockRejectedValueOnce("cancel");
|
||||
const { checkDesktopUpdateAndPrompt, getDesktopUpdateStatus } = await import("./desktopUpdateManager");
|
||||
|
||||
const postponed = await checkDesktopUpdateAndPrompt({ promptWhenAvailable: true });
|
||||
const postponedStatus = getDesktopUpdateStatus();
|
||||
const suppressed = await checkDesktopUpdateAndPrompt({ promptWhenAvailable: true });
|
||||
|
||||
expect(postponed).toBe("postponed");
|
||||
expect(suppressed).toBe("suppressed");
|
||||
expect(confirmMock).toHaveBeenCalledTimes(1);
|
||||
expect(installPendingDesktopUpdateMock).not.toHaveBeenCalled();
|
||||
expect(postponedStatus.postponedUntil).toBe("2026-07-03T00:00:00.000Z");
|
||||
expect(getDesktopUpdateStatus()).toMatchObject({
|
||||
lastStatus: "suppressed",
|
||||
pendingUpdate: update,
|
||||
postponedUntil: "2026-07-03T00:00:00.000Z",
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps a pending update retryable when installation fails", async () => {
|
||||
checkForDesktopUpdateMock.mockResolvedValue(update);
|
||||
installPendingDesktopUpdateMock.mockRejectedValueOnce(new Error("install failed"));
|
||||
const { checkDesktopUpdateAndPrompt, getDesktopUpdateStatus } = await import("./desktopUpdateManager");
|
||||
|
||||
const status = await checkDesktopUpdateAndPrompt({ promptWhenAvailable: true });
|
||||
|
||||
expect(status).toBe("failed");
|
||||
expect(messageErrorMock).toHaveBeenCalledWith("桌面端更新安装失败,请稍后重试或联系管理员。");
|
||||
expect(getDesktopUpdateStatus()).toMatchObject({
|
||||
installing: false,
|
||||
lastStatus: "failed",
|
||||
lastError: "桌面端更新安装失败",
|
||||
pendingUpdate: update,
|
||||
});
|
||||
});
|
||||
|
||||
it("does not interrupt timed update checks when checking fails", async () => {
|
||||
checkForDesktopUpdateMock.mockRejectedValueOnce(new Error("feed unavailable"));
|
||||
const { checkDesktopUpdateAndPrompt, getDesktopUpdateStatus } = await import("./desktopUpdateManager");
|
||||
|
||||
const status = await checkDesktopUpdateAndPrompt();
|
||||
|
||||
expect(status).toBe("failed");
|
||||
expect(messageErrorMock).not.toHaveBeenCalled();
|
||||
expect(getDesktopUpdateStatus()).toMatchObject({
|
||||
lastStatus: "failed",
|
||||
lastError: "feed unavailable",
|
||||
});
|
||||
});
|
||||
|
||||
it("reports disabled updater builds explicitly", async () => {
|
||||
isDesktopUpdaterAvailableMock.mockReturnValue(false);
|
||||
const { checkDesktopUpdateAndPrompt, getDesktopUpdateStatus } = await import("./desktopUpdateManager");
|
||||
|
||||
const status = await checkDesktopUpdateAndPrompt({ notifyWhenCurrent: true });
|
||||
|
||||
expect(status).toBe("disabled");
|
||||
expect(checkForDesktopUpdateMock).not.toHaveBeenCalled();
|
||||
expect(getDesktopUpdateStatus()).toMatchObject({
|
||||
available: false,
|
||||
lastStatus: "disabled",
|
||||
pendingUpdate: null,
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user