Files
simstudioai--sim/apps/sim/lib/copilot/vfs/workflow-aliases.test.ts
T
wehub-resource-sync d25d482dc2
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:20:55 +08:00

140 lines
4.8 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import {
buildWorkflowAliasWorkflowEntries,
isWorkflowAliasBackingPath,
resolveWorkflowAliasPath,
resolveWorkspacePlanAliasPath,
workflowChangelogBackingPath,
workspacePlanBackingPath,
} from './workflow-aliases'
describe('workflow aliases', () => {
const folders = [
{ folderId: 'root-a', folderName: 'Folder A', parentId: null },
{ folderId: 'nested', folderName: 'Nested', parentId: 'root-a' },
{ folderId: 'root-b', folderName: 'Folder B', parentId: null },
]
it('resolves root workspace plan aliases to workspace backing files', () => {
const alias = resolveWorkspacePlanAliasPath('.plans/root.md')
expect(alias).toMatchObject({
kind: 'plan_file',
scope: 'workspace',
aliasPath: '.plans/root.md',
planRelativePath: 'root.md',
backingPath: workspacePlanBackingPath('root.md'),
})
})
it('preserves nested root workspace plan paths in backing storage', () => {
const alias = resolveWorkspacePlanAliasPath('.plans/nested/phase-1.md')
expect(alias).toMatchObject({
kind: 'plan_file',
scope: 'workspace',
planRelativePath: 'nested/phase-1.md',
backingPath: 'files/.plans/workspace/nested/phase-1.md',
})
})
it('rejects root plan directory paths as file aliases', () => {
expect(resolveWorkspacePlanAliasPath('.plans')).toMatchObject({
kind: 'plans_dir',
scope: 'workspace',
})
expect(resolveWorkspacePlanAliasPath('.plans/.folder')).toMatchObject({
kind: 'plans_dir',
scope: 'workspace',
})
expect(resolveWorkspacePlanAliasPath('.plans/links.json')).toBeNull()
})
it('resolves root workflow changelog aliases to workflow-id keyed backing files', () => {
const workflows = buildWorkflowAliasWorkflowEntries(
[{ id: 'wf_123', name: 'Root Flow', folderId: null }],
[]
)
const alias = resolveWorkflowAliasPath('workflows/Root%20Flow/changelog.md', workflows)
expect(alias).toMatchObject({
kind: 'changelog',
workflowId: 'wf_123',
aliasPath: 'workflows/Root%20Flow/changelog.md',
backingPath: workflowChangelogBackingPath('wf_123'),
})
})
it('resolves nested plan aliases using the workflow folder path', () => {
const workflows = buildWorkflowAliasWorkflowEntries(
[{ id: 'wf_nested', name: 'Planner', folderId: 'nested' }],
folders
)
const alias = resolveWorkflowAliasPath(
'workflows/Folder%20A/Nested/Planner/.plans/launch.md',
workflows
)
expect(alias).toMatchObject({
kind: 'plan_file',
workflowId: 'wf_nested',
planRelativePath: 'launch.md',
backingPath: 'files/.plans/wf_nested/launch.md',
})
})
it('keeps same-name workflows in different folders distinct', () => {
const workflows = buildWorkflowAliasWorkflowEntries(
[
{ id: 'wf_a', name: 'Duplicate', folderId: 'root-a' },
{ id: 'wf_b', name: 'Duplicate', folderId: 'root-b' },
],
folders
)
expect(
resolveWorkflowAliasPath('workflows/Folder%20A/Duplicate/changelog.md', workflows)
).toMatchObject({ workflowId: 'wf_a', backingPath: 'files/.changelogs/wf_a.md' })
expect(
resolveWorkflowAliasPath('workflows/Folder%20B/Duplicate/changelog.md', workflows)
).toMatchObject({ workflowId: 'wf_b', backingPath: 'files/.changelogs/wf_b.md' })
})
it('keeps backing paths stable across workflow rename', () => {
const before = buildWorkflowAliasWorkflowEntries(
[{ id: 'wf_stable', name: 'Old Name', folderId: null }],
[]
)
const after = buildWorkflowAliasWorkflowEntries(
[{ id: 'wf_stable', name: 'New Name', folderId: null }],
[]
)
expect(resolveWorkflowAliasPath('workflows/Old%20Name/changelog.md', before)?.backingPath).toBe(
'files/.changelogs/wf_stable.md'
)
expect(resolveWorkflowAliasPath('workflows/New%20Name/changelog.md', after)?.backingPath).toBe(
'files/.changelogs/wf_stable.md'
)
expect(resolveWorkflowAliasPath('workflows/Old%20Name/changelog.md', after)).toBeNull()
})
it('rejects arbitrary workflow-local files and missing workflows', () => {
const workflows = buildWorkflowAliasWorkflowEntries(
[{ id: 'wf_123', name: 'Root Flow', folderId: null }],
[]
)
expect(resolveWorkflowAliasPath('workflows/Root%20Flow/random.md', workflows)).toBeNull()
expect(resolveWorkflowAliasPath('workflows/Missing/changelog.md', workflows)).toBeNull()
})
it('recognizes reserved backing paths after VFS segment canonicalization', () => {
expect(isWorkflowAliasBackingPath('files/.plans/wf_1/launch.md')).toBe(true)
expect(isWorkflowAliasBackingPath('files/%2Eplans/wf_1/launch.md')).toBe(true)
expect(isWorkflowAliasBackingPath('files/ordinary/launch.md')).toBe(false)
})
})