"use strict";
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;
    };
})();
describe('Security (Phase 11)', () => {
    describe('checkRateLimit', () => {
        it('allows first request', async () => {
            const { checkRateLimit, resetRateLimit } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            resetRateLimit('test-1');
            const r = checkRateLimit('test-1');
            expect(r.allowed).toBe(true);
            expect(r.remaining).toBeGreaterThan(0);
        });
        it('blocks after exceeding limit', async () => {
            const { checkRateLimit, resetRateLimit } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            resetRateLimit('test-2');
            // Default limit is 600; send 601
            let allowedCount = 0;
            for (let i = 0; i < 601; i++) {
                const r = checkRateLimit('test-2');
                if (r.allowed)
                    allowedCount++;
            }
            expect(allowedCount).toBe(600);
            const blocked = checkRateLimit('test-2');
            expect(blocked.allowed).toBe(false);
        });
        it('isolates buckets per client', async () => {
            const { checkRateLimit, resetRateLimit } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            resetRateLimit();
            const a = checkRateLimit('client-A');
            const b = checkRateLimit('client-B');
            expect(a.allowed).toBe(true);
            expect(b.allowed).toBe(true);
            expect(a.remaining).toBe(b.remaining);
        });
    });
    describe('validateToolArgs', () => {
        it('accepts plain object', async () => {
            const { validateToolArgs } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            const r = validateToolArgs('cell_x', { project: 'foo', count: 5 });
            expect(r.valid).toBe(true);
        });
        it('rejects null', async () => {
            const { validateToolArgs } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            expect(validateToolArgs('cell_x', null).valid).toBe(false);
        });
        it('rejects arrays at top level', async () => {
            const { validateToolArgs } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            expect(validateToolArgs('cell_x', [1, 2, 3]).valid).toBe(false);
        });
        it('rejects oversized strings', async () => {
            const { validateToolArgs } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            const big = 'x'.repeat(200_000);
            const r = validateToolArgs('cell_x', { data: big });
            expect(r.valid).toBe(false);
            expect(r.reason).toContain('too long');
        });
        it('rejects deeply nested objects', async () => {
            const { validateToolArgs } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            let deep = { v: 1 };
            for (let i = 0; i < 20; i++)
                deep = { v: deep };
            const r = validateToolArgs('cell_x', deep);
            expect(r.valid).toBe(false);
        });
        it('rejects objects with too many keys', async () => {
            const { validateToolArgs } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            const obj = {};
            for (let i = 0; i < 200; i++)
                obj['k' + i] = i;
            const r = validateToolArgs('cell_x', obj);
            expect(r.valid).toBe(false);
        });
        it('rejects oversized arrays', async () => {
            const { validateToolArgs } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            const arr = new Array(2000).fill(0);
            const r = validateToolArgs('cell_x', { items: arr });
            expect(r.valid).toBe(false);
        });
        it('rejects unsupported types', async () => {
            const { validateToolArgs } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            expect(validateToolArgs('cell_x', { fn: () => 1 }).valid).toBe(false);
            expect(validateToolArgs('cell_x', { sym: Symbol('x') }).valid).toBe(false);
        });
    });
    describe('isSafePath', () => {
        it('accepts normal paths', async () => {
            const { isSafePath } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            expect(isSafePath('src/index.ts')).toBe(true);
            expect(isSafePath('C:/Users/x/file.txt')).toBe(true);
        });
        it('rejects path traversal', async () => {
            const { isSafePath } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            expect(isSafePath('../../etc/passwd')).toBe(false);
            expect(isSafePath('C:\\Users\\..\\..\\Windows')).toBe(false);
        });
        it('rejects extremely long paths', async () => {
            const { isSafePath } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            expect(isSafePath('a/'.repeat(3000))).toBe(false);
        });
    });
    describe('looksLikeSqlInjection', () => {
        it('detects UNION SELECT', async () => {
            const { looksLikeSqlInjection } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            expect(looksLikeSqlInjection('1 UNION SELECT password FROM users')).toBe(true);
        });
        it('detects DROP TABLE', async () => {
            const { looksLikeSqlInjection } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            expect(looksLikeSqlInjection('; DROP TABLE users; --')).toBe(true);
        });
        it('does not flag benign strings', async () => {
            const { looksLikeSqlInjection } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            expect(looksLikeSqlInjection('hello world')).toBe(false);
            expect(looksLikeSqlInjection('select an item from the menu')).toBe(false); // case + structure
        });
    });
    describe('getClientId', () => {
        it('reads from x-forwarded-for header', async () => {
            const { getClientId } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            const id = getClientId({ ip: '127.0.0.1', headers: { 'x-forwarded-for': '192.168.1.1, 10.0.0.1' } });
            expect(id).toBe('192.168.1.1');
        });
        it('falls back to socket address', async () => {
            const { getClientId } = await Promise.resolve().then(() => __importStar(require('../walls/05-community/privacy/security')));
            const id = getClientId({ ip: '127.0.0.1', headers: {} });
            expect(id).toBe('127.0.0.1');
        });
    });
});
//# sourceMappingURL=security.test.js.map