mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 11:40:42 +00:00
test(cli): cover oauth auth epoch continuity
This commit is contained in:
@@ -30,20 +30,42 @@ describe("resolveCliAuthEpoch", () => {
|
||||
).resolves.toBeUndefined();
|
||||
});
|
||||
|
||||
it("changes when claude cli credentials change", async () => {
|
||||
it("keeps claude cli oauth epochs stable across access-token refreshes", async () => {
|
||||
let access = "access-a";
|
||||
let expires = 1;
|
||||
setCliAuthEpochTestDeps({
|
||||
readClaudeCliCredentialsCached: () => ({
|
||||
type: "oauth",
|
||||
provider: "anthropic",
|
||||
access,
|
||||
refresh: "refresh",
|
||||
expires: 1,
|
||||
expires,
|
||||
}),
|
||||
});
|
||||
|
||||
const first = await resolveCliAuthEpoch({ provider: "claude-cli" });
|
||||
access = "access-b";
|
||||
expires = 2;
|
||||
const second = await resolveCliAuthEpoch({ provider: "claude-cli" });
|
||||
|
||||
expect(first).toBeDefined();
|
||||
expect(second).toBe(first);
|
||||
});
|
||||
|
||||
it("changes claude cli oauth epochs when the refresh token changes", async () => {
|
||||
let refresh = "refresh-a";
|
||||
setCliAuthEpochTestDeps({
|
||||
readClaudeCliCredentialsCached: () => ({
|
||||
type: "oauth",
|
||||
provider: "anthropic",
|
||||
access: "access",
|
||||
refresh,
|
||||
expires: 1,
|
||||
}),
|
||||
});
|
||||
|
||||
const first = await resolveCliAuthEpoch({ provider: "claude-cli" });
|
||||
refresh = "refresh-b";
|
||||
const second = await resolveCliAuthEpoch({ provider: "claude-cli" });
|
||||
|
||||
expect(first).toBeDefined();
|
||||
@@ -51,7 +73,7 @@ describe("resolveCliAuthEpoch", () => {
|
||||
expect(second).not.toBe(first);
|
||||
});
|
||||
|
||||
it("changes when auth profile credentials change", async () => {
|
||||
it("keeps oauth auth-profile epochs stable across access-token refreshes", async () => {
|
||||
let store: AuthProfileStore = {
|
||||
version: 1,
|
||||
profiles: {
|
||||
@@ -80,6 +102,48 @@ describe("resolveCliAuthEpoch", () => {
|
||||
provider: "anthropic",
|
||||
access: "access-b",
|
||||
refresh: "refresh",
|
||||
expires: 2,
|
||||
},
|
||||
},
|
||||
};
|
||||
const second = await resolveCliAuthEpoch({
|
||||
provider: "google-gemini-cli",
|
||||
authProfileId: "anthropic:work",
|
||||
});
|
||||
|
||||
expect(first).toBeDefined();
|
||||
expect(second).toBe(first);
|
||||
});
|
||||
|
||||
it("changes oauth auth-profile epochs when the refresh token changes", async () => {
|
||||
let store: AuthProfileStore = {
|
||||
version: 1,
|
||||
profiles: {
|
||||
"anthropic:work": {
|
||||
type: "oauth",
|
||||
provider: "anthropic",
|
||||
access: "access",
|
||||
refresh: "refresh-a",
|
||||
expires: 1,
|
||||
},
|
||||
},
|
||||
};
|
||||
setCliAuthEpochTestDeps({
|
||||
loadAuthProfileStoreForRuntime: () => store,
|
||||
});
|
||||
|
||||
const first = await resolveCliAuthEpoch({
|
||||
provider: "google-gemini-cli",
|
||||
authProfileId: "anthropic:work",
|
||||
});
|
||||
store = {
|
||||
version: 1,
|
||||
profiles: {
|
||||
"anthropic:work": {
|
||||
type: "oauth",
|
||||
provider: "anthropic",
|
||||
access: "access",
|
||||
refresh: "refresh-b",
|
||||
expires: 1,
|
||||
},
|
||||
},
|
||||
@@ -96,13 +160,14 @@ describe("resolveCliAuthEpoch", () => {
|
||||
|
||||
it("mixes local codex and auth-profile state", async () => {
|
||||
let access = "local-access-a";
|
||||
let localRefresh = "local-refresh-a";
|
||||
let refresh = "profile-refresh-a";
|
||||
setCliAuthEpochTestDeps({
|
||||
readCodexCliCredentialsCached: () => ({
|
||||
type: "oauth",
|
||||
provider: "openai-codex",
|
||||
access,
|
||||
refresh: "local-refresh",
|
||||
refresh: localRefresh,
|
||||
expires: 1,
|
||||
accountId: "acct-1",
|
||||
}),
|
||||
@@ -129,17 +194,23 @@ describe("resolveCliAuthEpoch", () => {
|
||||
provider: "codex-cli",
|
||||
authProfileId: "openai:work",
|
||||
});
|
||||
refresh = "profile-refresh-b";
|
||||
localRefresh = "local-refresh-b";
|
||||
const third = await resolveCliAuthEpoch({
|
||||
provider: "codex-cli",
|
||||
authProfileId: "openai:work",
|
||||
});
|
||||
refresh = "profile-refresh-b";
|
||||
const fourth = await resolveCliAuthEpoch({
|
||||
provider: "codex-cli",
|
||||
authProfileId: "openai:work",
|
||||
});
|
||||
|
||||
expect(first).toBeDefined();
|
||||
expect(second).toBeDefined();
|
||||
expect(third).toBeDefined();
|
||||
expect(second).not.toBe(first);
|
||||
expect(fourth).toBeDefined();
|
||||
expect(second).toBe(first);
|
||||
expect(third).not.toBe(second);
|
||||
expect(fourth).not.toBe(third);
|
||||
});
|
||||
|
||||
it("can ignore local codex state when the backend is profile-owned", async () => {
|
||||
|
||||
@@ -55,6 +55,7 @@ function buildPreparedContext(params?: {
|
||||
systemPrompt: "You are a helpful assistant.",
|
||||
systemPromptReport: {} as PreparedCliRunContext["systemPromptReport"],
|
||||
bootstrapPromptWarningLines: [],
|
||||
authEpochVersion: 2,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -111,6 +111,7 @@ function buildPreparedCliRunContext(params: {
|
||||
systemPrompt: "You are a helpful assistant.",
|
||||
systemPromptReport: {} as PreparedCliRunContext["systemPromptReport"],
|
||||
bootstrapPromptWarningLines: [],
|
||||
authEpochVersion: 2,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -170,6 +171,7 @@ describe("runCliAgent spawn path", () => {
|
||||
systemPrompt: "You are a helpful assistant.",
|
||||
systemPromptReport: {} as PreparedCliRunContext["systemPromptReport"],
|
||||
bootstrapPromptWarningLines: [],
|
||||
authEpochVersion: 2,
|
||||
};
|
||||
await executePreparedCliRun(context);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ describe("cli-session helpers", () => {
|
||||
sessionId: "cli-session-1",
|
||||
authProfileId: "anthropic:work",
|
||||
authEpoch: "auth-epoch",
|
||||
authEpochVersion: 2,
|
||||
extraSystemPromptHash: "prompt-hash",
|
||||
mcpConfigHash: "mcp-hash",
|
||||
mcpResumeHash: "mcp-resume-hash",
|
||||
@@ -31,6 +32,7 @@ describe("cli-session helpers", () => {
|
||||
sessionId: "cli-session-1",
|
||||
authProfileId: "anthropic:work",
|
||||
authEpoch: "auth-epoch",
|
||||
authEpochVersion: 2,
|
||||
extraSystemPromptHash: "prompt-hash",
|
||||
mcpConfigHash: "mcp-hash",
|
||||
mcpResumeHash: "mcp-resume-hash",
|
||||
@@ -84,6 +86,7 @@ describe("cli-session helpers", () => {
|
||||
sessionId: "cli-session-1",
|
||||
authProfileId: "anthropic:work",
|
||||
authEpoch: "auth-epoch-a",
|
||||
authEpochVersion: 2,
|
||||
extraSystemPromptHash: "prompt-a",
|
||||
mcpConfigHash: "mcp-a",
|
||||
};
|
||||
@@ -93,6 +96,7 @@ describe("cli-session helpers", () => {
|
||||
binding,
|
||||
authProfileId: "anthropic:personal",
|
||||
authEpoch: "auth-epoch-a",
|
||||
authEpochVersion: 2,
|
||||
extraSystemPromptHash: "prompt-a",
|
||||
mcpConfigHash: "mcp-a",
|
||||
}),
|
||||
@@ -102,6 +106,7 @@ describe("cli-session helpers", () => {
|
||||
binding,
|
||||
authProfileId: "anthropic:work",
|
||||
authEpoch: "auth-epoch-b",
|
||||
authEpochVersion: 2,
|
||||
extraSystemPromptHash: "prompt-a",
|
||||
mcpConfigHash: "mcp-a",
|
||||
}),
|
||||
@@ -111,6 +116,7 @@ describe("cli-session helpers", () => {
|
||||
binding,
|
||||
authProfileId: "anthropic:work",
|
||||
authEpoch: "auth-epoch-a",
|
||||
authEpochVersion: 2,
|
||||
extraSystemPromptHash: "prompt-b",
|
||||
mcpConfigHash: "mcp-a",
|
||||
}),
|
||||
@@ -120,17 +126,18 @@ describe("cli-session helpers", () => {
|
||||
binding,
|
||||
authProfileId: "anthropic:work",
|
||||
authEpoch: "auth-epoch-a",
|
||||
authEpochVersion: 2,
|
||||
extraSystemPromptHash: "prompt-a",
|
||||
mcpConfigHash: "mcp-b",
|
||||
}),
|
||||
).toEqual({ invalidatedReason: "mcp" });
|
||||
});
|
||||
|
||||
it("does not treat model changes as a session mismatch", () => {
|
||||
it("accepts unversioned auth epochs for binding upgrades", () => {
|
||||
const binding = {
|
||||
sessionId: "cli-session-1",
|
||||
authProfileId: "anthropic:work",
|
||||
authEpoch: "auth-epoch-a",
|
||||
authEpoch: "previous-auth-epoch",
|
||||
extraSystemPromptHash: "prompt-a",
|
||||
mcpConfigHash: "mcp-a",
|
||||
};
|
||||
@@ -140,6 +147,29 @@ describe("cli-session helpers", () => {
|
||||
binding,
|
||||
authProfileId: "anthropic:work",
|
||||
authEpoch: "auth-epoch-a",
|
||||
authEpochVersion: 2,
|
||||
extraSystemPromptHash: "prompt-a",
|
||||
mcpConfigHash: "mcp-a",
|
||||
}),
|
||||
).toEqual({ sessionId: "cli-session-1" });
|
||||
});
|
||||
|
||||
it("does not treat model changes as a session mismatch", () => {
|
||||
const binding = {
|
||||
sessionId: "cli-session-1",
|
||||
authProfileId: "anthropic:work",
|
||||
authEpoch: "auth-epoch-a",
|
||||
authEpochVersion: 2,
|
||||
extraSystemPromptHash: "prompt-a",
|
||||
mcpConfigHash: "mcp-a",
|
||||
};
|
||||
|
||||
expect(
|
||||
resolveCliSessionReuse({
|
||||
binding,
|
||||
authProfileId: "anthropic:work",
|
||||
authEpoch: "auth-epoch-a",
|
||||
authEpochVersion: 2,
|
||||
extraSystemPromptHash: "prompt-a",
|
||||
mcpConfigHash: "mcp-a",
|
||||
}),
|
||||
@@ -151,6 +181,7 @@ describe("cli-session helpers", () => {
|
||||
sessionId: "cli-session-1",
|
||||
authProfileId: "anthropic:work",
|
||||
authEpoch: "auth-epoch-a",
|
||||
authEpochVersion: 2,
|
||||
extraSystemPromptHash: "prompt-a",
|
||||
mcpConfigHash: "mcp-config-a",
|
||||
mcpResumeHash: "mcp-resume-a",
|
||||
@@ -161,6 +192,7 @@ describe("cli-session helpers", () => {
|
||||
binding,
|
||||
authProfileId: "anthropic:work",
|
||||
authEpoch: "auth-epoch-a",
|
||||
authEpochVersion: 2,
|
||||
extraSystemPromptHash: "prompt-a",
|
||||
mcpConfigHash: "mcp-config-b",
|
||||
mcpResumeHash: "mcp-resume-a",
|
||||
@@ -171,6 +203,7 @@ describe("cli-session helpers", () => {
|
||||
binding,
|
||||
authProfileId: "anthropic:work",
|
||||
authEpoch: "auth-epoch-a",
|
||||
authEpochVersion: 2,
|
||||
extraSystemPromptHash: "prompt-a",
|
||||
mcpConfigHash: "mcp-config-a",
|
||||
mcpResumeHash: "mcp-resume-b",
|
||||
@@ -183,6 +216,7 @@ describe("cli-session helpers", () => {
|
||||
sessionId: "cli-session-1",
|
||||
authProfileId: "anthropic:work",
|
||||
authEpoch: "auth-epoch-a",
|
||||
authEpochVersion: 2,
|
||||
extraSystemPromptHash: "prompt-a",
|
||||
mcpConfigHash: "mcp-config-a",
|
||||
};
|
||||
@@ -192,6 +226,7 @@ describe("cli-session helpers", () => {
|
||||
binding,
|
||||
authProfileId: "anthropic:work",
|
||||
authEpoch: "auth-epoch-a",
|
||||
authEpochVersion: 2,
|
||||
extraSystemPromptHash: "prompt-a",
|
||||
mcpConfigHash: "mcp-config-a",
|
||||
mcpResumeHash: "mcp-resume-a",
|
||||
@@ -202,6 +237,7 @@ describe("cli-session helpers", () => {
|
||||
binding,
|
||||
authProfileId: "anthropic:work",
|
||||
authEpoch: "auth-epoch-a",
|
||||
authEpochVersion: 2,
|
||||
extraSystemPromptHash: "prompt-a",
|
||||
mcpConfigHash: "mcp-config-b",
|
||||
mcpResumeHash: "mcp-resume-a",
|
||||
|
||||
Reference in New Issue
Block a user