LibreChat / api /strategies /validators.spec.js
N.Achyuth Reddy
Upload 683 files
9705b6c
const { loginSchema, registerSchema, errorsToString } = require('./validators');
describe('Zod Schemas', () => {
describe('loginSchema', () => {
it('should validate a correct login object', () => {
const result = loginSchema.safeParse({
email: 'test@example.com',
password: 'password123',
});
expect(result.success).toBe(true);
});
it('should invalidate an incorrect email', () => {
const result = loginSchema.safeParse({
email: 'testexample.com',
password: 'password123',
});
expect(result.success).toBe(false);
});
it('should invalidate a short password', () => {
const result = loginSchema.safeParse({
email: 'test@example.com',
password: 'pass',
});
expect(result.success).toBe(false);
});
it('should handle email with unusual characters', () => {
const emails = ['test+alias@example.com', 'test@subdomain.example.co.uk'];
emails.forEach((email) => {
const result = loginSchema.safeParse({
email,
password: 'password123',
});
expect(result.success).toBe(true);
});
});
it('should invalidate email without a domain', () => {
const result = loginSchema.safeParse({
email: 'test@.com',
password: 'password123',
});
expect(result.success).toBe(false);
});
it('should invalidate password with only spaces', () => {
const result = loginSchema.safeParse({
email: 'test@example.com',
password: ' ',
});
expect(result.success).toBe(false);
});
it('should invalidate password that is too long', () => {
const result = loginSchema.safeParse({
email: 'test@example.com',
password: 'a'.repeat(129),
});
expect(result.success).toBe(false);
});
it('should invalidate empty email or password', () => {
const result = loginSchema.safeParse({
email: '',
password: '',
});
expect(result.success).toBe(false);
});
});
describe('registerSchema', () => {
it('should validate a correct register object', () => {
const result = registerSchema.safeParse({
name: 'John Doe',
username: 'john_doe',
email: 'john@example.com',
password: 'password123',
confirm_password: 'password123',
});
expect(result.success).toBe(true);
});
it('should allow the username to be omitted', () => {
const result = registerSchema.safeParse({
name: 'John Doe',
email: 'john@example.com',
password: 'password123',
confirm_password: 'password123',
});
expect(result.success).toBe(true);
});
it('should invalidate a short name', () => {
const result = registerSchema.safeParse({
name: 'Jo',
username: 'john_doe',
email: 'john@example.com',
password: 'password123',
confirm_password: 'password123',
});
expect(result.success).toBe(false);
});
it('should handle empty username by transforming to null', () => {
const result = registerSchema.safeParse({
name: 'John Doe',
username: '',
email: 'john@example.com',
password: 'password123',
confirm_password: 'password123',
});
expect(result.success).toBe(true);
expect(result.data.username).toBe(null);
});
it('should handle name with special characters', () => {
const names = ['Jöhn Dœ', 'John <Doe>'];
names.forEach((name) => {
const result = registerSchema.safeParse({
name,
username: 'john_doe',
email: 'john@example.com',
password: 'password123',
confirm_password: 'password123',
});
expect(result.success).toBe(true);
});
});
it('should handle username with special characters', () => {
const usernames = ['john.doe@', 'john..doe'];
usernames.forEach((username) => {
const result = registerSchema.safeParse({
name: 'John Doe',
username,
email: 'john@example.com',
password: 'password123',
confirm_password: 'password123',
});
expect(result.success).toBe(true);
});
});
it('should invalidate mismatched password and confirm_password', () => {
const result = registerSchema.safeParse({
name: 'John Doe',
username: 'john_doe',
email: 'john@example.com',
password: 'password123',
confirm_password: 'password124',
});
expect(result.success).toBe(false);
});
it('should handle email without a TLD', () => {
const result = registerSchema.safeParse({
name: 'John Doe',
username: 'john_doe',
email: 'john@domain',
password: 'password123',
confirm_password: 'password123',
});
expect(result.success).toBe(false);
});
it('should handle email with multiple @ symbols', () => {
const result = registerSchema.safeParse({
name: 'John Doe',
username: 'john_doe',
email: 'john@domain@com',
password: 'password123',
confirm_password: 'password123',
});
expect(result.success).toBe(false);
});
it('should handle name that is too long', () => {
const result = registerSchema.safeParse({
name: 'a'.repeat(81),
username: 'john_doe',
email: 'john@example.com',
password: 'password123',
confirm_password: 'password123',
});
expect(result.success).toBe(false);
});
it('should handle username that is too long', () => {
const result = registerSchema.safeParse({
name: 'John Doe',
username: 'a'.repeat(81),
email: 'john@example.com',
password: 'password123',
confirm_password: 'password123',
});
expect(result.success).toBe(false);
});
it('should handle password or confirm_password that is too long', () => {
const result = registerSchema.safeParse({
name: 'John Doe',
username: 'john_doe',
email: 'john@example.com',
password: 'a'.repeat(129),
confirm_password: 'a'.repeat(129),
});
expect(result.success).toBe(false);
});
it('should handle password or confirm_password that is just spaces', () => {
const result = registerSchema.safeParse({
name: 'John Doe',
username: 'john_doe',
email: 'john@example.com',
password: ' ',
confirm_password: ' ',
});
expect(result.success).toBe(false);
});
it('should handle null values for fields', () => {
const result = registerSchema.safeParse({
name: null,
username: null,
email: null,
password: null,
confirm_password: null,
});
expect(result.success).toBe(false);
});
it('should handle undefined values for fields', () => {
const result = registerSchema.safeParse({
name: undefined,
username: undefined,
email: undefined,
password: undefined,
confirm_password: undefined,
});
expect(result.success).toBe(false);
});
it('should handle extra fields not defined in the schema', () => {
const result = registerSchema.safeParse({
name: 'John Doe',
username: 'john_doe',
email: 'john@example.com',
password: 'password123',
confirm_password: 'password123',
extraField: 'I shouldn\'t be here',
});
expect(result.success).toBe(true);
});
it('should handle username with special characters from various languages', () => {
const usernames = [
// General
'éèäöü',
// German
'Jöhn.Döe@',
'Jöhn_Ü',
'Jöhnß',
// French
'Jéan-Piérre',
'Élève',
'Fiançée',
'Mère',
// Spanish
'Niño',
'Señor',
'Muñoz',
// Portuguese
'João',
'Coração',
'Pão',
// Italian
'Pietro',
'Bambino',
'Forlì',
// Romanian
'Mâncare',
'Școală',
'Țară',
// Catalan
'Niç',
'Màquina',
'Çap',
// Swedish
'Fjärran',
'Skål',
'Öland',
// Norwegian
'Blåbær',
'Fjord',
'Årstid',
// Danish
'Flød',
'Søster',
'Århus',
// Icelandic
'Þór',
'Ætt',
'Öx',
// Turkish
'Şehir',
'Çocuk',
'Gözlük',
// Polish
'Łódź',
'Część',
'Świat',
// Czech
'Čaj',
'Řeka',
'Život',
// Slovak
'Kočka',
'Ľudia',
'Žaba',
// Croatian
'Čovjek',
'Šuma',
'Žaba',
// Hungarian
'Tűz',
'Ősz',
'Ünnep',
// Finnish
'Mäki',
'Yö',
'Äiti',
// Estonian
'Tänav',
'Öö',
'Ülikool',
// Latvian
'Ēka',
'Ūdens',
'Čempions',
// Lithuanian
'Ūsas',
'Ąžuolas',
'Čia',
// Dutch
'Maïs',
'Geërfd',
'Coördinatie',
];
const failingUsernames = usernames.reduce((acc, username) => {
const result = registerSchema.safeParse({
name: 'John Doe',
username,
email: 'john@example.com',
password: 'password123',
confirm_password: 'password123',
});
if (!result.success) {
acc.push({ username, error: result.error });
}
return acc;
}, []);
if (failingUsernames.length > 0) {
console.log('Failing Usernames:', failingUsernames);
}
expect(failingUsernames).toEqual([]);
});
it('should reject invalid usernames', () => {
const invalidUsernames = [
'Дмитрий', // Cyrillic characters
'محمد', // Arabic characters
'张伟', // Chinese characters
'john{doe}', // Contains `{` and `}`
'j', // Only one character
'a'.repeat(81), // More than 80 characters
'\' OR \'1\'=\'1\'; --', // SQL Injection
'{$ne: null}', // MongoDB Injection
'<script>alert("XSS")</script>', // Basic XSS
'"><script>alert("XSS")</script>', // XSS breaking out of an attribute
'"><img src=x onerror=alert("XSS")>', // XSS using an image tag
];
const passingUsernames = [];
const failingUsernames = invalidUsernames.reduce((acc, username) => {
const result = registerSchema.safeParse({
name: 'John Doe',
username,
email: 'john@example.com',
password: 'password123',
confirm_password: 'password123',
});
if (!result.success) {
acc.push({ username, error: result.error });
}
if (result.success) {
passingUsernames.push({ username });
}
return acc;
}, []);
expect(failingUsernames.length).toEqual(invalidUsernames.length); // They should match since all invalidUsernames should fail.
});
});
describe('errorsToString', () => {
it('should convert errors to string', () => {
const { error } = registerSchema.safeParse({
name: 'Jo',
username: 'john_doe',
email: 'john@example.com',
password: 'password123',
confirm_password: 'password123',
});
const result = errorsToString(error.errors);
expect(result).toBe('name: String must contain at least 3 character(s)');
});
});
});