"use strict";
/**
 * RED-GREEN tests for the pack rule validator.
 *
 * @connexum/ai-governance  pack-rule-validator
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
const node_test_1 = require("node:test");
const assert = __importStar(require("node:assert/strict"));
const pack_rule_validator_1 = require("./pack-rule-validator");
const capability_classes_1 = require("./capability-classes");
const validInput = () => ({
    id: 'co-pack-1',
    version: '1.0.0',
    orgId: 'org-x',
    rules: [{ capability: capability_classes_1.CAPABILITY_CLASS.MCP, action: 'BLOCK' }],
    isolation: 'none',
});
(0, node_test_1.describe)('pack-rule-validator', () => {
    (0, node_test_1.it)('valid input passes with ok=true and no errors', () => {
        const r = (0, pack_rule_validator_1.validatePackInput)(validInput());
        assert.equal(r.ok, true);
        assert.equal(r.errors.length, 0);
        assert.equal(r.warnings.length, 0);
    });
    (0, node_test_1.it)('missing id is an ERROR', () => {
        const r = (0, pack_rule_validator_1.validatePackInput)({ ...validInput(), id: undefined });
        assert.equal(r.ok, false);
        assert.ok(r.errors.some((e) => e.field === 'id' && e.code === 'MISSING'));
    });
    (0, node_test_1.it)('invalid id format is an ERROR', () => {
        const r = (0, pack_rule_validator_1.validatePackInput)({ ...validInput(), id: 'has spaces and !' });
        assert.equal(r.ok, false);
        assert.ok(r.errors.some((e) => e.field === 'id' && e.code === 'INVALID_FORMAT'));
    });
    (0, node_test_1.it)('missing version is an ERROR', () => {
        const r = (0, pack_rule_validator_1.validatePackInput)({ ...validInput(), version: undefined });
        assert.ok(r.errors.some((e) => e.field === 'version' && e.code === 'MISSING'));
    });
    (0, node_test_1.it)('invalid version is an ERROR', () => {
        const r = (0, pack_rule_validator_1.validatePackInput)({ ...validInput(), version: 'banana' });
        assert.ok(r.errors.some((e) => e.field === 'version' && e.code === 'INVALID_FORMAT'));
    });
    (0, node_test_1.it)('missing orgId is an ERROR', () => {
        const r = (0, pack_rule_validator_1.validatePackInput)({ ...validInput(), orgId: '' });
        assert.ok(r.errors.some((e) => e.field === 'orgId' && e.code === 'MISSING'));
    });
    (0, node_test_1.it)('invalid isolation is an ERROR', () => {
        const r = (0, pack_rule_validator_1.validatePackInput)({ ...validInput(), isolation: 'super-strict' });
        assert.ok(r.errors.some((e) => e.field === 'isolation' && e.code === 'INVALID_ISOLATION'));
    });
    (0, node_test_1.it)('valid isolation values pass', () => {
        for (const iso of ['none', 'sourced-only', 'strict']) {
            const r = (0, pack_rule_validator_1.validatePackInput)({ ...validInput(), isolation: iso });
            assert.equal(r.ok, true, `isolation=${iso} should pass`);
        }
    });
    (0, node_test_1.it)('non-array rules is an ERROR', () => {
        const r = (0, pack_rule_validator_1.validatePackInput)({ ...validInput(), rules: 'not an array' });
        assert.ok(r.errors.some((e) => e.field === 'rules' && e.code === 'MISSING'));
    });
    (0, node_test_1.it)('empty rules array is a WARN, not an ERROR', () => {
        const r = (0, pack_rule_validator_1.validatePackInput)({ ...validInput(), rules: [] });
        assert.equal(r.ok, true);
        assert.ok(r.warnings.some((w) => w.field === 'rules' && w.code === 'EMPTY_RULE_LIST'));
    });
    (0, node_test_1.it)('unknown capability is an ERROR with the allowed list in the message', () => {
        const r = (0, pack_rule_validator_1.validatePackInput)({
            ...validInput(),
            rules: [{ capability: 'capability:nonexistent', action: 'BLOCK' }],
        });
        assert.ok(r.errors.some((e) => e.code === 'UNKNOWN_CAPABILITY'));
        const err = r.errors.find((e) => e.code === 'UNKNOWN_CAPABILITY');
        assert.match(err.message, /Allowed:/);
    });
    (0, node_test_1.it)('unknown action is an ERROR', () => {
        const r = (0, pack_rule_validator_1.validatePackInput)({
            ...validInput(),
            rules: [{ capability: capability_classes_1.CAPABILITY_CLASS.MCP, action: 'EXPLODE' }],
        });
        assert.ok(r.errors.some((e) => e.code === 'UNKNOWN_ACTION'));
    });
    (0, node_test_1.it)('duplicate (capability, action) is an ERROR', () => {
        const r = (0, pack_rule_validator_1.validatePackInput)({
            ...validInput(),
            rules: [
                { capability: capability_classes_1.CAPABILITY_CLASS.MCP, action: 'BLOCK' },
                { capability: capability_classes_1.CAPABILITY_CLASS.MCP, action: 'BLOCK' },
            ],
        });
        assert.ok(r.errors.some((e) => e.code === 'DUPLICATE_RULE'));
    });
    (0, node_test_1.it)('different actions on same capability are NOT duplicates (strictest-wins handles)', () => {
        const r = (0, pack_rule_validator_1.validatePackInput)({
            ...validInput(),
            rules: [
                { capability: capability_classes_1.CAPABILITY_CLASS.MCP, action: 'BLOCK' },
                { capability: capability_classes_1.CAPABILITY_CLASS.MCP, action: 'WARN' },
            ],
        });
        assert.equal(r.ok, true);
    });
    (0, node_test_1.it)('rule that is not an object is an ERROR', () => {
        const r = (0, pack_rule_validator_1.validatePackInput)({
            ...validInput(),
            rules: ['not-an-object'],
        });
        assert.ok(r.errors.some((e) => e.field === 'rules[0]' && e.code === 'INVALID_FORMAT'));
    });
    (0, node_test_1.it)('all 5 valid actions pass', () => {
        for (const action of ['ALLOW', 'LOG', 'WARN', 'REQUIRE_APPROVAL', 'BLOCK']) {
            const r = (0, pack_rule_validator_1.validatePackInput)({
                ...validInput(),
                rules: [{ capability: capability_classes_1.CAPABILITY_CLASS.MCP, action }],
            });
            assert.equal(r.ok, true, `action=${action} should pass`);
        }
    });
});
//# sourceMappingURL=pack-rule-validator.test.js.map