Files
orca/src/main/ssh/ssh-config-resolver.test.ts
T
Neil 019417bd86 refactor(ssh): import the system-ssh and ssh -G modules directly, not through re-export shims (#30255)
Deletes ssh-system-fallback.ts and the re-export lines in ssh-config-parser.ts, ssh-connection.ts,
system-ssh-file-binary-transfer.ts and ssh-remote-powershell.ts; importers name the real modules.
SshConnection tests mock each real module, keeping the parser stub that holds ~/.ssh/config out.
2026-10-18 02:34:30 -07:00

80 lines
2.4 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { resolveWithSshG } from './ssh-g-config-resolution'
import { runProcess } from '@orca/process-host'
vi.mock('os', () => ({
homedir: () => '/home/testuser'
}))
// Why mock the chokepoint and not child_process: the point of routing this
// probe through runProcess is that the spawn shape (windowsHide, timeout,
// argv quoting) is no longer this module's decision, so the test must not
// re-assert it here. @orca/process-host owns that contract.
vi.mock('@orca/process-host', () => ({
runProcess: vi.fn()
}))
const ok = (stdout: string) => ({ code: 0, signal: null, stdout, stderr: '', timedOut: false })
describe('resolveWithSshG', () => {
beforeEach(() => {
vi.mocked(runProcess).mockReset()
})
afterEach(() => {
vi.useRealTimers()
})
it('returns parsed config on success', async () => {
vi.mocked(runProcess).mockResolvedValue(ok('hostname 10.0.0.1\nuser admin\nport 22'))
const result = await resolveWithSshG('myhost')
expect(result).toBeDefined()
expect(result!.hostname).toBe('10.0.0.1')
expect(result!.user).toBe('admin')
})
it('calls ssh -G with the given host under a bounded timeout', async () => {
vi.mocked(runProcess).mockResolvedValue(ok('hostname example.com\nport 22'))
await resolveWithSshG('testserver')
expect(runProcess).toHaveBeenCalledWith({
program: 'ssh',
args: ['-G', '--', 'testserver'],
timeoutMs: 5000
})
})
it('returns null when ssh -G fails', async () => {
vi.mocked(runProcess).mockResolvedValue({
code: 255,
signal: null,
stdout: '',
stderr: 'ssh not found',
timedOut: false
})
expect(await resolveWithSshG('myhost')).toBeNull()
})
it('returns null when ssh -G could not be started', async () => {
vi.mocked(runProcess).mockRejectedValue(new Error('ENOENT'))
expect(await resolveWithSshG('myhost')).toBeNull()
})
it('returns null when ssh -G never reports completion', async () => {
// Why not fake timers any more: the deadline is runProcess's, and it
// reports the outcome as data rather than by leaving the promise pending.
vi.mocked(runProcess).mockResolvedValue({
code: null,
signal: 'SIGTERM',
stdout: '',
stderr: '',
timedOut: true
})
expect(await resolveWithSshG('stuck-host')).toBeNull()
})
})