Skip to content

Commit 5fb1733

Browse files
committed
test: cover login selection persistence helpers
1 parent 9e0e10b commit 5fb1733

2 files changed

Lines changed: 50 additions & 0 deletions

File tree

lib/auth/login-runner.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,15 @@ export function applyAccountSelectionFallbacks(
146146
};
147147
}
148148

149+
/**
150+
* Persists the already-resolved selection through the caller's
151+
* `persistSelections` callback. Windows filesystem safety remains delegated to
152+
* that callback, so callers should use `persistAccountPool` or
153+
* `withAccountStorageTransaction` to keep the rename retry and serialized
154+
* read-modify-write behavior covered by `test/login-runner.test.ts`.
155+
* This helper does not log token material; callers must redact any callback
156+
* failure details before emitting logs.
157+
*/
149158
export async function persistResolvedAccountSelection(
150159
selection: AccountSelectionResult,
151160
options?: {
@@ -164,6 +173,15 @@ export async function persistResolvedAccountSelection(
164173
return selection;
165174
}
166175

176+
/**
177+
* Finalizes a resolved selection by delegating persistence to the caller's
178+
* `persistSelections` callback. Windows lock-retry and read-modify-write
179+
* serialization remain the callback's responsibility, so callers should route
180+
* through `persistAccountPool` or `withAccountStorageTransaction` to preserve
181+
* the guarantees covered by `test/login-runner.test.ts`.
182+
* This helper does not log tokens or account identifiers; callers must redact
183+
* callback failures before logging them.
184+
*/
167185
export async function resolveAndPersistAccountSelection(
168186
tokens: TokenSuccess,
169187
options?: {

test/login-runner.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
55
import {
66
applyAccountSelectionFallbacks,
77
persistAccountPool,
8+
persistResolvedAccountSelection,
89
resolveAccountSelection,
910
resolveAndPersistAccountSelection,
1011
type TokenSuccessWithAccount,
@@ -150,4 +151,35 @@ describe("login-runner selection finalization", () => {
150151
expect(persistSelections).toHaveBeenCalledTimes(1);
151152
expect(persistSelections).toHaveBeenCalledWith(result.variantsForPersistence, true);
152153
});
154+
155+
it("returns the selection unchanged when no persist callback is provided", async () => {
156+
const selection = resolveAccountSelection({
157+
type: "success",
158+
access: "access-token",
159+
refresh: "refresh-token",
160+
expires: Date.now() + 60_000,
161+
idToken: "id-token",
162+
});
163+
164+
await expect(persistResolvedAccountSelection(selection)).resolves.toBe(selection);
165+
});
166+
167+
it("propagates persist callback failures", async () => {
168+
const selection = resolveAccountSelection({
169+
type: "success",
170+
access: "access-token",
171+
refresh: "refresh-token",
172+
expires: Date.now() + 60_000,
173+
idToken: "id-token",
174+
});
175+
const persistError = new Error("persist failed");
176+
const persistSelections = vi.fn(async () => {
177+
throw persistError;
178+
});
179+
180+
await expect(
181+
persistResolvedAccountSelection(selection, { persistSelections }),
182+
).rejects.toThrow("persist failed");
183+
expect(persistSelections).toHaveBeenCalledTimes(1);
184+
});
153185
});

0 commit comments

Comments
 (0)