Files
przeprogramowani__10x-cli/tests/auth-command.test.ts
“mkczarkowski” a0832349f0 fix(windows-compatibility): cross-platform config isolation in tests
On Windows, configDir() reads APPDATA, not XDG_CONFIG_HOME. Tests that
only redirected XDG_CONFIG_HOME leaked config state across test files,
causing failures on windows-latest CI. Extract redirectConfigDir/
restoreConfigDir helper that sets both env vars, apply across all 10
test files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-09 15:31:02 +02:00

84 lines
2.3 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it } from "bun:test";
import { existsSync, mkdtempSync, readFileSync, rmSync, statSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import {
AUTH_FILE_VERSION,
type AuthData,
authFilePath,
deleteAuth,
isAuthenticated,
saveAuth,
} from "../src/lib/config";
import { redirectConfigDir, restoreConfigDir } from "./helpers/config-isolation";
let tmp: string;
beforeEach(() => {
tmp = mkdtempSync(join(tmpdir(), "10x-cli-auth-cmd-"));
redirectConfigDir(tmp);
});
afterEach(() => {
restoreConfigDir();
rmSync(tmp, { recursive: true, force: true });
});
function writeFutureAuth(): AuthData {
const data: AuthData = {
version: AUTH_FILE_VERSION,
email: "student@example.com",
access_token: "jwt-1",
refresh_token: "rt-1",
expires_at: new Date(Date.now() + 7 * 24 * 60 * 60 * 1_000).toISOString(),
created_at: new Date().toISOString(),
};
saveAuth(data);
return data;
}
describe("auth file lifecycle", () => {
it("saveAuth writes mode 0o600 inside the configured XDG dir", () => {
writeFutureAuth();
const file = authFilePath();
expect(existsSync(file)).toBe(true);
expect(file.startsWith(tmp)).toBe(true);
if (process.platform !== "win32") {
const mode = statSync(file).mode & 0o777;
expect(mode).toBe(0o600);
}
const round = JSON.parse(readFileSync(file, "utf8")) as AuthData;
expect(round.email).toBe("student@example.com");
expect(round.version).toBe(AUTH_FILE_VERSION);
});
it("isAuthenticated reflects expiry", () => {
writeFutureAuth();
expect(isAuthenticated()).toBe(true);
});
it("deleteAuth wipes the credentials file", () => {
writeFutureAuth();
expect(existsSync(authFilePath())).toBe(true);
deleteAuth();
expect(existsSync(authFilePath())).toBe(false);
// Idempotent
deleteAuth();
});
it("isAuthenticated returns false for an expired token", () => {
const data: AuthData = {
version: AUTH_FILE_VERSION,
email: "student@example.com",
access_token: "jwt-old",
refresh_token: "rt-old",
expires_at: new Date(Date.now() - 1_000).toISOString(),
created_at: new Date().toISOString(),
};
saveAuth(data);
expect(isAuthenticated()).toBe(false);
});
});