mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
291 lines
9.1 KiB
TypeScript
291 lines
9.1 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import {
|
|
LOCAL_EXECUTION_HOST_ID,
|
|
toRuntimeExecutionHostId,
|
|
toSshExecutionHostId
|
|
} from './execution-host'
|
|
import {
|
|
areTaskSourceContextsEqual,
|
|
buildTaskSourceContextFromRepo,
|
|
buildWorkspaceRunContext,
|
|
getTaskSourceCacheScope,
|
|
getTaskSourceRuntimeSettings,
|
|
normalizeStoredTaskSourceContext,
|
|
normalizeTaskSourceContext,
|
|
runtimeHostIdFromEnvironmentId,
|
|
type TaskSourceContext
|
|
} from './task-source-context'
|
|
import { TaskSourceContextSchema } from './task-source-context-schema'
|
|
|
|
describe('task source context', () => {
|
|
it('defaults source context to the local host', () => {
|
|
expect(
|
|
normalizeTaskSourceContext({
|
|
provider: 'github',
|
|
projectId: ' project-1 ',
|
|
providerIdentity: { provider: 'github', owner: 'stablyai', repo: 'orca' }
|
|
})
|
|
).toEqual({
|
|
kind: 'task-source',
|
|
provider: 'github',
|
|
projectId: 'project-1',
|
|
hostId: 'local',
|
|
projectHostSetupId: null,
|
|
repoId: null,
|
|
providerIdentity: { provider: 'github', owner: 'stablyai', repo: 'orca' },
|
|
accountLabel: null
|
|
})
|
|
})
|
|
|
|
it('uses repo execution ownership when building a source context', () => {
|
|
expect(
|
|
buildTaskSourceContextFromRepo({
|
|
provider: 'github',
|
|
projectId: 'project-1',
|
|
repo: {
|
|
id: 'repo-1',
|
|
connectionId: 'ssh target',
|
|
executionHostId: null
|
|
}
|
|
})?.hostId
|
|
).toBe(toSshExecutionHostId('ssh target'))
|
|
|
|
expect(
|
|
buildTaskSourceContextFromRepo({
|
|
provider: 'github',
|
|
projectId: 'project-1',
|
|
repo: {
|
|
id: 'repo-1',
|
|
connectionId: 'ssh target',
|
|
executionHostId: toRuntimeExecutionHostId('remote-runtime')
|
|
}
|
|
})?.hostId
|
|
).toBe(toRuntimeExecutionHostId('remote-runtime'))
|
|
})
|
|
|
|
it('derives runtime settings only for runtime-owned task sources', () => {
|
|
expect(
|
|
getTaskSourceRuntimeSettings({
|
|
hostId: toRuntimeExecutionHostId('remote-runtime')
|
|
})
|
|
).toEqual({ activeRuntimeEnvironmentId: 'remote-runtime' })
|
|
|
|
expect(
|
|
getTaskSourceRuntimeSettings({
|
|
hostId: toSshExecutionHostId('ssh-target')
|
|
})
|
|
).toEqual({ activeRuntimeEnvironmentId: null })
|
|
})
|
|
|
|
it('keeps provider cache scopes separate by host and provider identity', () => {
|
|
const local = getTaskSourceCacheScope({
|
|
provider: 'github',
|
|
projectId: 'project-1',
|
|
hostId: 'local',
|
|
repoId: 'repo-1',
|
|
providerIdentity: { provider: 'github', owner: 'stablyai', repo: 'orca' }
|
|
})
|
|
const ssh = getTaskSourceCacheScope({
|
|
provider: 'github',
|
|
projectId: 'project-1',
|
|
hostId: toSshExecutionHostId('builder'),
|
|
repoId: 'repo-1',
|
|
providerIdentity: { provider: 'github', owner: 'stablyai', repo: 'orca' }
|
|
})
|
|
const differentRepo = getTaskSourceCacheScope({
|
|
provider: 'github',
|
|
projectId: 'project-1',
|
|
hostId: 'local',
|
|
repoId: 'repo-1',
|
|
providerIdentity: { provider: 'github', owner: 'other', repo: 'orca' }
|
|
})
|
|
const enterpriseRepo = getTaskSourceCacheScope({
|
|
provider: 'github',
|
|
projectId: 'project-1',
|
|
hostId: 'local',
|
|
repoId: 'repo-1',
|
|
providerIdentity: {
|
|
provider: 'github',
|
|
owner: 'stablyai',
|
|
repo: 'orca',
|
|
host: 'github.acme.test'
|
|
}
|
|
})
|
|
|
|
expect(local).not.toBe(ssh)
|
|
expect(local).not.toBe(differentRepo)
|
|
expect(local).not.toBe(enterpriseRepo)
|
|
})
|
|
|
|
it('separates named task accounts without changing legacy anonymous cache scopes', () => {
|
|
const source = { provider: 'linear', projectId: 'project', hostId: 'runtime:owner' } as const
|
|
const legacy = getTaskSourceCacheScope(source)
|
|
expect(getTaskSourceCacheScope({ ...source, accountLabel: null })).toBe(legacy)
|
|
expect(getTaskSourceCacheScope({ ...source, accountLabel: ' account-a ' })).toBe(
|
|
getTaskSourceCacheScope({ ...source, accountLabel: 'account-a' })
|
|
)
|
|
const account = getTaskSourceCacheScope({ ...source, accountLabel: 'account-a' })
|
|
expect(account).not.toBe(legacy)
|
|
expect(account).not.toBe(getTaskSourceCacheScope({ ...source, accountLabel: 'account-b' }))
|
|
expect(account).not.toBe(
|
|
getTaskSourceCacheScope({ ...source, hostId: 'local', accountLabel: 'account-a' })
|
|
)
|
|
})
|
|
|
|
it('serializes provider identities for GitLab, Linear, and Jira cache scopes', () => {
|
|
const base = {
|
|
projectId: 'project-1',
|
|
hostId: LOCAL_EXECUTION_HOST_ID,
|
|
repoId: 'repo-1'
|
|
} as const
|
|
|
|
expect(
|
|
getTaskSourceCacheScope({
|
|
...base,
|
|
provider: 'gitlab',
|
|
providerIdentity: { provider: 'gitlab', namespace: 'stably', project: 'orca' }
|
|
})
|
|
).toContain(encodeURIComponent('stably/orca'))
|
|
expect(
|
|
getTaskSourceCacheScope({
|
|
...base,
|
|
provider: 'linear',
|
|
providerIdentity: { provider: 'linear', workspaceId: 'workspace-1', teamKey: 'ENG' }
|
|
})
|
|
).toContain(encodeURIComponent('workspace-1/ENG'))
|
|
expect(
|
|
getTaskSourceCacheScope({
|
|
...base,
|
|
provider: 'jira',
|
|
providerIdentity: {
|
|
provider: 'jira',
|
|
siteUrl: 'https://example.atlassian.net',
|
|
projectKey: 'OPS'
|
|
}
|
|
})
|
|
).toContain(encodeURIComponent('https://example.atlassian.net/OPS'))
|
|
})
|
|
|
|
it('drops provider identities that do not match the source provider', () => {
|
|
expect(
|
|
normalizeTaskSourceContext({
|
|
provider: 'gitlab',
|
|
projectId: 'project-1',
|
|
providerIdentity: { provider: 'github', owner: 'stablyai', repo: 'orca' }
|
|
})?.providerIdentity
|
|
).toBeNull()
|
|
})
|
|
|
|
it('rejects malformed stored scalar and provider-identity fields without throwing', () => {
|
|
const valid = {
|
|
kind: 'task-source',
|
|
provider: 'jira',
|
|
projectId: 'project-1',
|
|
hostId: 'local',
|
|
providerIdentity: {
|
|
provider: 'jira',
|
|
siteId: 'site-1',
|
|
siteUrl: 'https://example.atlassian.net',
|
|
projectKey: 'OPS'
|
|
}
|
|
}
|
|
for (const malformed of [
|
|
{ ...valid, accountLabel: 44 },
|
|
{ ...valid, hostId: { runtime: 'env-1' } },
|
|
{ ...valid, providerIdentity: { ...valid.providerIdentity, siteId: 44 } },
|
|
{ ...valid, providerIdentity: { ...valid.providerIdentity, projectKey: [] } }
|
|
]) {
|
|
expect(() => TaskSourceContextSchema.safeParse(malformed)).not.toThrow()
|
|
expect(TaskSourceContextSchema.safeParse(malformed).success).toBe(false)
|
|
expect(normalizeStoredTaskSourceContext(malformed)).toBeNull()
|
|
}
|
|
})
|
|
|
|
it('builds workspace run context from an explicit project host setup', () => {
|
|
expect(
|
|
buildWorkspaceRunContext({
|
|
projectId: 'project-1',
|
|
hostId: toSshExecutionHostId('builder'),
|
|
projectHostSetupId: 'setup-1',
|
|
repoId: 'repo-1',
|
|
path: '/repo'
|
|
})
|
|
).toEqual({
|
|
kind: 'workspace-run',
|
|
projectId: 'project-1',
|
|
hostId: toSshExecutionHostId('builder'),
|
|
projectHostSetupId: 'setup-1',
|
|
repoId: 'repo-1',
|
|
path: '/repo'
|
|
})
|
|
})
|
|
|
|
it('normalizes focused runtime ids to host ids', () => {
|
|
expect(runtimeHostIdFromEnvironmentId(' remote ')).toBe(toRuntimeExecutionHostId('remote'))
|
|
expect(runtimeHostIdFromEnvironmentId(' ')).toBe('local')
|
|
})
|
|
})
|
|
|
|
describe('areTaskSourceContextsEqual', () => {
|
|
const base: TaskSourceContext = {
|
|
kind: 'task-source',
|
|
provider: 'jira',
|
|
projectId: 'project-1',
|
|
hostId: 'local',
|
|
repoId: 'repo-1',
|
|
providerIdentity: {
|
|
provider: 'jira',
|
|
siteId: 'site-1',
|
|
siteUrl: 'https://company.atlassian.net',
|
|
projectKey: 'ORCA'
|
|
}
|
|
}
|
|
|
|
it('ignores key order and absent-vs-null optional fields', () => {
|
|
expect(
|
|
areTaskSourceContextsEqual(base, {
|
|
providerIdentity: {
|
|
projectKey: 'ORCA',
|
|
siteUrl: 'https://company.atlassian.net',
|
|
siteId: 'site-1',
|
|
provider: 'jira'
|
|
},
|
|
repoId: 'repo-1',
|
|
hostId: 'local',
|
|
projectId: 'project-1',
|
|
provider: 'jira',
|
|
kind: 'task-source',
|
|
accountLabel: null
|
|
})
|
|
).toBe(true)
|
|
})
|
|
|
|
it('treats both nullish contexts as equal and a one-sided context as different', () => {
|
|
expect(areTaskSourceContextsEqual(null, undefined)).toBe(true)
|
|
expect(areTaskSourceContextsEqual(base, null)).toBe(false)
|
|
})
|
|
|
|
it('separates contexts that differ by host, account, or provider identity', () => {
|
|
expect(areTaskSourceContextsEqual(base, { ...base, hostId: 'ssh:builder' })).toBe(false)
|
|
expect(areTaskSourceContextsEqual(base, { ...base, accountLabel: 'ada@example.com' })).toBe(
|
|
false
|
|
)
|
|
expect(
|
|
areTaskSourceContextsEqual(base, {
|
|
...base,
|
|
providerIdentity: { provider: 'jira', siteId: 'site-2' }
|
|
})
|
|
).toBe(false)
|
|
expect(areTaskSourceContextsEqual(base, { ...base, providerIdentity: null })).toBe(false)
|
|
})
|
|
|
|
it('does not equate identities from different providers', () => {
|
|
const github: TaskSourceContext = {
|
|
...base,
|
|
provider: 'github',
|
|
providerIdentity: { provider: 'github', owner: 'acme', repo: 'orca' }
|
|
}
|
|
expect(areTaskSourceContextsEqual(github, { ...github, provider: 'gitlab' })).toBe(false)
|
|
})
|
|
})
|