/** * I-001: Pipeline CRUD — Create / Update / Publish */ import { describe, it, expect, beforeAll, afterAll } from 'vitest' import { prisma, createTestContext } from '../setup' import { createTestUser, createTestProgram, cleanupTestData, } from '../helpers' import { pipelineRouter } from '@/server/routers/pipeline' let programId: string let userIds: string[] = [] beforeAll(async () => { const program = await createTestProgram({ name: 'Pipeline CRUD Test' }) programId = program.id }) afterAll(async () => { await cleanupTestData(programId, userIds) }) describe('I-001: Pipeline CRUD', () => { it('creates a pipeline with tracks and stages via createStructure', async () => { const admin = await createTestUser('SUPER_ADMIN') userIds.push(admin.id) const ctx = createTestContext(admin) const caller = pipelineRouter.createCaller(ctx) const result = await caller.createStructure({ programId, name: 'Test Pipeline', slug: `test-pipe-${Date.now()}`, tracks: [ { name: 'Main Track', slug: 'main', kind: 'MAIN', sortOrder: 0, stages: [ { name: 'Filtering', slug: 'filtering', stageType: 'FILTER', sortOrder: 0 }, { name: 'Evaluation', slug: 'evaluation', stageType: 'EVALUATION', sortOrder: 1 }, ], }, ], }) expect(result.pipeline.id).toBeDefined() // Verify pipeline was created const pipeline = await prisma.pipeline.findUnique({ where: { id: result.pipeline.id }, include: { tracks: { include: { stages: { orderBy: { sortOrder: 'asc' } } }, }, }, }) expect(pipeline).not.toBeNull() expect(pipeline!.name).toBe('Test Pipeline') expect(pipeline!.tracks).toHaveLength(1) expect(pipeline!.tracks[0].name).toBe('Main Track') expect(pipeline!.tracks[0].stages).toHaveLength(2) expect(pipeline!.tracks[0].stages[0].name).toBe('Filtering') expect(pipeline!.tracks[0].stages[1].name).toBe('Evaluation') // Verify auto-created StageTransition between stages const transitions = await prisma.stageTransition.findMany({ where: { fromStage: { trackId: pipeline!.tracks[0].id }, }, }) expect(transitions.length).toBeGreaterThanOrEqual(1) }) it('updates a pipeline name and settings', async () => { const admin = await createTestUser('SUPER_ADMIN') userIds.push(admin.id) const ctx = createTestContext(admin) const caller = pipelineRouter.createCaller(ctx) const created = await caller.createStructure({ programId, name: 'Original Name', slug: `upd-pipe-${Date.now()}`, tracks: [ { name: 'Track 1', slug: 'track-1', kind: 'MAIN', sortOrder: 0, stages: [{ name: 'S1', slug: 's1', stageType: 'EVALUATION', sortOrder: 0 }], }, ], }) const updated = await caller.update({ id: created.pipeline.id, name: 'Updated Name', settingsJson: { theme: 'blue' }, }) expect(updated.name).toBe('Updated Name') const fetched = await prisma.pipeline.findUnique({ where: { id: created.pipeline.id } }) expect(fetched!.name).toBe('Updated Name') expect((fetched!.settingsJson as any)?.theme).toBe('blue') }) it('publishes a pipeline with valid structure', async () => { const admin = await createTestUser('SUPER_ADMIN') userIds.push(admin.id) const ctx = createTestContext(admin) const caller = pipelineRouter.createCaller(ctx) const created = await caller.createStructure({ programId, name: 'Publish Test', slug: `pub-pipe-${Date.now()}`, tracks: [ { name: 'Main', slug: 'main', kind: 'MAIN', sortOrder: 0, stages: [{ name: 'Eval', slug: 'eval', stageType: 'EVALUATION', sortOrder: 0 }], }, ], }) const published = await caller.publish({ id: created.pipeline.id }) expect(published.status).toBe('ACTIVE') const fetched = await prisma.pipeline.findUnique({ where: { id: created.pipeline.id } }) expect(fetched!.status).toBe('ACTIVE') }) })