/ src / lib / server / tasks / task-service.test.ts
task-service.test.ts
  1  import assert from 'node:assert/strict'
  2  import { describe, it } from 'node:test'
  3  
  4  import { computeTaskFingerprint } from '@/lib/task-dedupe'
  5  import type { BoardTask } from '@/types'
  6  
  7  import { applyTaskPatch, prepareTaskCreation } from '@/lib/server/tasks/task-service'
  8  
  9  function makeTask(overrides: Partial<BoardTask> = {}): BoardTask {
 10    return {
 11      id: 'task-1',
 12      title: 'Example Task',
 13      description: 'Do the work',
 14      status: 'backlog',
 15      agentId: 'agent-1',
 16      sessionId: null,
 17      result: null,
 18      error: null,
 19      createdAt: 1,
 20      updatedAt: 1,
 21      queuedAt: null,
 22      startedAt: null,
 23      completedAt: null,
 24      ...overrides,
 25    }
 26  }
 27  
 28  describe('task service helpers', () => {
 29    it('prepareTaskCreation derives a title and normalizes running to queued', () => {
 30      const prepared = prepareTaskCreation({
 31        id: 'task-create',
 32        input: {
 33          description: 'Please create a new login page for the app.',
 34          status: 'running',
 35          agentId: 'agent-1',
 36        },
 37        tasks: {},
 38        now: 50,
 39        deriveTitleFromDescription: true,
 40        requireMeaningfulTitle: true,
 41      })
 42  
 43      assert.equal(prepared.ok, true)
 44      if (!prepared.ok) return
 45      assert.equal(prepared.duplicate, null)
 46      assert.equal(prepared.task.title, 'a new login page for the app.')
 47      assert.equal(prepared.task.status, 'queued')
 48      assert.equal((prepared.task.fingerprint || '').length, 16)
 49    })
 50  
 51    it('prepareTaskCreation returns an existing duplicate task instead of a new one', () => {
 52      const existing = makeTask({
 53        id: 'existing-task',
 54        title: 'Unique dedupe title',
 55        agentId: 'agent-1',
 56        fingerprint: computeTaskFingerprint('Unique dedupe title', 'agent-1'),
 57      })
 58      const prepared = prepareTaskCreation({
 59        id: 'task-create',
 60        input: {
 61          title: 'Unique dedupe title',
 62          description: 'Duplicate task',
 63          agentId: 'agent-1',
 64        },
 65        tasks: { 'existing-task': existing },
 66        now: 60,
 67      })
 68  
 69      assert.equal(prepared.ok, true)
 70      if (!prepared.ok) return
 71      assert.equal(prepared.duplicate?.id, 'existing-task')
 72    })
 73  
 74    it('applyTaskPatch strips invalid statuses and clears nullable project ids', () => {
 75      const task = makeTask({
 76        status: 'backlog',
 77        projectId: 'project-1',
 78      })
 79  
 80      applyTaskPatch({
 81        task,
 82        patch: {
 83          status: 'bananas',
 84          projectId: null,
 85        },
 86        now: 75,
 87        clearProjectIdWhenNull: true,
 88      })
 89  
 90      assert.equal(task.status, 'backlog')
 91      assert.equal('projectId' in task, false)
 92      assert.equal(task.updatedAt, 75)
 93    })
 94  
 95    it('applyTaskPatch normalizes running updates to queued', () => {
 96      const task = makeTask({
 97        status: 'backlog',
 98      })
 99  
100      applyTaskPatch({
101        task,
102        patch: { status: 'running' },
103        now: 90,
104      })
105  
106      assert.equal(task.status, 'queued')
107    })
108  })