perf(directories): SQL-фильтрация/пагинация справочников, N+1, лимиты column-values
Шаги 1.1 и 1.2 плана production-готовности: - getDataTableRowsPaged: фильтры/поиск/сортировка/пагинация в SQL (values->>N) - getDataTablesWithAccess и list_directories без N+1 - /column-values: limit (дефолт 20, кап 1000), убраны debug-логи с горячего пути - tree-режим и legacy-путь TableEditor сохранены 1:1 - 10 новых тестов (88/88)
This commit is contained in:
74
tests/data-table-rows-query.test.ts
Normal file
74
tests/data-table-rows-query.test.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import {
|
||||
escapeIlikePattern,
|
||||
clampDirectoryRowsLimit,
|
||||
clampDirectoryRowsOffset,
|
||||
DIRECTORY_ROWS_DEFAULT_LIMIT,
|
||||
DIRECTORY_ROWS_MAX_LIMIT,
|
||||
} from '../server/utils/data-table-rows-query';
|
||||
|
||||
describe('escapeIlikePattern', () => {
|
||||
it('обычная строка не меняется', () => {
|
||||
expect(escapeIlikePattern('Казань')).toBe('Казань');
|
||||
expect(escapeIlikePattern('abc 123')).toBe('abc 123');
|
||||
});
|
||||
|
||||
it('экранирует %, _ и обратный слэш', () => {
|
||||
expect(escapeIlikePattern('100%')).toBe('100\\%');
|
||||
expect(escapeIlikePattern('a_b')).toBe('a\\_b');
|
||||
expect(escapeIlikePattern('a\\b')).toBe('a\\\\b');
|
||||
});
|
||||
|
||||
it('экранирует все вхождения', () => {
|
||||
expect(escapeIlikePattern('%_%\\')).toBe('\\%\\_\\%\\\\');
|
||||
});
|
||||
});
|
||||
|
||||
describe('clampDirectoryRowsLimit', () => {
|
||||
it('без значения — дефолт 100', () => {
|
||||
expect(clampDirectoryRowsLimit(undefined)).toBe(DIRECTORY_ROWS_DEFAULT_LIMIT);
|
||||
expect(clampDirectoryRowsLimit(null)).toBe(100);
|
||||
expect(clampDirectoryRowsLimit('')).toBe(100);
|
||||
});
|
||||
|
||||
it('неположительные и невалидные значения — дефолт', () => {
|
||||
expect(clampDirectoryRowsLimit(0)).toBe(100);
|
||||
expect(clampDirectoryRowsLimit(-10)).toBe(100);
|
||||
expect(clampDirectoryRowsLimit('abc')).toBe(100);
|
||||
expect(clampDirectoryRowsLimit(NaN)).toBe(100);
|
||||
});
|
||||
|
||||
it('принимает числа и числовые строки', () => {
|
||||
expect(clampDirectoryRowsLimit(50)).toBe(50);
|
||||
expect(clampDirectoryRowsLimit('25')).toBe(25);
|
||||
expect(clampDirectoryRowsLimit(1)).toBe(1);
|
||||
});
|
||||
|
||||
it('капает сверху на 1000', () => {
|
||||
expect(clampDirectoryRowsLimit(1001)).toBe(DIRECTORY_ROWS_MAX_LIMIT);
|
||||
expect(clampDirectoryRowsLimit('5000')).toBe(1000);
|
||||
});
|
||||
|
||||
it('поддерживает кастомные дефолт и максимум', () => {
|
||||
expect(clampDirectoryRowsLimit(undefined, 20, 500)).toBe(20);
|
||||
expect(clampDirectoryRowsLimit(700, 20, 500)).toBe(500);
|
||||
expect(clampDirectoryRowsLimit(30, 20, 500)).toBe(30);
|
||||
});
|
||||
});
|
||||
|
||||
describe('clampDirectoryRowsOffset', () => {
|
||||
it('без значения и невалидные — 0', () => {
|
||||
expect(clampDirectoryRowsOffset(undefined)).toBe(0);
|
||||
expect(clampDirectoryRowsOffset(null)).toBe(0);
|
||||
expect(clampDirectoryRowsOffset('')).toBe(0);
|
||||
expect(clampDirectoryRowsOffset(-5)).toBe(0);
|
||||
expect(clampDirectoryRowsOffset('xyz')).toBe(0);
|
||||
});
|
||||
|
||||
it('неотрицательные значения проходят, дробные — вниз', () => {
|
||||
expect(clampDirectoryRowsOffset(0)).toBe(0);
|
||||
expect(clampDirectoryRowsOffset(200)).toBe(200);
|
||||
expect(clampDirectoryRowsOffset('40')).toBe(40);
|
||||
expect(clampDirectoryRowsOffset(12.9)).toBe(12);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user