mirror of
https://github.com/CloakHQ/CloakBrowser.git
synced 2026-06-23 11:41:46 +02:00
feat: add wrapper version update checks for PyPI and npm
Check for newer wrapper versions on startup (once per process). Python queries PyPI, JS queries npm registry. Respects CLOAKBROWSER_AUTO_UPDATE=false and CLOAKBROWSER_DOWNLOAD_URL (custom mirror mode skips external registry calls). Includes unit tests for both languages covering: update detection, env var gating, network error handling, and once-per-process guard.
This commit is contained in:
+86
-2
@@ -1,4 +1,4 @@
|
||||
import { describe, it, expect, vi, afterEach } from "vitest";
|
||||
import { describe, it, expect, vi, afterEach, beforeEach } from "vitest";
|
||||
import {
|
||||
CHROMIUM_VERSION,
|
||||
getChromiumVersion,
|
||||
@@ -8,7 +8,12 @@ import {
|
||||
parseVersion,
|
||||
versionNewer,
|
||||
} from "../src/config.js";
|
||||
import { getLatestChromiumVersion, parseChecksums } from "../src/download.js";
|
||||
import {
|
||||
checkWrapperUpdate,
|
||||
getLatestChromiumVersion,
|
||||
parseChecksums,
|
||||
resetWrapperUpdateChecked,
|
||||
} from "../src/download.js";
|
||||
|
||||
describe("version comparison", () => {
|
||||
it("parseVersion handles 4-part versions", () => {
|
||||
@@ -149,6 +154,85 @@ describe("latest version (platform-aware)", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("wrapper update check", () => {
|
||||
beforeEach(() => {
|
||||
resetWrapperUpdateChecked();
|
||||
delete process.env.CLOAKBROWSER_AUTO_UPDATE;
|
||||
delete process.env.CLOAKBROWSER_DOWNLOAD_URL;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
delete process.env.CLOAKBROWSER_AUTO_UPDATE;
|
||||
delete process.env.CLOAKBROWSER_DOWNLOAD_URL;
|
||||
});
|
||||
|
||||
it("warns when newer version available", async () => {
|
||||
const spy = vi.spyOn(globalThis, "fetch").mockResolvedValue({
|
||||
ok: true,
|
||||
json: async () => ({ version: "99.0.0" }),
|
||||
} as Response);
|
||||
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
|
||||
await checkWrapperUpdate();
|
||||
|
||||
expect(spy).toHaveBeenCalledOnce();
|
||||
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining("Update available"));
|
||||
});
|
||||
|
||||
it("silent when current version", async () => {
|
||||
const { WRAPPER_VERSION } = await import("../src/config.js");
|
||||
vi.spyOn(globalThis, "fetch").mockResolvedValue({
|
||||
ok: true,
|
||||
json: async () => ({ version: WRAPPER_VERSION }),
|
||||
} as Response);
|
||||
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
|
||||
await checkWrapperUpdate();
|
||||
|
||||
expect(warnSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("disabled by CLOAKBROWSER_AUTO_UPDATE=false", async () => {
|
||||
process.env.CLOAKBROWSER_AUTO_UPDATE = "false";
|
||||
const spy = vi.spyOn(globalThis, "fetch");
|
||||
|
||||
await checkWrapperUpdate();
|
||||
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("disabled by CLOAKBROWSER_DOWNLOAD_URL", async () => {
|
||||
process.env.CLOAKBROWSER_DOWNLOAD_URL = "https://mirror.example.com";
|
||||
const spy = vi.spyOn(globalThis, "fetch");
|
||||
|
||||
await checkWrapperUpdate();
|
||||
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("silent on network error", async () => {
|
||||
vi.spyOn(globalThis, "fetch").mockRejectedValue(new Error("timeout"));
|
||||
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
|
||||
await checkWrapperUpdate();
|
||||
|
||||
expect(warnSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("runs only once per process", async () => {
|
||||
const spy = vi.spyOn(globalThis, "fetch").mockResolvedValue({
|
||||
ok: true,
|
||||
json: async () => ({ version: "0.0.1" }),
|
||||
} as Response);
|
||||
|
||||
await checkWrapperUpdate();
|
||||
await checkWrapperUpdate();
|
||||
|
||||
expect(spy).toHaveBeenCalledOnce();
|
||||
});
|
||||
});
|
||||
|
||||
describe("parseChecksums", () => {
|
||||
// Valid 64-char hex strings for testing
|
||||
const HASH_A = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
|
||||
|
||||
Reference in New Issue
Block a user