From 460e07cab0b342a4fb8c0e4f85b747e13e5c9ee1 Mon Sep 17 00:00:00 2001 From: JUN Date: Sun, 13 Sep 2026 12:24:15 +0900 Subject: [PATCH] test(devin-cli): anchor the empty-data-dir fallback at the host home Carry #4384 from fdba29bc1ae1cf262430764221312d729476a551 onto the current dev tip. The empty-XDG_DATA_HOME case asserted the resolved path starts with "/", which is false on a Windows runner: devinCliCredentialsPath picks path.win32 or path.posix from its platform ARGUMENT, but the fallback joins the HOST homedir(), so asking about "linux" from Windows yields C:\Users\/.local/share/devin/credentials.toml. Anchor both crossings at that home directory instead, normalising through win32.join for the win32 branch so a POSIX host home compares against the same separators. Anchoring, not a leading slash, is what proves the path is not cwd-relative, which is the defect the test exists to pin. The surviving endsWith assertions and the startsWith("devin") === false check still prove it. Production behaviour is unchanged; this is test-only. Local product tests, typecheck, build and install: NOT RUN. Hosted exact-head CI on this PR is the merge proof. Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com> --- tests/providers/devin-cli-login.test.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/providers/devin-cli-login.test.ts b/tests/providers/devin-cli-login.test.ts index 766e28eca2..5871a8ae08 100644 --- a/tests/providers/devin-cli-login.test.ts +++ b/tests/providers/devin-cli-login.test.ts @@ -1,4 +1,6 @@ import { describe, expect, test } from "bun:test"; +import { homedir } from "node:os"; +import { win32 } from "node:path"; import { DEVIN_CLI_CREDENTIALS_ENV, devinCliCredentialsPath, @@ -149,13 +151,21 @@ describe("devin-cli credential path and read bounds", () => { // directory the proxy was started in, and a planted file there would import // as the operator's own CLI session. // The fallback reads the real home directory rather than env.HOME, so the - // assertion is on shape: absolute, and under the home data dir. + // assertion is on shape: anchored at that home directory, and under its data + // dir. Anchoring is what proves the path is not cwd-relative; asserting a + // leading "/" instead would only hold when the HOST is POSIX, because + // `homedir()` returns `C:\\Users\\` on Windows no matter which + // platform the resolver is asked about. for (const empty of ["", " "]) { const resolved = devinCliCredentialsPath({ HOME: "/home/u", XDG_DATA_HOME: empty }, "linux"); - expect(resolved.startsWith("/")).toBe(true); + expect(resolved.startsWith(homedir())).toBe(true); expect(resolved.endsWith("/.local/share/devin/credentials.toml")).toBe(true); } const win = devinCliCredentialsPath({ APPDATA: "" }, "win32"); + // The win32 branch joins with win32 separators, so a POSIX host home such as + // `/Users/runner` comes back as `\\Users\\runner`. Normalize the anchor the + // same way rather than comparing a host-shaped string against it. + expect(win.startsWith(win32.join(homedir()))).toBe(true); expect(win.endsWith("AppData\\Roaming\\devin\\credentials.toml")).toBe(true); expect(win.startsWith("devin")).toBe(false); });