import { describe, it, expect, vi } from 'vitest';
import { timingSafeEqual, validateNotionApiKey } from '../../src/utils/security.js';
describe('Security Utils', () => {
describe('timingSafeEqual', () => {
it('should return true for matching strings', () => {
const result = timingSafeEqual('test-token', 'test-token');
expect(result).toBe(true);
});
it('should return false for different strings', () => {
const result = timingSafeEqual('test-token', 'different-token');
expect(result).toBe(false);
});
it('should return false for strings of different lengths', () => {
const result = timingSafeEqual('short', 'longer-string');
expect(result).toBe(false);
});
it('should return false for empty strings', () => {
const result = timingSafeEqual('', '');
expect(result).toBe(false);
});
it('should handle special characters', () => {
const result = timingSafeEqual('tëst-tokën', 'tëst-tokën');
expect(result).toBe(true);
});
});
describe('validateNotionApiKey', () => {
it('should validate legacy secret_ format', () => {
const legacyKey = 'secret_' + 'a'.repeat(43);
const result = validateNotionApiKey(legacyKey);
expect(result.valid).toBe(true);
});
it('should validate new ntn_ format', () => {
const newKey = 'ntn_' + 'a'.repeat(20);
const result = validateNotionApiKey(newKey);
expect(result.valid).toBe(true);
});
it('should reject invalid format', () => {
const result = validateNotionApiKey('invalid-key');
expect(result.valid).toBe(false);
expect(result.error).toContain('Invalid Notion API key format');
});
it('should reject empty string', () => {
const result = validateNotionApiKey('');
expect(result.valid).toBe(false);
expect(result.error).toContain('API key is required');
});
it('should reject non-string input', () => {
const result = validateNotionApiKey(123 as any);
expect(result.valid).toBe(false);
expect(result.error).toContain('API key is required and must be a string');
});
it('should accept non-standard but reasonable format', () => {
const nonStandardKey = 'secret_' + 'a'.repeat(20);
const result = validateNotionApiKey(nonStandardKey);
expect(result.valid).toBe(true);
});
it('should reject too short keys', () => {
const shortKey = 'ntn_a';
const result = validateNotionApiKey(shortKey);
expect(result.valid).toBe(false);
expect(result.error).toContain('at least 10 characters long');
});
});
});