From 5de8fe2a34ac8a6a06bee712269458d78350964e Mon Sep 17 00:00:00 2001 From: Janghoon Lee <44862514+savagemanage@users.noreply.github.com> Date: Mon, 21 Sep 2026 15:31:30 +0000 Subject: [PATCH] fix(test): isolate the XDG data directory so a real login cannot leak into core tests Three ModelsDev tests were green in CI and red on any developer machine where somebody had run `redrob providers login`. They clear `REDROB_API_KEY` and then assert the static fallback catalog is served -- but `resolveApiKey()` reads THREE sources in order: that env var, the Integration store, and `auth.json` under `Global.Path.data`. The suite stubs the second and clears the first. The third was the developer's own credential. So the service found a key, fetched, and returned the live listing's figures -- `limit.output: 64000` where the fallback publishes `32000`. The assertion was reporting the difference between two catalogues rather than the thing it claims to check, and nothing in the test named the variable it depended on. `XDG_DATA_HOME` is pointed at a fresh temp directory in the preload, which is early enough: `Global.Path.data` is computed once at module load, so redirecting it afterwards is impossible -- the suite's own `REDROB_TEST_HOME` seam is a getter and covers `home` only, not the data directory where credentials live. Fixed in the test setup rather than by adding a seam to production code. Nothing about the CLI's real path resolution is wrong, and `XDG_DATA_HOME` is the standard way to say where that directory is. Verified by removing only the isolation: exactly those three fail again, and nothing else in the 974 does. --- packages/core/test/preload.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/core/test/preload.ts b/packages/core/test/preload.ts index ba28a8ea03..6d945b0282 100644 --- a/packages/core/test/preload.ts +++ b/packages/core/test/preload.ts @@ -1,3 +1,28 @@ +import fs from "fs/promises" +import os from "os" +import path from "path" + +/* + Isolate the XDG data directory BEFORE anything imports `global.ts`. + + `Global.Path.data` is computed once at module load from `xdgData`, and `auth.json` lives there. The + suite's own `home` seam (`REDROB_TEST_HOME`) does not cover it, so the ModelsDev "no key" tests -- + which clear `REDROB_API_KEY` and then assert the static fallback is served -- still found a real + credential on any machine where somebody had run `redrob providers login`. `resolveApiKey()` reads + three sources in order: the env var, the Integration store, and this file. The tests stub the second + and clear the first. + + The result was three tests that passed in CI, where no profile exists, and failed on a developer's own + machine -- reporting the live catalogue's figures (`limit.output: 64000`) instead of the fallback's + (`32000`). A test that is green only because the environment happens to be empty is not testing what + it says it is, and the variable it depends on is invisible from the assertion. + + Set here rather than given a new seam in production code: nothing about the CLI's real path resolution + is wrong, and `XDG_DATA_HOME` is the standard way to say where that directory is. +*/ +const dataDir = await fs.mkdtemp(path.join(os.tmpdir(), "redrob-core-test-data-")) +process.env.XDG_DATA_HOME = dataDir + process.env.REDROB_DB = ":memory:" // Gate the console /models fetch off so core tests stay offline/deterministic; the // ModelsDev.Service then serves the static console fallback catalog (redrob/auto and the rest of