Files
orca/src/main/ssh/ssh-connection-store.test.ts

142 lines
4.1 KiB
TypeScript

import { describe, expect, it, vi, beforeEach } from 'vitest'
import { SshConnectionStore } from './ssh-connection-store'
import type { SshTarget } from '../../shared/ssh-types'
const { loadUserSshConfigMock, sshConfigHostsToTargetsMock } = vi.hoisted(() => ({
loadUserSshConfigMock: vi.fn(),
sshConfigHostsToTargetsMock: vi.fn()
}))
vi.mock('./ssh-config-parser', () => ({
loadUserSshConfig: loadUserSshConfigMock,
sshConfigHostsToTargets: sshConfigHostsToTargetsMock
}))
function createMockStore() {
const targets: SshTarget[] = []
return {
getSshTargets: vi.fn(() => [...targets]),
getSshTarget: vi.fn((id: string) => targets.find((t) => t.id === id)),
addSshTarget: vi.fn((target: SshTarget) => targets.push(target)),
updateSshTarget: vi.fn((id: string, updates: Partial<Omit<SshTarget, 'id'>>) => {
const target = targets.find((t) => t.id === id)
if (!target) {
return null
}
Object.assign(target, updates)
return { ...target }
}),
removeSshTarget: vi.fn((id: string) => {
const idx = targets.findIndex((t) => t.id === id)
if (idx !== -1) {
targets.splice(idx, 1)
}
})
}
}
describe('SshConnectionStore', () => {
let mockStore: ReturnType<typeof createMockStore>
let sshStore: SshConnectionStore
beforeEach(() => {
mockStore = createMockStore()
sshStore = new SshConnectionStore(mockStore as never)
loadUserSshConfigMock.mockReset()
sshConfigHostsToTargetsMock.mockReset()
})
it('listTargets delegates to store', () => {
sshStore.listTargets()
expect(mockStore.getSshTargets).toHaveBeenCalled()
})
it('getTarget delegates to store', () => {
sshStore.getTarget('test-id')
expect(mockStore.getSshTarget).toHaveBeenCalledWith('test-id')
})
it('addTarget generates an id and persists', () => {
const target = sshStore.addTarget({
label: 'My Server',
host: 'example.com',
port: 22,
username: 'deploy'
})
expect(target.id).toMatch(/^ssh-/)
expect(target.label).toBe('My Server')
expect(mockStore.addSshTarget).toHaveBeenCalledWith(target)
})
it('updateTarget delegates to store', () => {
const original: SshTarget = {
id: 'ssh-1',
label: 'Old Name',
host: 'example.com',
port: 22,
username: 'user'
}
mockStore.addSshTarget(original)
const result = sshStore.updateTarget('ssh-1', { label: 'New Name' })
expect(result).toBeTruthy()
expect(mockStore.updateSshTarget).toHaveBeenCalledWith('ssh-1', { label: 'New Name' })
})
it('removeTarget delegates to store', () => {
sshStore.removeTarget('ssh-1')
expect(mockStore.removeSshTarget).toHaveBeenCalledWith('ssh-1')
})
describe('importFromSshConfig', () => {
it('imports new hosts from SSH config', () => {
const configHosts = [{ host: 'staging', hostname: 'staging.example.com' }]
const newTargets: SshTarget[] = [
{
id: 'ssh-new-1',
label: 'staging',
host: 'staging.example.com',
port: 22,
username: ''
}
]
loadUserSshConfigMock.mockReturnValue(configHosts)
sshConfigHostsToTargetsMock.mockReturnValue(newTargets)
const result = sshStore.importFromSshConfig()
expect(result).toEqual(newTargets)
expect(mockStore.addSshTarget).toHaveBeenCalledWith(newTargets[0])
})
it('passes existing target labels to avoid duplicates', () => {
const existing: SshTarget = {
id: 'ssh-existing',
label: 'production',
host: 'prod.example.com',
port: 22,
username: 'deploy'
}
mockStore.addSshTarget(existing)
loadUserSshConfigMock.mockReturnValue([])
sshConfigHostsToTargetsMock.mockReturnValue([])
sshStore.importFromSshConfig()
expect(sshConfigHostsToTargetsMock).toHaveBeenCalledWith([], new Set(['production']))
})
it('returns empty array when no new hosts found', () => {
loadUserSshConfigMock.mockReturnValue([])
sshConfigHostsToTargetsMock.mockReturnValue([])
const result = sshStore.importFromSshConfig()
expect(result).toEqual([])
})
})
})