automation-ingest-integration.test.mjs
98 lines 3.4 KB
Raw
sha256:700fafdd1afa490919f9515d660ca6e75456bcd5bb67513abcd8757a634c01f6 docs: record AIP-b SD-21 land (KN #308) Human 9 days ago
1 /**
2 * AIP-b integration: pack load, PUT rules, route+execute review_queue, from-template.
3 */
4 import { describe, it, beforeEach, afterEach } from 'node:test';
5 import assert from 'node:assert/strict';
6 import fs from 'node:fs';
7 import os from 'node:os';
8 import path from 'node:path';
9 import {
10 listPackTemplates,
11 normalizeRuleForSave,
12 mintRuleId,
13 processAutomationIngest,
14 } from '../lib/automation-ingest-policy.mjs';
15 import {
16 loadIngestRulesForSub,
17 saveIngestRulesForSub,
18 } from '../hub/gateway/automation-ingest-store.mjs';
19 import { createProposal } from '../hub/proposals-store.mjs';
20 import { augmentProposalCreateRequestBody } from '../lib/hub-proposal-create-augment.mjs';
21 import { loadReviewTriggers } from '../lib/hub-proposal-review-triggers.mjs';
22
23 let tmp;
24
25 beforeEach(() => {
26 tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'aip-int-'));
27 });
28
29 afterEach(() => {
30 fs.rmSync(tmp, { recursive: true, force: true });
31 });
32
33 describe('automation ingest integration', () => {
34 it('load pack disabled; PUT rules; from-template stays disabled unless enable', async () => {
35 const templates = listPackTemplates();
36 assert.ok(templates.every((t) => t.enabled === false));
37 const empty = await loadIngestRulesForSub('user:1', tmp);
38 assert.deepEqual(empty.rules, []);
39 const rule = normalizeRuleForSave({
40 label: 'mine',
41 disposition: 'review_queue',
42 match: { path_prefix: 'inbox/trends/' },
43 });
44 await saveIngestRulesForSub('user:1', [rule], tmp);
45 const loaded = await loadIngestRulesForSub('user:1', tmp);
46 assert.equal(loaded.rules.length, 1);
47 assert.equal(loaded.rules[0].label, 'mine');
48
49 const copiedOff = normalizeRuleForSave(
50 { ...templates[0], rule_id: mintRuleId(), enabled: false },
51 { mintMissingId: false }
52 );
53 assert.equal(copiedOff.enabled, false);
54 const copiedOn = normalizeRuleForSave(
55 { ...templates[0], rule_id: mintRuleId(), enabled: true },
56 { mintMissingId: false }
57 );
58 assert.equal(copiedOn.enabled, true);
59 });
60
61 it('route + execute review_queue creates a proposal', async () => {
62 const audits = [];
63 const io = {
64 async getIdempotency() { return null; },
65 async putIdempotency() {},
66 async appendAudit(action, detail, proposalId) { audits.push({ action, detail, proposalId }); },
67 async runBilling() { return true; },
68 async readExistingNote() { return null; },
69 async writeNote() { throw new Error('should not write'); },
70 async createProposal(payload) {
71 const augmented = augmentProposalCreateRequestBody(payload, tmp, {
72 evaluationRequired: false,
73 sessionBound: false,
74 evaluatedBy: 'user:1',
75 });
76 return createProposal(tmp, { ...augmented, proposed_by: 'user:1' });
77 },
78 async markProposalApproved() { return { ok: true }; },
79 };
80 const out = await processAutomationIngest({
81 rawBody: {
82 path: 'inbox/trends/int.md',
83 body: 'integration',
84 source_fingerprint: 'fp-int-0001',
85 content_class: 'research',
86 },
87 actor: { sub: 'user:1', vaultId: 'default', credentialId: null, credentialName: 'bot' },
88 rules: [],
89 triggers: loadReviewTriggers(tmp),
90 io,
91 });
92 assert.equal(out.status, 201);
93 assert.equal(out.body.disposition, 'review_queue');
94 assert.equal(out.body.outcome, 'proposal');
95 assert.ok(out.body.proposal_id);
96 assert.ok(audits.some((a) => a.action === 'ingest_review_queued'));
97 });
98 });
File History 1 commit
sha256:700fafdd1afa490919f9515d660ca6e75456bcd5bb67513abcd8757a634c01f6 docs: record AIP-b SD-21 land (KN #308) Human 9 days ago