import { describe, it, expect, beforeEach } from 'vitest'; import { appRouter } from './index'; describe('revisionsRouter', () => { const ctx = { userId: '123e4567-e89b-12d3-a456-426614174000' }; describe('createRevision', () => { it('should create a revision with version 1', async () => { const result = await appRouter.revisions.createRevision.mutate({ input: { scriptId: 1, title: 'Initial draft', content: 'FADE IN:\n\nINT. ROOM - DAY', authorId: 1, }, ctx, }); expect(result.versionNumber).toBe(1); expect(result.branchName).toBe('main'); expect(result.status).toBe('draft'); }); it('should increment version number for same script', async () => { await appRouter.revisions.createRevision.mutate({ input: { scriptId: 1, title: 'v1', content: 'content1', authorId: 1 }, ctx, }); const result = await appRouter.revisions.createRevision.mutate({ input: { scriptId: 1, title: 'v2', content: 'content2', authorId: 1 }, ctx, }); expect(result.versionNumber).toBe(2); }); it('should support custom branch', async () => { const result = await appRouter.revisions.createRevision.mutate({ input: { scriptId: 1, title: 'Branch revision', content: 'branch content', branchName: 'feature-act2', authorId: 1, }, ctx, }); expect(result.branchName).toBe('feature-act2'); }); }); describe('listRevisions', () => { it('should return empty array for unknown script', async () => { const result = await appRouter.revisions.listRevisions.query({ input: { scriptId: 999 }, ctx, }); expect(result).toEqual([]); }); it('should filter by branch', async () => { await appRouter.revisions.createRevision.mutate({ input: { scriptId: 1, title: 'main v1', content: 'main', branchName: 'main', authorId: 1 }, ctx, }); await appRouter.revisions.createRevision.mutate({ input: { scriptId: 1, title: 'feature v1', content: 'feature', branchName: 'feature', authorId: 1 }, ctx, }); const mainRevisions = await appRouter.revisions.listRevisions.query({ input: { scriptId: 1, branchName: 'main' }, ctx, }); expect(mainRevisions).toHaveLength(1); expect(mainRevisions[0]!.branchName).toBe('main'); }); }); describe('acceptRevision', () => { it('should accept a revision', async () => { const created = await appRouter.revisions.createRevision.mutate({ input: { scriptId: 1, title: 'To accept', content: 'content', authorId: 1 }, ctx, }); const result = await appRouter.revisions.acceptRevision.mutate({ input: { revisionId: created.id, reviewedById: 2 }, ctx, }); expect(result.status).toBe('accepted'); expect(result.reviewedById).toBe(2); expect(result.reviewedAt).toBeDefined(); }); }); describe('rejectRevision', () => { it('should reject a revision with reason', async () => { const created = await appRouter.revisions.createRevision.mutate({ input: { scriptId: 1, title: 'To reject', content: 'content', authorId: 1 }, ctx, }); const result = await appRouter.revisions.rejectRevision.mutate({ input: { revisionId: created.id, reviewedById: 2, reason: 'Needs more work on dialogue' }, ctx, }); expect(result.status).toBe('rejected'); expect(result.summary).toContain('Needs more work on dialogue'); }); }); describe('rollbackToRevision', () => { it('should create a new revision with old content', async () => { const original = await appRouter.revisions.createRevision.mutate({ input: { scriptId: 1, title: 'Original', content: 'original content', authorId: 1 }, ctx, }); await appRouter.revisions.createRevision.mutate({ input: { scriptId: 1, title: 'Changed', content: 'changed content', authorId: 1 }, ctx, }); const rollback = await appRouter.revisions.rollbackToRevision.mutate({ input: { scriptId: 1, revisionId: original.id, authorId: 1 }, ctx, }); expect(rollback.content).toBe('original content'); expect(rollback.versionNumber).toBe(3); expect(rollback.title).toContain('Rollback'); }); }); describe('compareRevisions', () => { it('should compare two revisions', async () => { const rev1 = await appRouter.revisions.createRevision.mutate({ input: { scriptId: 1, title: 'v1', content: 'line1\nline2\nline3', authorId: 1 }, ctx, }); const rev2 = await appRouter.revisions.createRevision.mutate({ input: { scriptId: 1, title: 'v2', content: 'line1\nchanged\nline3', authorId: 1 }, ctx, }); const result = await appRouter.revisions.compareRevisions.query({ input: { baseRevisionId: rev1.id, targetRevisionId: rev2.id }, ctx, }); expect(result.diff.modifications).toBe(1); expect(result.diff.additions).toBe(0); expect(result.diff.deletions).toBe(0); }); }); describe('getTimeline', () => { it('should return timeline entries in chronological order', async () => { await appRouter.revisions.createRevision.mutate({ input: { scriptId: 1, title: 'First', content: 'first', authorId: 1 }, ctx, }); await appRouter.revisions.createRevision.mutate({ input: { scriptId: 1, title: 'Second', content: 'second', authorId: 1 }, ctx, }); const timeline = await appRouter.revisions.getTimeline.query({ input: { scriptId: 1 }, ctx, }); expect(timeline).toHaveLength(2); expect(timeline[0]!.revision.title).toBe('First'); expect(timeline[1]!.revision.title).toBe('Second'); }); }); describe('getBranches', () => { it('should return branch information', async () => { await appRouter.revisions.createRevision.mutate({ input: { scriptId: 1, title: 'main v1', content: 'main', authorId: 1 }, ctx, }); await appRouter.revisions.createBranch.mutate({ input: { scriptId: 1, branchName: 'feature', authorId: 1 }, ctx, }); const branches = await appRouter.revisions.getBranches.query({ input: { scriptId: 1 }, ctx, }); expect(branches).toHaveLength(2); const branchNames = branches.map((b: any) => b.branchName); expect(branchNames).toContain('main'); expect(branchNames).toContain('feature'); }); }); describe('deleteRevision', () => { it('should delete a revision', async () => { const created = await appRouter.revisions.createRevision.mutate({ input: { scriptId: 1, title: 'To delete', content: 'content', authorId: 1 }, ctx, }); const result = await appRouter.revisions.deleteRevision.mutate({ input: { id: created.id }, ctx, }); expect(result.success).toBe(true); await expect( appRouter.revisions.getRevision.query({ input: { id: created.id }, ctx, }) ).rejects.toThrow(); }); }); });