Track installer downloads by platform via license server API.

Fire-and-forget POST on Platforms download clicks with tests and configurable tracking URL.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ivan Fontosh
2026-07-02 00:21:22 +08:00
parent 1110b3e533
commit 9013fa0b49
6 changed files with 114 additions and 4 deletions
+47
View File
@@ -0,0 +1,47 @@
import assert from "node:assert/strict";
import { afterEach, describe, it, mock } from "node:test";
import {
DEFAULT_LICENSE_TRACKING_BASE,
resolveTrackDownloadUrl,
trackDownload,
} from "./trackDownload";
describe("trackDownload", () => {
afterEach(() => {
mock.restoreAll();
});
it("builds default tracking URL", () => {
assert.equal(
resolveTrackDownloadUrl(DEFAULT_LICENSE_TRACKING_BASE),
"https://license.ttrpgplayer.ru/v1/track/download",
);
});
it("normalizes base URL without trailing slash", () => {
assert.equal(
resolveTrackDownloadUrl("https://license.example.test"),
"https://license.example.test/v1/track/download",
);
});
it("POSTs platform with keepalive and swallows errors", async () => {
const fetchMock = mock.fn(() => Promise.reject(new Error("network down")));
globalThis.fetch = fetchMock;
trackDownload("macos");
await new Promise((resolve) => setTimeout(resolve, 0));
assert.equal(fetchMock.mock.calls.length, 1);
const call = fetchMock.mock.calls[0];
assert.ok(call);
const [url, init] = call.arguments as unknown as [string, RequestInit];
assert.equal(url, "https://license.ttrpgplayer.ru/v1/track/download");
assert.equal(init.method, "POST");
assert.equal(init.keepalive, true);
assert.deepEqual(init.headers, { "Content-Type": "application/json" });
assert.equal(init.body, JSON.stringify({ platform: "macos" }));
});
});