mirror of
https://github.com/stablyai/orca.git
synced 2026-10-18 16:03:17 +00:00
Pin WSL-gate and same-token short-circuit for legacy keychain retry
The legacy-keychain retry must never answer a WSL target with the host user's keychain account, and must not double the usage request when the legacy item mirrors the failed scoped token. Add tests locking both.
This commit is contained in:
@@ -276,6 +276,71 @@ describe('fetchClaudeRateLimits', () => {
|
||||
expect(readActiveClaudeKeychainCredentialsStrict).not.toHaveBeenCalledWith(undefined)
|
||||
})
|
||||
|
||||
it('does not retry with the legacy keychain for WSL targets', async () => {
|
||||
// Why: a WSL target's stale credentials must never be answered with the
|
||||
// host user's legacy macOS Keychain account.
|
||||
const configDir = '\\\\wsl$\\Ubuntu\\home\\test\\.claude'
|
||||
const authPreparation: ClaudeRuntimeAuthPreparation = {
|
||||
configDir,
|
||||
runtime: 'wsl',
|
||||
wslDistro: 'Ubuntu',
|
||||
wslLinuxConfigDir: '/home/test/.claude',
|
||||
envPatch: { CLAUDE_CONFIG_DIR: '/home/test/.claude' },
|
||||
stripAuthEnv: false,
|
||||
provenance: 'system'
|
||||
}
|
||||
vi.mocked(readActiveClaudeKeychainCredentialsStrict).mockImplementation(async (dir) =>
|
||||
dir
|
||||
? JSON.stringify({ claudeAiOauth: { accessToken: 'stale-wsl-token' } })
|
||||
: JSON.stringify({ claudeAiOauth: { accessToken: 'fresh-legacy-token' } })
|
||||
)
|
||||
netFetchMock.mockResolvedValue(
|
||||
new Response(JSON.stringify({ error: { message: 'Invalid authentication credentials' } }), {
|
||||
status: 401
|
||||
})
|
||||
)
|
||||
|
||||
await expect(
|
||||
fetchClaudeRateLimits({ authPreparation, allowPtyFallback: false })
|
||||
).resolves.toMatchObject({
|
||||
provider: 'claude',
|
||||
status: 'error'
|
||||
})
|
||||
|
||||
expect(netFetchMock).toHaveBeenCalledTimes(1)
|
||||
expect(readActiveClaudeKeychainCredentialsStrict).not.toHaveBeenCalledWith(undefined)
|
||||
})
|
||||
|
||||
it('skips the legacy retry when the legacy item mirrors the failed scoped token', async () => {
|
||||
// Why: Claude's usage endpoint has a tight request budget; retrying the
|
||||
// identical token would double the request for a guaranteed second 401.
|
||||
const configDir = '/Users/test/.claude'
|
||||
const authPreparation: ClaudeRuntimeAuthPreparation = {
|
||||
configDir,
|
||||
envPatch: { CLAUDE_CONFIG_DIR: configDir },
|
||||
stripAuthEnv: false,
|
||||
provenance: 'system'
|
||||
}
|
||||
vi.mocked(readActiveClaudeKeychainCredentialsStrict).mockResolvedValue(
|
||||
JSON.stringify({ claudeAiOauth: { accessToken: 'mirrored-token' } })
|
||||
)
|
||||
netFetchMock.mockResolvedValue(
|
||||
new Response(JSON.stringify({ error: { message: 'Invalid authentication credentials' } }), {
|
||||
status: 401
|
||||
})
|
||||
)
|
||||
|
||||
await expect(
|
||||
fetchClaudeRateLimits({ authPreparation, allowPtyFallback: false })
|
||||
).resolves.toMatchObject({
|
||||
provider: 'claude',
|
||||
status: 'error'
|
||||
})
|
||||
|
||||
expect(netFetchMock).toHaveBeenCalledTimes(1)
|
||||
expect(readActiveClaudeKeychainCredentialsStrict).toHaveBeenCalledWith(undefined)
|
||||
})
|
||||
|
||||
it('accepts Claude Code statusline-style rate limit window fields', async () => {
|
||||
const configDir = '/Users/test/.claude'
|
||||
const authPreparation: ClaudeRuntimeAuthPreparation = {
|
||||
|
||||
Reference in New Issue
Block a user