fix(cli): make telemetry opt-out durable (#2852)

* fix(cli): make telemetry opt-out durable

* fix(cli): make telemetry status trustworthy
This commit is contained in:
Miguel Ángel
2026-07-28 20:35:54 +02:00
committed by GitHub
parent c691869e22
commit 880021411d
13 changed files with 491 additions and 52 deletions
@@ -130,6 +130,7 @@ async function checkWith(registryVersion: unknown): Promise<{
const writes: Array<Record<string, unknown>> = [];
vi.doMock("../telemetry/config.js", () => ({
readConfig: () => ({}),
readConfigFresh: () => ({}),
writeConfig: (c: Record<string, unknown>) => writes.push({ ...c }),
}));
const origFetch = globalThis.fetch;
@@ -150,6 +151,49 @@ async function checkWith(registryVersion: unknown): Promise<{
}
}
async function checkAcrossConcurrentConfigWrite(): Promise<Record<string, unknown>> {
vi.resetModules();
const initial = {
telemetryEnabled: true,
anonymousId: "test-install",
telemetryNoticeShown: true,
commandCount: 0,
renderSuccessCount: 0,
lastFeedbackPromptAt: 0,
};
let persisted: Record<string, unknown> = { ...initial };
vi.doMock("../telemetry/config.js", () => ({
readConfig: () => ({ ...initial }),
readConfigFresh: () => ({ ...persisted }),
writeConfig: (config: Record<string, unknown>) => {
persisted = { ...config };
return true;
},
}));
const origFetch = globalThis.fetch;
let releaseResponse: (() => void) | undefined;
const responseReady = new Promise<void>((resolve) => {
releaseResponse = resolve;
});
globalThis.fetch = (async () => {
await responseReady;
return {
ok: true,
json: async () => ({ version: "9.9.9" }),
};
}) as unknown as typeof fetch;
try {
const mod = await import("./updateCheck.js");
const check = mod.checkForUpdate(true);
persisted = { ...persisted, telemetryEnabled: false };
releaseResponse?.();
await check;
return persisted;
} finally {
globalThis.fetch = origFetch;
}
}
/**
* U5: validate/inspect/layout are deprecated in favor of `check`. withMeta's
* optional `{ deprecated: true }` is the single place that adds `_meta.deprecated`
@@ -236,4 +280,12 @@ describe("checkForUpdate — registry boundary guard", () => {
expect(typeof latest).toBe("string");
expect(wroteVersion).toBeUndefined();
});
it("merges update metadata into a fresh snapshot without re-enabling telemetry", async () => {
const persisted = await checkAcrossConcurrentConfigWrite();
expect(persisted).toMatchObject({
telemetryEnabled: false,
latestVersion: "9.9.9",
});
});
});