| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- import { describe, expect, test } from "bun:test"
- import { createUpdaterController, type UpdaterBackend, type UpdaterReadyRecord } from "./updater-controller"
- function setup(input?: { currentVersion?: string; ready?: UpdaterReadyRecord }) {
- const calls: string[] = []
- const backend: UpdaterBackend = {
- async checkForUpdates() {
- calls.push("check")
- return { isUpdateAvailable: true, updateInfo: { version: "2.0.0" } }
- },
- async downloadUpdate() {
- calls.push("download")
- },
- quitAndInstall() {
- calls.push("install")
- },
- }
- let ready = input?.ready
- const controller = createUpdaterController({
- enabled: true,
- currentVersion: input?.currentVersion ?? "1.0.0",
- backend,
- persistence: {
- get: () => ready,
- set: (value) => {
- ready = value
- },
- clear: () => {
- ready = undefined
- },
- },
- stop: async () => {
- calls.push("stop")
- },
- })
- return { controller, calls, getReady: () => ready }
- }
- describe("updater controller", () => {
- test("checks, downloads, persists, and publishes one authoritative ready state", async () => {
- const app = setup()
- const states: ReturnType<typeof app.controller.getState>[] = []
- app.controller.subscribe((state) => states.push(state))
- await app.controller.start()
- expect(app.calls).toEqual(["check", "download"])
- expect(app.getReady()).toEqual({ version: "2.0.0" })
- expect(states.map((state) => state.status)).toEqual(["idle", "checking", "downloading", "ready"])
- expect(app.controller.getState()).toEqual({ status: "ready", version: "2.0.0" })
- })
- test("revalidates a persisted target through the updater cache on launch", async () => {
- const app = setup({ ready: { version: "2.0.0" } })
- await app.controller.start()
- expect(app.calls).toEqual(["check", "download"])
- expect(app.controller.getState()).toEqual({ status: "ready", version: "2.0.0" })
- })
- test("clears a target already installed before checking", async () => {
- const app = setup({ currentVersion: "2.0.0", ready: { version: "2.0.0" } })
- await app.controller.start()
- expect(app.getReady()).toBeUndefined()
- expect(app.calls).toEqual(["check"])
- })
- test("coalesces concurrent checks", async () => {
- const app = setup()
- await Promise.all([app.controller.check(), app.controller.check(), app.controller.check()])
- expect(app.calls).toEqual(["check", "download"])
- })
- test("returns to ready when quitAndInstall returns without exiting", async () => {
- const app = setup()
- await app.controller.start()
- await app.controller.install()
- expect(app.calls).toEqual(["check", "download", "stop", "install"])
- expect(app.controller.getState()).toEqual({ status: "ready", version: "2.0.0" })
- })
- test("returns to ready when installation cannot start", async () => {
- const app = setup()
- await app.controller.start()
- const failed = createUpdaterController({
- enabled: true,
- currentVersion: "1.0.0",
- backend: {
- checkForUpdates: async () => ({ isUpdateAvailable: true, updateInfo: { version: "2.0.0" } }),
- downloadUpdate: async () => {},
- quitAndInstall() {},
- },
- persistence: { get: () => undefined, set() {}, clear() {} },
- stop: async () => {
- throw new Error("stop failed")
- },
- })
- await failed.start()
- await expect(failed.install()).rejects.toThrow("stop failed")
- expect(failed.getState()).toEqual({ status: "ready", version: "2.0.0" })
- })
- })
|