task-loop-store-integration.test.mjs
123 lines 4.1 KB
Raw
sha256:b5f647cb9c409f563d4671fe3fc05ddea01fabfed9b41fc11cb923588e1c1baf mirror: GitHub Phase A durable MCP OAuth (#270) Human minor ⚠ breaking 10 days ago
1 /**
2 * Tier 2 — INTEGRATION: Task loop handlers + store seed parity.
3 *
4 * @see docs/TASK-LOOP-STORE-CONTRACT-2G-c.md §6
5 */
6 import { describe, it, beforeEach, afterEach } from 'node:test';
7 import assert from 'node:assert/strict';
8 import fs from 'node:fs';
9 import path from 'node:path';
10 import { fileURLToPath } from 'node:url';
11 import { getRepoRoot } from '../lib/repo-root.mjs';
12 import {
13 handleTaskLoopListRequest,
14 handleTaskLoopGetRequest,
15 handleOrchestratorGraphGetRequest,
16 } from '../lib/task/task-loop-handlers.mjs';
17 import { listTaskLoops, getTaskLoop } from '../lib/task/task-loop-store.mjs';
18
19 const __dirname = path.dirname(fileURLToPath(import.meta.url));
20 const tmpRoot = path.join(__dirname, 'fixtures', 'tmp-task-loop-integration');
21 const loopStarterDir = path.join(getRepoRoot(), 'task-loops/starter');
22 const graphStarterDir = path.join(getRepoRoot(), 'orchestrator-graphs/starter');
23 const instancesDir = path.join(getRepoRoot(), 'task-loops/starter/instances');
24 const vaultId = 'vault-loop-integration';
25
26 describe('Task loop store — handler integration', () => {
27 beforeEach(() => {
28 fs.rmSync(tmpRoot, { recursive: true, force: true });
29 fs.mkdirSync(tmpRoot, { recursive: true });
30 });
31
32 afterEach(() => {
33 fs.rmSync(tmpRoot, { recursive: true, force: true });
34 });
35
36 it('handleTaskLoopListRequest and listTaskLoops return matching loop counts', () => {
37 const dataDir = path.join(tmpRoot, 'data');
38 fs.mkdirSync(dataDir, { recursive: true });
39
40 const handlerResult = handleTaskLoopListRequest({
41 dataDir,
42 vaultId,
43 cliScopes: ['personal', 'project', 'org'],
44 starterDir: loopStarterDir,
45 graphsDir: graphStarterDir,
46 instancesDir,
47 });
48 assert.equal(handlerResult.ok, true);
49 if (!handlerResult.ok) return;
50
51 const storeResult = listTaskLoops(dataDir, vaultId, {
52 visibleScopes: new Set(['personal', 'project', 'org']),
53 filterScopes: new Set(['personal', 'project', 'org']),
54 effectiveScope: 'org',
55 starterDir: loopStarterDir,
56 graphsDir: graphStarterDir,
57 instancesDir,
58 });
59
60 assert.equal(handlerResult.payload.loops.length, storeResult.loops.length);
61 assert.equal(storeResult.loops.length, 6);
62 assert.equal(handlerResult.payload.schema, 'knowtation.task_loop_list/v0');
63 });
64
65 it('handleTaskLoopGetRequest returns loop_school_trip for authorized scope', () => {
66 const dataDir = path.join(tmpRoot, 'data-get');
67 fs.mkdirSync(dataDir, { recursive: true });
68
69 const result = handleTaskLoopGetRequest({
70 dataDir,
71 vaultId,
72 loopId: 'loop_school_trip',
73 cliScopes: ['personal'],
74 starterDir: loopStarterDir,
75 graphsDir: graphStarterDir,
76 instancesDir,
77 });
78
79 assert.equal(result.ok, true);
80 if (!result.ok) return;
81 assert.equal(result.payload.loop.loop_id, 'loop_school_trip');
82 assert.equal(result.payload.schema, 'knowtation.task_loop_get/v0');
83 });
84
85 it('handleOrchestratorGraphGetRequest returns graph_school_trip', () => {
86 const dataDir = path.join(tmpRoot, 'data-graph');
87 fs.mkdirSync(dataDir, { recursive: true });
88
89 const result = handleOrchestratorGraphGetRequest({
90 dataDir,
91 vaultId,
92 graphId: 'graph_school_trip',
93 cliScopes: ['personal'],
94 starterDir: loopStarterDir,
95 graphsDir: graphStarterDir,
96 instancesDir,
97 });
98
99 assert.equal(result.ok, true);
100 if (!result.ok) return;
101 assert.equal(result.payload.graph.graph_id, 'graph_school_trip');
102 assert.equal(result.payload.graph.edges.length, 4);
103 });
104
105 it('getTaskLoop returns null for out-of-scope loop (no existence leak)', () => {
106 const dataDir = path.join(tmpRoot, 'data-deny');
107 fs.mkdirSync(dataDir, { recursive: true });
108
109 listTaskLoops(dataDir, vaultId, {
110 visibleScopes: new Set(['personal', 'project', 'org']),
111 filterScopes: new Set(['personal', 'project', 'org']),
112 effectiveScope: 'org',
113 starterDir: loopStarterDir,
114 graphsDir: graphStarterDir,
115 instancesDir,
116 });
117
118 const row = getTaskLoop(dataDir, vaultId, 'loop_school_trip', {
119 visibleScopes: new Set(['org']),
120 });
121 assert.equal(row, null);
122 });
123 });
File History 1 commit
sha256:b5f647cb9c409f563d4671fe3fc05ddea01fabfed9b41fc11cb923588e1c1baf mirror: GitHub Phase A durable MCP OAuth (#270) Human minor 10 days ago