Finder-launched terminals now inherit a login PATH so tools like ollama resolve, destructive SFTP/editor actions require confirmation, and terminal search plus window dragging work again. SSH forwards and RDP sessions keep listeners and survive reconnect without FastPath crashes. Co-authored-by: Cursor <cursoragent@cursor.com>
91 lines
3.1 KiB
TypeScript
91 lines
3.1 KiB
TypeScript
/**
|
|
* SSH session / terminal open patrol
|
|
*/
|
|
|
|
import { render, screen, waitFor } from '@testing-library/react'
|
|
import userEvent from '@testing-library/user-event'
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import SessionDialog from '../../src/components/sessions/SessionDialog'
|
|
import QuickConnectDialog, { parseSshTarget } from '../../src/components/sessions/QuickConnectDialog'
|
|
import { useSessionStore } from '../../src/stores/sessionStore'
|
|
import { useTabStore } from '../../src/stores/tabStore'
|
|
import { mockDesktopApi } from '../setup'
|
|
import { resetPatrolStores, SSH_SESSION } from '../helpers/patrol'
|
|
import { buildOpenTabPayload } from '../../src/utils/sessionProtocol'
|
|
|
|
describe('patrol / ssh', () => {
|
|
beforeEach(() => {
|
|
resetPatrolStores()
|
|
})
|
|
|
|
it('parses ssh targets used by quick connect', () => {
|
|
expect(parseSshTarget('admin@10.0.0.8:2222')).toEqual({
|
|
host: '10.0.0.8',
|
|
port: 2222,
|
|
username: 'admin',
|
|
})
|
|
expect(parseSshTarget('opsbase.cn')).toEqual({
|
|
host: 'opsbase.cn',
|
|
port: 22,
|
|
username: 'root',
|
|
})
|
|
})
|
|
|
|
it('creates an SSH session with default port 22 and password auth', async () => {
|
|
const user = userEvent.setup()
|
|
render(<SessionDialog isOpen onClose={vi.fn()} editSession={null} />)
|
|
|
|
expect(screen.getByLabelText('端口')).toHaveValue(22)
|
|
await user.clear(screen.getByLabelText('主机'))
|
|
await user.type(screen.getByLabelText('主机'), 'root@opsbase.cn')
|
|
await user.type(screen.getByLabelText('密码'), 'patrol-secret')
|
|
await user.click(screen.getByRole('button', { name: '创建并保存' }))
|
|
|
|
await waitFor(() => {
|
|
expect(mockDesktopApi.sessionCreate).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
host: 'opsbase.cn',
|
|
port: 22,
|
|
username: 'root',
|
|
authType: 'password',
|
|
password: 'patrol-secret',
|
|
})
|
|
)
|
|
})
|
|
})
|
|
|
|
it('opens a terminal tab from a saved SSH session payload', () => {
|
|
const payload = buildOpenTabPayload(SSH_SESSION)
|
|
useTabStore.getState().addTab(payload)
|
|
const tab = useTabStore.getState().tabs.find((item) => item.sessionId === SSH_SESSION.id)
|
|
expect(tab).toEqual(
|
|
expect.objectContaining({
|
|
type: 'terminal',
|
|
sessionId: SSH_SESSION.id,
|
|
})
|
|
)
|
|
})
|
|
|
|
it('quick-connect opens a terminal tab for user@host:port', async () => {
|
|
const user = userEvent.setup()
|
|
render(<QuickConnectDialog isOpen onClose={vi.fn()} />)
|
|
|
|
const input = screen.getByRole('textbox')
|
|
await user.clear(input)
|
|
await user.type(input, 'admin@10.0.0.8:2222')
|
|
await user.type(screen.getByPlaceholderText('••••••••'), 'x')
|
|
await user.click(screen.getByRole('button', { name: /连接/ }))
|
|
|
|
await waitFor(() => {
|
|
const tabs = useTabStore.getState().tabs
|
|
expect(tabs.some((tab) => tab.type === 'terminal')).toBe(true)
|
|
})
|
|
})
|
|
|
|
it('keeps SSH sessions in the session store', () => {
|
|
useSessionStore.setState({ sessions: [SSH_SESSION] })
|
|
expect(useSessionStore.getState().sessions).toHaveLength(1)
|
|
expect(useSessionStore.getState().sessions[0].protocol ?? 'ssh').toBe('ssh')
|
|
})
|
|
})
|