task-acceptance-mode.test.js 3.07 KB
/**
 * 43 号文档 Phase 0:`tasks.acceptance_mode` + `createTask({parentTaskId})` 的落库校验。
 *
 * 隔离:先设 GRAPH_DB_PATH 再 require(清 require.cache),仓库 data/graph.sqlite 全程不碰
 * ——写法与 graph-edge-contracts.test.js 同源。
 */
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import fs from 'fs';

const TEST_DB_PATH = '/tmp/test-task-acceptance-mode.sqlite';
const DB_FILES = [TEST_DB_PATH, `${TEST_DB_PATH}-shm`, `${TEST_DB_PATH}-wal`];

describe('43 号文档 Phase 0:acceptance_mode / parentTaskId', () => {
  let wdb;

  beforeAll(() => {
    for (const f of DB_FILES) { try { fs.unlinkSync(f); } catch {} }
    process.env.GRAPH_DB_PATH = TEST_DB_PATH;
    delete require.cache[require.resolve('../../services/graph-db')];
    delete require.cache[require.resolve('../../services/work-graph-db')];
    wdb = require('../../services/work-graph-db');
  });

  afterAll(() => {
    for (const f of DB_FILES) { try { fs.unlinkSync(f); } catch {} }
    delete process.env.GRAPH_DB_PATH;
    delete require.cache[require.resolve('../../services/graph-db')];
    delete require.cache[require.resolve('../../services/work-graph-db')];
  });

  function goalId() {
    const g = wdb.createGoal({ companyId: 'co-amode', title: 'g', description: 'd' });
    return g.id;
  }

  it('缺省 acceptance_mode=holistic、parent_task_id=null(图流水线现状不变)', () => {
    const t = wdb.createTask({ goalId: goalId(), title: 't', description: 'd' });
    expect(t.acceptance_mode).toBe('holistic');
    expect(t.parent_task_id).toBeNull();
  });

  it('可以显式建一条 itemized 的顶层 task', () => {
    const t = wdb.createTask({ goalId: goalId(), title: 't', description: 'd', acceptanceMode: 'itemized' });
    expect(t.acceptance_mode).toBe('itemized');
  });

  it('非法 acceptanceMode 直接拒', () => {
    expect(() => wdb.createTask({ goalId: goalId(), title: 't', description: 'd', acceptanceMode: 'bogus' }))
      .toThrow(/acceptanceMode 非法/);
  });

  it('子任务:parentTaskId 指回父任务,acceptance_mode 恒 holistic', () => {
    const gid = goalId();
    const parent = wdb.createTask({ goalId: gid, title: 'parent', description: 'd', acceptanceMode: 'itemized' });
    const child = wdb.createTask({ goalId: gid, title: 'child A.1', description: 'd', parentTaskId: parent.id });
    expect(child.parent_task_id).toBe(parent.id);
    expect(child.acceptance_mode).toBe('holistic');
  });

  it('子任务不允许递归声明 itemized(不支持二级拆分)', () => {
    const gid = goalId();
    const parent = wdb.createTask({ goalId: gid, title: 'parent', description: 'd' });
    expect(() => wdb.createTask({
      goalId: gid, title: 'child', description: 'd', parentTaskId: parent.id, acceptanceMode: 'itemized',
    })).toThrow(/不支持递归拆分/);
  });

  it('parentTaskId 指向不存在的 task 直接拒,不静默建成孤儿行', () => {
    expect(() => wdb.createTask({ goalId: goalId(), title: 't', description: 'd', parentTaskId: 'T-not-exist' }))
      .toThrow(/parentTaskId 不存在/);
  });
});