257 lines · 8.5 KB · TypeScript
RawDownload
import { describe, expect, it } from "vite-plus/test"; import {  createInitialDesktopUpdateState,  reduceDesktopUpdateStateOnCheckFailure,  reduceDesktopUpdateStateOnCheckStart,  reduceDesktopUpdateStateOnDownloadComplete,  reduceDesktopUpdateStateOnDownloadFailure,  reduceDesktopUpdateStateOnDownloadProgress,  reduceDesktopUpdateStateOnDownloadStart,  reduceDesktopUpdateStateOnInstallFailure,  reduceDesktopUpdateStateOnNoUpdate,  reduceDesktopUpdateStateOnUpdateAvailable,} from "./updateMachine.ts"; const runtimeInfo = {  hostArch: "x64",  appArch: "x64",  runningUnderArm64Translation: false,} as const; describe("updateMachine", () => {  it("clears transient errors when a check starts", () => {    const state = reduceDesktopUpdateStateOnCheckStart(      {        ...createInitialDesktopUpdateState("1.0.0", runtimeInfo, "latest"),        enabled: true,        status: "error",        message: "network",        errorContext: "check",        canRetry: true,      },      "2026-03-04T00:00:00.000Z",    );     expect(state.status).toBe("checking");    expect(state.message).toBeNull();    expect(state.errorContext).toBeNull();    expect(state.canRetry).toBe(false);  });   it("records a check failure without exposing an action", () => {    const state = reduceDesktopUpdateStateOnCheckFailure(      {        ...createInitialDesktopUpdateState("1.0.0", runtimeInfo, "latest"),        enabled: true,        status: "checking",      },      "network unavailable",      "2026-03-04T00:00:00.000Z",    );     expect(state.status).toBe("error");    expect(state.errorContext).toBe("check");    expect(state.canRetry).toBe(true);  });   it("preserves an already-downloaded update while checking the feed", () => {    const downloadedState = {      ...createInitialDesktopUpdateState("1.0.0", runtimeInfo, "latest"),      enabled: true,      status: "downloaded" as const,      availableVersion: "1.1.0",      downloadedVersion: "1.1.0",      releaseNotes: [{ version: "1.1.0", items: ["fix: queued update"], totalItems: 1 }],      omittedReleaseCount: 2,      downloadPercent: 100,    };    const checking = reduceDesktopUpdateStateOnCheckStart(      downloadedState,      "2026-03-04T00:00:00.000Z",    );    const failed = reduceDesktopUpdateStateOnCheckFailure(      checking,      "network unavailable",      "2026-03-04T00:00:01.000Z",    );     expect(checking.status).toBe("checking");    expect(checking.downloadedVersion).toBe("1.1.0");    expect(checking.releaseNotes).toEqual(downloadedState.releaseNotes);    expect(checking.omittedReleaseCount).toBe(2);    expect(failed.status).toBe("downloaded");    expect(failed.downloadedVersion).toBe("1.1.0");    expect(failed.releaseNotes).toEqual(downloadedState.releaseNotes);    expect(failed.omittedReleaseCount).toBe(2);    expect(failed.message).toBeNull();  });   it("keeps the installer when the feed still offers its version", () => {    const releaseNotes = [{ version: "1.1.0", items: ["fix: queued update"], totalItems: 1 }];    const state = reduceDesktopUpdateStateOnUpdateAvailable(      {        ...createInitialDesktopUpdateState("1.0.0", runtimeInfo, "latest"),        enabled: true,        status: "downloaded",        availableVersion: "1.1.0",        downloadedVersion: "1.1.0",        releaseNotes,        omittedReleaseCount: 2,        downloadPercent: 100,      },      "1.1.0",      "2026-03-04T00:00:00.000Z",    );     expect(state.status).toBe("downloaded");    expect(state.downloadedVersion).toBe("1.1.0");    expect(state.releaseNotes).toEqual(releaseNotes);    expect(state.omittedReleaseCount).toBe(2);    expect(state.downloadPercent).toBe(100);  });   it("preserves available version on download failure for retry", () => {    const state = reduceDesktopUpdateStateOnDownloadFailure(      {        ...createInitialDesktopUpdateState("1.0.0", runtimeInfo, "latest"),        enabled: true,        status: "downloading",        availableVersion: "1.1.0",        downloadPercent: 43,      },      "checksum mismatch",    );     expect(state.status).toBe("available");    expect(state.availableVersion).toBe("1.1.0");    expect(state.errorContext).toBe("download");    expect(state.canRetry).toBe(true);  });   it("transitions to downloaded and then preserves install retry state", () => {    const downloaded = reduceDesktopUpdateStateOnDownloadComplete(      {        ...createInitialDesktopUpdateState("1.0.0", runtimeInfo, "latest"),        enabled: true,        status: "downloading",        availableVersion: "1.1.0",      },      "1.1.0",    );    const failedInstall = reduceDesktopUpdateStateOnInstallFailure(      downloaded,      "backend shutdown timed out",    );     expect(downloaded.status).toBe("downloaded");    expect(downloaded.downloadedVersion).toBe("1.1.0");    expect(failedInstall.status).toBe("downloaded");    expect(failedInstall.errorContext).toBe("install");    expect(failedInstall.canRetry).toBe(true);  });   it("preserves a downloaded update when no update is available", () => {    const releaseNotes = [{ version: "1.1.0", items: ["fix: queued update"], totalItems: 1 }];    const state = reduceDesktopUpdateStateOnNoUpdate(      {        ...createInitialDesktopUpdateState("1.0.0", runtimeInfo, "latest"),        enabled: true,        status: "error",        availableVersion: "1.1.0",        downloadedVersion: "1.1.0",        releaseNotes,        omittedReleaseCount: 2,        message: "old failure",        errorContext: "download",        canRetry: true,      },      "2026-03-04T00:00:00.000Z",    );     expect(state.status).toBe("downloaded");    expect(state.availableVersion).toBe("1.1.0");    expect(state.downloadedVersion).toBe("1.1.0");    expect(state.releaseNotes).toBe(releaseNotes);    expect(state.omittedReleaseCount).toBe(2);    expect(state.downloadPercent).toBe(100);    expect(state.message).toBeNull();    expect(state.errorContext).toBeNull();    expect(state.canRetry).toBe(true);  });   it("clears stale available state when no update is available", () => {    const state = reduceDesktopUpdateStateOnNoUpdate(      {        ...createInitialDesktopUpdateState("1.0.0", runtimeInfo, "latest"),        enabled: true,        status: "error",        availableVersion: "1.1.0",        releaseNotes: [{ version: "1.1.0", items: ["fix: stale update"], totalItems: 1 }],        omittedReleaseCount: 2,        message: "old failure",        errorContext: "download",        canRetry: true,      },      "2026-03-04T00:00:00.000Z",    );     expect(state.status).toBe("up-to-date");    expect(state.availableVersion).toBeNull();    expect(state.downloadedVersion).toBeNull();    expect(state.releaseNotes).toEqual([]);    expect(state.omittedReleaseCount).toBe(0);    expect(state.message).toBeNull();    expect(state.errorContext).toBeNull();  });   it("tracks available, download start, and progress cleanly", () => {    const releaseNotes = [      {        version: "1.1.0",        items: ["feat: add update release notes"],        totalItems: 1,      },    ];    const available = reduceDesktopUpdateStateOnUpdateAvailable(      {        ...createInitialDesktopUpdateState("1.0.0", runtimeInfo, "latest"),        enabled: true,        status: "checking",      },      "1.1.0",      "2026-03-04T00:00:00.000Z",      releaseNotes,      2,    );    const downloading = reduceDesktopUpdateStateOnDownloadStart(available);    const progress = reduceDesktopUpdateStateOnDownloadProgress(downloading, 55.5);     expect(available.status).toBe("available");    expect(available.channel).toBe("latest");    expect(available.releaseNotes).toBe(releaseNotes);    expect(available.omittedReleaseCount).toBe(2);    expect(downloading.releaseNotes).toBe(releaseNotes);    expect(downloading.status).toBe("downloading");    expect(downloading.downloadPercent).toBe(0);    expect(progress.downloadPercent).toBe(55.5);    expect(progress.errorContext).toBeNull();  });   it("clears release notes when checking again", () => {    const state = reduceDesktopUpdateStateOnCheckStart(      {        ...createInitialDesktopUpdateState("1.0.0", runtimeInfo, "nightly"),        enabled: true,        status: "available",        availableVersion: "1.1.0-nightly.1",        releaseNotes: [{ version: "1.1.0-nightly.1", items: ["feat: old note"], totalItems: 1 }],        omittedReleaseCount: 2,      },      "2026-03-04T00:00:00.000Z",    );     expect(state.releaseNotes).toEqual([]);    expect(state.omittedReleaseCount).toBe(0);  });});