Files
opsxshell/test/components/connection/forwardIntent.test.ts
T
Logan.LiandCursor 08696896f9 feat: harden local shell, SFTP, and desktop session reliability
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>
2026-08-16 16:08:11 +08:00

136 lines
3.9 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from 'vitest'
import {
clearForwardIntent,
forgetForwardIntent,
forwardIntentKey,
listForwardIntent,
rememberForwardIntent,
resetForwardIntentForTests,
restoreForwardIntent,
tunnelCoversRule,
} from '../../../src/components/connection/forwardIntent'
import type { ForwardRule } from '../../../src/components/connection/forwardRules'
import type { SSHForwardStatus } from '../../../shared/types/ipc.types'
const localRule: ForwardRule = {
id: 'pf-local',
type: 'local',
name: 'db',
localPort: 3306,
remoteHost: '127.0.0.1',
remotePort: 3306,
}
function tunnel(overrides: Partial<SSHForwardStatus> = {}): SSHForwardStatus {
return {
forwardId: 'pf-local',
connectionId: 'conn-1',
kind: 'local',
bindHost: '127.0.0.1',
boundPort: 3306,
startedAt: 1,
running: true,
activeConnections: 0,
bytesUp: 0,
bytesDown: 0,
...overrides,
}
}
afterEach(() => {
resetForwardIntentForTests()
})
describe('forward reconnect intent', () => {
it('keys by session so a new connection id does not drop remembered rules', () => {
expect(forwardIntentKey('sess-1', 'tab-1')).toBe('session:sess-1')
expect(forwardIntentKey(undefined, 'tab-1')).toBe('tab:tab-1')
})
it('remembers start intent and forgets explicit stop', () => {
const key = forwardIntentKey('sess-1', 'tab-1')
rememberForwardIntent(key, localRule)
expect(listForwardIntent(key)).toEqual([localRule])
forgetForwardIntent(key, localRule.id)
expect(listForwardIntent(key)).toEqual([])
})
it('matches a running tunnel by rule id or listen port after reconnect', () => {
expect(tunnelCoversRule([tunnel()], localRule)).toBe(true)
expect(
tunnelCoversRule([tunnel({ forwardId: 'legacy', boundPort: 3306 })], localRule)
).toBe(true)
expect(
tunnelCoversRule([tunnel({ running: false })], localRule)
).toBe(false)
})
it('matches remote forwards by remote listen port, not local target port', () => {
const remoteRule: ForwardRule = {
id: 'pf-remote',
type: 'remote',
name: 'expose',
localPort: 8080,
remoteHost: '127.0.0.1',
remotePort: 18080,
}
expect(
tunnelCoversRule(
[tunnel({ forwardId: 'x', kind: 'remote', boundPort: 18080 })],
remoteRule
)
).toBe(true)
expect(
tunnelCoversRule(
[tunnel({ forwardId: 'x', kind: 'remote', boundPort: 8080 })],
remoteRule
)
).toBe(false)
})
it('clears remembered intent when a tab is disposed', () => {
const key = forwardIntentKey('sess-1', 'tab-1')
rememberForwardIntent(key, localRule)
clearForwardIntent(key)
expect(listForwardIntent(key)).toEqual([])
})
it('restores only rules that are not already running', async () => {
const key = forwardIntentKey('sess-1', 'tab-1')
rememberForwardIntent(key, localRule)
rememberForwardIntent(key, { ...localRule, id: 'pf-other', localPort: 8080 })
const start = vi.fn().mockResolvedValue(true)
const restored = await restoreForwardIntent(
key,
(rule) => rule.id === 'pf-local',
start
)
expect(restored).toBe(1)
expect(start).toHaveBeenCalledTimes(1)
expect(start).toHaveBeenCalledWith(expect.objectContaining({ id: 'pf-other' }))
})
it('shares one restore pass when StatusBar and PortForwardView race', async () => {
const key = forwardIntentKey('sess-1', 'tab-1')
rememberForwardIntent(key, localRule)
let release!: (value: boolean) => void
const start = vi.fn(
() =>
new Promise<boolean>((resolve) => {
release = resolve
})
)
const first = restoreForwardIntent(key, () => false, start)
const second = restoreForwardIntent(key, () => false, start)
release(true)
await expect(first).resolves.toBe(1)
await expect(second).resolves.toBe(1)
expect(start).toHaveBeenCalledTimes(1)
})
})