test: close Claude shared auth migration coverage

This commit is contained in:
Merge Sim
2026-08-31 22:11:36 -07:00
parent c424d4065a
commit 6d13dc2bbf
@@ -8,14 +8,19 @@ import {
migrateLegacySharedClaudeAuth
} from './legacy-shared-claude-auth-migration'
const ownership = vi.hoisted(() => ({
resolve: (_id: string, path: string): string | null => path
}))
vi.mock('./managed-auth-path', () => ({
resolveOwnedClaudeManagedAuthPath: (_id: string, path: string) => path
resolveOwnedClaudeManagedAuthPath: (id: string, path: string) => ownership.resolve(id, path)
}))
let root: string
beforeEach(() => {
root = mkdtempSync(join(tmpdir(), 'orca-claude-migration-'))
ownership.resolve = (_id, path) => path
})
afterEach(() => {
@@ -98,6 +103,123 @@ describe('legacy shared Claude auth migration', () => {
expect(writeManagedCredentials).not.toHaveBeenCalled()
expect(fixture.marker()).toMatchObject({ outcome: 'already-present' })
})
it('refuses an untrusted account home without reading or mutating the shared store', async () => {
const fixture = createFixture()
const readLegacyKeychain = vi.fn(async () => fixture.shared)
const writeManagedCredentials = vi.fn(async () => {})
ownership.resolve = () => null
const outcome = await fixture.migrate({ readLegacyKeychain, writeManagedCredentials })
expect(outcome).toBe('unavailable')
expect(readLegacyKeychain).not.toHaveBeenCalled()
expect(writeManagedCredentials).not.toHaveBeenCalled()
expect(existsSync(fixture.markerPath)).toBe(false)
})
it('migrates the active account even when another account home is stale or deleted', async () => {
const fixture = createFixture()
const stale = {
...fixture.account,
id: 'account-2',
email: 'other@example.com',
managedAuthPath: join(root, 'account-2', 'auth')
}
ownership.resolve = (id, path) => (id === stale.id ? null : path)
const writeManagedCredentials = vi.fn(async () => {})
const outcome = await fixture.migrate({
accounts: [fixture.account, stale],
readLegacyOauthAccount: () => ({ emailAddress: 'user@example.com' }),
writeManagedCredentials
})
expect(outcome).toBe('migrated')
expect(writeManagedCredentials).toHaveBeenCalledWith(fixture.account, fixture.shared)
expect(fixture.marker()).toMatchObject({ outcome: 'migrated', accountId: fixture.account.id })
})
it('keeps a deleted-home duplicate identity in the ambiguity gate', async () => {
const fixture = createFixture()
const duplicate = {
...fixture.account,
id: 'account-2',
managedAuthPath: join(root, 'account-2', 'auth')
}
ownership.resolve = (id, path) => (id === duplicate.id ? null : path)
const writeManagedCredentials = vi.fn(async () => {})
const outcome = await fixture.migrate({
accounts: [fixture.account, duplicate],
readLegacyOauthAccount: () => ({ emailAddress: 'user@example.com' }),
writeManagedCredentials
})
expect(outcome).toBe('ambiguous')
expect(writeManagedCredentials).not.toHaveBeenCalled()
expect(existsSync(fixture.markerPath)).toBe(false)
})
it('never clobbers a newer per-account credential', async () => {
const fixture = createFixture()
const newer = JSON.stringify({ claudeAiOauth: { accessToken: 'newer-token' } })
const writeManagedCredentials = vi.fn(async () => {})
const outcome = await fixture.migrate({
readLegacyOauthAccount: () => ({ emailAddress: 'user@example.com' }),
readManagedCredentials: async () => newer,
writeManagedCredentials
})
expect(outcome).toBe('already-present')
expect(writeManagedCredentials).not.toHaveBeenCalled()
expect(fixture.marker()).toMatchObject({
outcome: 'already-present',
accountId: fixture.account.id
})
})
it('is a full no-op once the generation marker is present', async () => {
const fixture = createFixture()
mkdirSync(join(root, 'metadata'), { recursive: true })
writeFileSync(
fixture.markerPath,
`${JSON.stringify({ version: 1, completedAt: 1, outcome: 'migrated', accountId: fixture.account.id })}\n`,
'utf-8'
)
const readLegacyKeychain = vi.fn(async () => fixture.shared)
const readLegacyOauthAccount = vi.fn(() => ({ emailAddress: 'user@example.com' }))
const readManagedCredentials = vi.fn(async () => null)
const writeManagedCredentials = vi.fn(async () => {})
const outcome = await fixture.migrate({
readLegacyKeychain,
readLegacyOauthAccount,
readManagedCredentials,
writeManagedCredentials
})
expect(outcome).toBe('already-present')
expect(readLegacyKeychain).not.toHaveBeenCalled()
expect(readLegacyOauthAccount).not.toHaveBeenCalled()
expect(readManagedCredentials).not.toHaveBeenCalled()
expect(writeManagedCredentials).not.toHaveBeenCalled()
})
it('never leaks the shared store to a non-matching account', async () => {
const fixture = createFixture()
const writeManagedCredentials = vi.fn(async () => {})
const outcome = await fixture.migrate({
readLegacyOauthAccount: () => ({ emailAddress: 'other@example.com' }),
writeManagedCredentials
})
expect(outcome).toBe('ambiguous')
expect(writeManagedCredentials).not.toHaveBeenCalled()
expect(existsSync(fixture.markerPath)).toBe(false)
})
})
function createFixture() {