Files
orca/src/main/runtime/runtime-server-environment-commands.test.ts
T
NeilandGideon c8ad8ea313 fix(projects): list symlinked folders as folders in the remote Add Project browser (#29658)
A symlink to a directory was listed as a file on SSH and managed hosts, so
projects behind a linked path could not be reached. Follow links when
classifying entries; broken links and loops stay files.

Co-authored-by: Gideon <jjin6573@naver.com>
2026-10-16 05:21:44 -07:00

57 lines
2.3 KiB
TypeScript

import { mkdir, mkdtemp, rm, symlink, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
import { RuntimeServerEnvironmentCommands } from './runtime-server-environment-commands'
const dirLinkType = process.platform === 'win32' ? 'junction' : 'dir'
describe('RuntimeServerEnvironmentCommands.browseDirectory', () => {
let root: string
beforeEach(async () => {
root = await mkdtemp(join(tmpdir(), 'orca-server-browse-symlink-'))
})
afterEach(async () => {
await rm(root, { recursive: true, force: true })
})
it.skipIf(process.platform === 'win32')(
'lists a symlinked directory as a directory and keeps broken links and loops as files',
async () => {
await mkdir(join(root, 'real-dir'))
await writeFile(join(root, 'real-file.txt'), 'x\n')
await symlink(join(root, 'real-dir'), join(root, 'linked-dir'), dirLinkType)
await symlink(join(root, 'real-file.txt'), join(root, 'linked-file'))
await symlink(join(root, 'missing-target'), join(root, 'broken-link'))
await symlink(join(root, 'loop-b'), join(root, 'loop-a'))
await symlink(join(root, 'loop-a'), join(root, 'loop-b'))
const result = await new RuntimeServerEnvironmentCommands().browseDirectory(root)
expect(result.entries).toEqual([
{ name: 'linked-dir', isDirectory: true, isSymlink: true },
{ name: 'real-dir', isDirectory: true, isSymlink: false },
{ name: 'broken-link', isDirectory: false, isSymlink: true },
{ name: 'linked-file', isDirectory: false, isSymlink: true },
{ name: 'loop-a', isDirectory: false, isSymlink: true },
{ name: 'loop-b', isDirectory: false, isSymlink: true },
{ name: 'real-file.txt', isDirectory: false, isSymlink: false }
])
}
)
it('navigates into a symlinked directory', async () => {
await mkdir(join(root, 'real-dir', 'project'), { recursive: true })
await symlink(join(root, 'real-dir'), join(root, 'linked-dir'), dirLinkType)
const result = await new RuntimeServerEnvironmentCommands().browseDirectory(
join(root, 'linked-dir')
)
expect(result.resolvedPath).toBe(join(root, 'linked-dir'))
expect(result.entries).toEqual([{ name: 'project', isDirectory: true, isSymlink: false }])
})
})