UNPKG

als-mongo-list

Version:

A flexible, lightweight MongoDB query utility for Node.js applications. Simplifies database operations with intuitive filtering, pagination, sorting, and field selection. Ideal for REST API endpoints, providing a primary List class that abstracts complex

243 lines (213 loc) 9.48 kB
const Filter = require('../lib/filter/filter'); // Обновите путь к файлу Filter const assert = require('node:assert'); const { describe, it } = require('node:test'); const { Types: { ObjectId } } = require('mongoose'); describe('Filter', () => { const tree = { name: { type: String }, age: { type: Number, min: 18, max: 99 }, isActive: { type: Boolean }, userId: { type: ObjectId }, createdAt: { type: Date }, status: { type: String, enum: ['active', 'inactive', 'pending'] } }; const searchKeys = ['name', 'age', 'isActive', 'userId', 'createdAt', 'status']; const filter = new Filter({ tree, searchKeys }); describe('getSearch', () => { it('should create regex filter for String fields', () => { const query = { name: 'John' }; const search = filter.getSearch(query); assert.deepStrictEqual(search, { name: { $regex: 'John', $options: 'i' } }); }); it('should create range filters for Number fields', () => { const query = { age_gte: '18', age_lte: '30' }; const search = filter.getSearch(query); assert.deepStrictEqual(search, { age: { $gte: 18, $lte: 30 } }); }); it('should create boolean filter for Boolean fields', () => { const query = { isActive: 'true' }; const search = filter.getSearch(query); assert.deepStrictEqual(search, { isActive: true }); }); it('should create range filters for Date fields', () => { const dateFrom = '2022-01-01'; const dateTo = '2022-12-31'; const query = { createdAt_gte: dateFrom, createdAt_lte: dateTo }; const search = filter.getSearch(query); const expected = { createdAt: { $gte: new Date(dateFrom), $lte: new Date(dateTo) } } // console.log({search,expected}) assert.deepStrictEqual(search, expected); }); it('should ignore invalid ObjectId values', () => { const query = { userId: 'invalidObjectId' }; const search = filter.getSearch(query); assert.deepStrictEqual(search, {}); }); it('should create ObjectId filter for ObjectId fields', () => { const validId = new ObjectId().toString(); const query = { userId: validId }; const search = filter.getSearch(query); assert.deepStrictEqual(search, { userId: new ObjectId(validId) }); }); }); describe('validators and inputs initialization', () => { it('should initialize validators for each searchKey', () => { assert.strictEqual(typeof filter.validators.name, 'function'); assert.strictEqual(typeof filter.validators.age_gte, 'function'); assert.strictEqual(typeof filter.validators.age_lte, 'function'); assert.strictEqual(typeof filter.validators.isActive, 'function'); assert.strictEqual(typeof filter.validators.userId, 'function'); assert.strictEqual(typeof filter.validators.createdAt_gte, 'function'); assert.strictEqual(typeof filter.validators.createdAt_lte, 'function'); assert.strictEqual(typeof filter.validators.status, 'function'); }); it('should initialize inputs correctly based on field types', () => { const { name, age_gte, age_lte, isActive, userId, status } = filter.inputs; assert.deepStrictEqual(name, { tag: 'input', type: 'search', name: 'name' }); assert.deepStrictEqual(age_gte, { tag: 'input', type: 'number', name: 'age_gte', min: 18, max: 99, step: undefined }); assert.deepStrictEqual(age_lte, { tag: 'input', type: 'number', name: 'age_lte', min: 18, max: 99, step: undefined }); assert.deepStrictEqual(userId, { tag: 'input', type: 'text', name: 'userId' }); assert.deepStrictEqual(isActive, { tag: 'select', name: 'isActive', options: [ { value: '', text: 'all' }, { value: 'true', text: 'true' }, { value: 'false', text: 'false' } ] }); assert.deepStrictEqual(status, { tag: 'select', name: 'status', options: [ { value: 'active', text: 'active' }, { value: 'inactive', text: 'inactive' }, { value: 'pending', text: 'pending' } ] }); }); }); describe('Additional tests', () => { const treeWithEnums = { status: { type: String, enum: ['active', 'inactive'], default: 'inactive' }, category: { type: String } }; it('should set input attributes for enums and other fields', () => { const customFilter = new Filter({ tree: treeWithEnums, searchKeys: ['status', 'category'] }); assert.deepStrictEqual(customFilter.inputs.status, { tag: 'select', name: 'status', options: [ { value: 'active', text: 'active' }, { value: 'inactive', text: 'inactive' } ] }); assert.deepStrictEqual(customFilter.inputs.category, { tag: 'input', type: 'search', name: 'category' }); }); }); describe('Additional and edge case tests', () => { it('should handle empty query gracefully', () => { const query = {}; const search = filter.getSearch(query); assert.deepStrictEqual(search, {}); }); it('should create range filters for Number fields with boundary values', () => { const query = { age_gte: '18', age_lte: '99' }; const search = filter.getSearch(query); assert.deepStrictEqual(search, { age: { $gte: 18, $lte: 99 } }); }); it('should ignore invalid range for Number fields', () => { const query = { age_gte: 'abc', age_lte: 'xyz' }; const search = filter.getSearch(query); assert.deepStrictEqual(search, {}); }); it('should create boolean filter for Boolean fields with "false"', () => { const query = { isActive: 'false' }; const search = filter.getSearch(query); assert.deepStrictEqual(search, { isActive: false }); }); it('should handle non-boolean values for Boolean fields', () => { const query = { isActive: 'yes' }; const search = filter.getSearch(query); assert.deepStrictEqual(search, { isActive: true }); }); it('should ignore invalid Date values', () => { const query = { createdAt_gte: 'invalid-date', createdAt_lte: 'another-invalid-date' }; const search = filter.getSearch(query); assert.deepStrictEqual(search, {}); }); it('should handle multiple filters in a single query', () => { const query = { name: 'John', age_gte: '25', createdAt_gte: '2022-01-01', isActive: 'true' }; const search = filter.getSearch(query); const expected = { name: { $regex: 'John', $options: 'i' }, age: { $gte: 25 }, createdAt: { $gte: new Date(Date.UTC(2022, 0, 1)) }, isActive: true }; assert.deepStrictEqual(search, expected); }); it('should ignore unsupported keys in the query', () => { const query = { unsupportedKey: 'value' }; const search = filter.getSearch(query); assert.deepStrictEqual(search, {}); }); it('should handle empty strings as query values gracefully', () => { const query = { name: '' }; const search = filter.getSearch(query); assert.deepStrictEqual(search, {}); }); it('should handle null or undefined values in the query', () => { const query = { name: null, age_gte: undefined }; const search = filter.getSearch(query); assert.deepStrictEqual(search, {}); }); }); }); describe('Filter date inputs', () => { it('should have select input with default date options', () => { const tree = { createdAt: { type: Date } }; const searchKeys = ['createdAt']; const filter = new Filter({ tree, searchKeys }); assert.deepStrictEqual(filter.inputs, { createdAt_gte: { tag: 'input', type: 'date', name: 'createdAt_gte', key: 'createdAt' }, createdAt_lte: { tag: 'input', type: 'date', name: 'createdAt_lte', key: 'createdAt' } }) }); }); describe('Filter few strings', () => { const tree = { title: { type: String }, description: { type: String }, keywords: [{ type: String }], }; const searchKeys = ['title', 'description', 'keywords']; const filter = new Filter({ tree, searchKeys }); it('basic search', () => { const search = filter.getSearch({ search: 'John', title: 'true', description: 'true', keywords: 'true' }) assert.deepStrictEqual(search, { $or: [ {title: {$regex: "John",$options: "i"}}, {description: {$regex: "John",$options: "i"}}, {keywords: {$regex: "John",$options: "i"}} ] }) }) });