"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;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
const validation_1 = require("../../utils/validation");
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
// Mock fs module
jest.mock('fs');
describe('Validation Utils', () => {
    beforeEach(() => {
        jest.clearAllMocks();
    });
    describe('validateFilePath', () => {
        it('should accept valid file paths for write', () => {
            fs.existsSync.mockReturnValue(true);
            const result = (0, validation_1.validateFilePath)('/tmp/test.txt', 'write');
            expect(result).toBe(path.normalize('/tmp/test.txt'));
        });
        it('should accept valid file paths for read', () => {
            fs.existsSync.mockReturnValue(true);
            const result = (0, validation_1.validateFilePath)('/tmp/test.txt', 'read');
            expect(result).toBe(path.normalize('/tmp/test.txt'));
        });
        it('should reject empty file paths', () => {
            expect(() => (0, validation_1.validateFilePath)('', 'read')).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateFilePath)('', 'read')).toThrow('File path must be a non-empty string');
        });
        it('should reject null/undefined file paths', () => {
            expect(() => (0, validation_1.validateFilePath)(null, 'read')).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateFilePath)(undefined, 'read')).toThrow(validation_1.ValidationError);
        });
        it('should reject path traversal attempts', () => {
            expect(() => (0, validation_1.validateFilePath)('../../../etc/passwd', 'read')).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateFilePath)('../../../etc/passwd', 'read')).toThrow('Path traversal detected');
        });
        it('should reject non-existent files for read', () => {
            fs.existsSync.mockReturnValue(false);
            expect(() => (0, validation_1.validateFilePath)('/tmp/nonexistent.txt', 'read')).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateFilePath)('/tmp/nonexistent.txt', 'read')).toThrow('File not found');
        });
        it('should reject non-existent directories for write', () => {
            fs.existsSync.mockReturnValue(false);
            expect(() => (0, validation_1.validateFilePath)('/nonexistent/dir/file.txt', 'write')).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateFilePath)('/nonexistent/dir/file.txt', 'write')).toThrow('Directory not found');
        });
    });
    describe('validateSearchQuery', () => {
        it('should accept valid search queries', () => {
            expect((0, validation_1.validateSearchQuery)('test query')).toBe('test query');
            expect((0, validation_1.validateSearchQuery)('  spaces  ')).toBe('spaces');
        });
        it('should escape SQL wildcards', () => {
            expect((0, validation_1.validateSearchQuery)('test%query')).toBe('test\\%query');
            expect((0, validation_1.validateSearchQuery)('test_query')).toBe('test\\_query');
        });
        it('should reject empty queries', () => {
            expect(() => (0, validation_1.validateSearchQuery)('')).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateSearchQuery)('   ')).toThrow('Search query cannot be empty');
        });
        it('should reject null/undefined queries', () => {
            expect(() => (0, validation_1.validateSearchQuery)(null)).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateSearchQuery)(undefined)).toThrow(validation_1.ValidationError);
        });
        it('should reject queries that are too long', () => {
            const longQuery = 'a'.repeat(1001);
            expect(() => (0, validation_1.validateSearchQuery)(longQuery)).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateSearchQuery)(longQuery)).toThrow('Search query too long');
        });
    });
    describe('validateSessionName', () => {
        it('should accept valid session names', () => {
            expect((0, validation_1.validateSessionName)('My Session')).toBe('My Session');
            expect((0, validation_1.validateSessionName)('  Trimmed  ')).toBe('Trimmed');
        });
        it('should reject empty session names', () => {
            expect(() => (0, validation_1.validateSessionName)('')).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateSessionName)('   ')).toThrow('Session name cannot be empty');
        });
        it('should reject null/undefined session names', () => {
            expect(() => (0, validation_1.validateSessionName)(null)).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateSessionName)(undefined)).toThrow(validation_1.ValidationError);
        });
        it('should reject session names that are too long', () => {
            const longName = 'a'.repeat(256);
            expect(() => (0, validation_1.validateSessionName)(longName)).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateSessionName)(longName)).toThrow('Session name too long');
        });
    });
    describe('validateKey', () => {
        it('should accept valid keys', () => {
            expect((0, validation_1.validateKey)('my_key')).toBe('my_key');
            expect((0, validation_1.validateKey)('valid_key_123')).toBe('valid_key_123');
            expect((0, validation_1.validateKey)('key-with-hyphens')).toBe('key-with-hyphens');
            expect((0, validation_1.validateKey)('key.with.dots')).toBe('key.with.dots');
            expect((0, validation_1.validateKey)('path/to/key')).toBe('path/to/key');
            expect((0, validation_1.validateKey)('namespace:key')).toBe('namespace:key');
        });
        it('should reject keys with leading or trailing whitespace', () => {
            expect(() => (0, validation_1.validateKey)('  trimmed_key  ')).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateKey)(' leading_space')).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateKey)('trailing_space ')).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateKey)('\ttab_key')).toThrow(validation_1.ValidationError);
        });
        it('should reject empty keys', () => {
            expect(() => (0, validation_1.validateKey)('')).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateKey)('   ')).toThrow('Key cannot be empty');
        });
        it('should reject null/undefined keys', () => {
            expect(() => (0, validation_1.validateKey)(null)).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateKey)(undefined)).toThrow(validation_1.ValidationError);
        });
        it('should reject keys that are too long', () => {
            const longKey = 'k'.repeat(256);
            expect(() => (0, validation_1.validateKey)(longKey)).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateKey)(longKey)).toThrow('Key too long');
        });
    });
    describe('validateValue', () => {
        it('should accept valid values', () => {
            expect((0, validation_1.validateValue)('test value')).toBe('test value');
            expect((0, validation_1.validateValue)('')).toBe(''); // Empty values are allowed
        });
        it('should reject non-string values', () => {
            expect(() => (0, validation_1.validateValue)(123)).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateValue)(null)).toThrow('Value must be a string');
        });
        it('should reject values that are too large', () => {
            const largeValue = 'v'.repeat(1000001);
            expect(() => (0, validation_1.validateValue)(largeValue)).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateValue)(largeValue)).toThrow('Value too large');
        });
    });
    describe('validateCategory', () => {
        it('should accept valid categories', () => {
            expect((0, validation_1.validateCategory)('task')).toBe('task');
            expect((0, validation_1.validateCategory)('decision')).toBe('decision');
            expect((0, validation_1.validateCategory)('progress')).toBe('progress');
            expect((0, validation_1.validateCategory)('note')).toBe('note');
            expect((0, validation_1.validateCategory)('error')).toBe('error');
            expect((0, validation_1.validateCategory)('warning')).toBe('warning');
            expect((0, validation_1.validateCategory)('git')).toBe('git');
            expect((0, validation_1.validateCategory)('system')).toBe('system');
        });
        it('should return undefined for empty category', () => {
            expect((0, validation_1.validateCategory)('')).toBeUndefined();
            expect((0, validation_1.validateCategory)(undefined)).toBeUndefined();
        });
        it('should reject invalid categories', () => {
            expect(() => (0, validation_1.validateCategory)('invalid')).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validateCategory)('invalid')).toThrow('Invalid category');
        });
    });
    describe('validatePriority', () => {
        it('should accept valid priorities', () => {
            expect((0, validation_1.validatePriority)('high')).toBe('high');
            expect((0, validation_1.validatePriority)('normal')).toBe('normal');
            expect((0, validation_1.validatePriority)('low')).toBe('low');
        });
        it('should default to normal for empty priority', () => {
            expect((0, validation_1.validatePriority)('')).toBe('normal');
            expect((0, validation_1.validatePriority)(undefined)).toBe('normal');
        });
        it('should reject invalid priorities', () => {
            expect(() => (0, validation_1.validatePriority)('urgent')).toThrow(validation_1.ValidationError);
            expect(() => (0, validation_1.validatePriority)('invalid')).toThrow('Invalid priority');
        });
    });
});
