157 lines · 5.7 KB · TypeScript
RawDownload
import { describe, expect, it } from 'vitest' import { projectApplicationCommandContracts } from './projects' const project = {  id: 'project-1',  name: 'Project',  description: '',  isExample: false,  createdAt: 1,  updatedAt: 2} describe('project application command contracts', () => {  it('decodes the eight Project command argument and result shapes', () => {    const listArgs: [] = []    const listResult = [project]    expect(projectApplicationCommandContracts.list.args.parse(listArgs)).toBe(listArgs)    expect(projectApplicationCommandContracts.list.result.parse(listResult)).toBe(listResult)    expect(projectApplicationCommandContracts.get.args.parse(['project-1'])).toEqual(['project-1'])    expect(projectApplicationCommandContracts.get.result.parse(null)).toBeNull()    expect(projectApplicationCommandContracts.create.args.parse([{ name: 'Project' }])).toEqual([      { name: 'Project' }    ])    expect(      projectApplicationCommandContracts.update.args.parse([        { id: 'project-1', name: 'Renamed', expectedUpdatedAt: 2 }      ])    ).toEqual([{ id: 'project-1', name: 'Renamed', expectedUpdatedAt: 2 }])    expect(      projectApplicationCommandContracts.update.args.parse([        { id: 'project-1', pinned: true, expectedUpdatedAt: 2 }      ])    ).toEqual([{ id: 'project-1', pinned: true, expectedUpdatedAt: 2 }])    expect(      projectApplicationCommandContracts.create.args.parse([        { name: 'Project', agentContext: 'Always cite DOIs.' }      ])    ).toEqual([{ name: 'Project', agentContext: 'Always cite DOIs.' }])    expect(      projectApplicationCommandContracts.update.args.parse([        { id: 'project-1', agentContext: 'Always cite DOIs.', expectedUpdatedAt: 2 }      ])    ).toEqual([{ id: 'project-1', agentContext: 'Always cite DOIs.', expectedUpdatedAt: 2 }])    expect(      projectApplicationCommandContracts.get.result.parse({        ...project,        agentContext: 'Always cite DOIs.'      })    ).toEqual({ ...project, agentContext: 'Always cite DOIs.' })    expect(      projectApplicationCommandContracts.updateArchive.args.parse([        { id: 'project-1', archived: true, expectedArchiveRevision: 0 }      ])    ).toEqual([{ id: 'project-1', archived: true, expectedArchiveRevision: 0 }])    expect(projectApplicationCommandContracts.delete.args.parse([{ id: 'project-1' }])).toEqual([      { id: 'project-1' }    ])    expect(projectApplicationCommandContracts.delete.result.parse({ status: 'deleted' })).toEqual({      status: 'deleted'    })    expect(      projectApplicationCommandContracts.delete.result.parse({ status: 'cleanup-pending' })    ).toEqual({ status: 'cleanup-pending' })    const cleanup = [      {        projectId: 'project-1',        projectName: 'Project',        phase: 'retry-scheduled',        failureCount: 2,        nextRetryAt: 6_000      }    ]    expect(projectApplicationCommandContracts.listDeletionCleanup.args.parse([])).toEqual([])    expect(projectApplicationCommandContracts.listDeletionCleanup.result.parse(cleanup)).toEqual(      cleanup    )    expect(projectApplicationCommandContracts.retryDeletionCleanup.args.parse([])).toEqual([])    expect(      projectApplicationCommandContracts.retryDeletionCleanup.result.parse(undefined)    ).toBeUndefined()  })   it('rejects malformed and surplus public fields', () => {    expect(() => projectApplicationCommandContracts.create.args.parse([{ name: 42 }])).toThrow()    expect(() =>      projectApplicationCommandContracts.delete.args.parse([        { id: 'project-1', databasePath: '/private/research.db' }      ])    ).toThrow()    expect(() =>      projectApplicationCommandContracts.list.result.parse([{ ...project, createdAt: 'today' }])    ).toThrow()    expect(() =>      projectApplicationCommandContracts.listDeletionCleanup.result.parse([        {          projectId: 'project-1',          phase: 'retry-scheduled',          failureCount: 1,          nextRetryAt: 6_000,          error: '/private/research.db'        }      ])    ).toThrow()  })   it('rejects an agent context beyond the 16000 character limit', () => {    const oversized = 'x'.repeat(16001)     expect(() =>      projectApplicationCommandContracts.create.args.parse([        { name: 'Project', agentContext: oversized }      ])    ).toThrow()  })   it('requires an update baseline and enforces Project name and description limits', () => {    expect(() =>      projectApplicationCommandContracts.update.args.parse([{ id: 'project-1', name: 'Renamed' }])    ).toThrow()    expect(() =>      projectApplicationCommandContracts.create.args.parse([{ name: 'x'.repeat(201) }])    ).toThrow()    expect(() =>      projectApplicationCommandContracts.create.args.parse([        { name: 'Project', description: 'x'.repeat(1001) }      ])    ).toThrow()    expect(() =>      projectApplicationCommandContracts.update.args.parse([        { id: 'project-1', name: 'x'.repeat(201), expectedUpdatedAt: 2 }      ])    ).toThrow()    expect(() =>      projectApplicationCommandContracts.update.args.parse([        { id: 'project-1', description: 'x'.repeat(1001), expectedUpdatedAt: 2 }      ])    ).toThrow()    expect(      projectApplicationCommandContracts.create.args.parse([        { name: 'x'.repeat(200), description: 'x'.repeat(1000) }      ])    ).toEqual([{ name: 'x'.repeat(200), description: 'x'.repeat(1000) }])  })   it('keeps historical projects above the new write limits readable', () => {    const historicalProject = {      ...project,      name: 'x'.repeat(201),      description: 'x'.repeat(1001)    }     expect(projectApplicationCommandContracts.list.result.parse([historicalProject])).toEqual([      historicalProject    ])  })})