105 lines
3.8 KiB
JavaScript
105 lines
3.8 KiB
JavaScript
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
|
|
const {
|
|
buildSearchFilter,
|
|
buildSortOrderClause,
|
|
fetchPagedRows,
|
|
findTopLevelOrderByIndex,
|
|
normalizePageNumber,
|
|
normalizeSortDirection,
|
|
parseJsonSafe,
|
|
readFormArray
|
|
} = require('../src/data/utils');
|
|
|
|
test('parseJsonSafe returns null for invalid JSON and preserves objects', () => {
|
|
assert.equal(parseJsonSafe(''), null);
|
|
assert.equal(parseJsonSafe('not-json'), null);
|
|
assert.deepEqual(parseJsonSafe('{"value":true}'), { value: true });
|
|
const value = { nested: ['a'] };
|
|
assert.equal(parseJsonSafe(value), value);
|
|
});
|
|
|
|
test('readFormArray always returns an array shape', () => {
|
|
assert.deepEqual(readFormArray({}, 'roles'), []);
|
|
assert.deepEqual(readFormArray({ roles: 'admin' }, 'roles'), ['admin']);
|
|
assert.deepEqual(readFormArray({ roles: ['admin', 'editor'] }, 'roles'), ['admin', 'editor']);
|
|
});
|
|
|
|
test('normalize helpers clamp pagination and sort direction', () => {
|
|
assert.equal(normalizePageNumber('0'), 1);
|
|
assert.equal(normalizePageNumber('3.9'), 3);
|
|
assert.equal(normalizePageNumber('abc'), 1);
|
|
assert.equal(normalizeSortDirection('DESC'), 'desc');
|
|
assert.equal(normalizeSortDirection('anything else'), 'asc');
|
|
});
|
|
|
|
test('buildSortOrderClause applies multiple columns and ignores unknown keys', () => {
|
|
assert.deepEqual(buildSortOrderClause({ name: 'title' }, 'name', 'desc'), {
|
|
clause: ' ORDER BY title DESC',
|
|
sortKey: 'name',
|
|
sortDirection: 'desc'
|
|
});
|
|
assert.deepEqual(buildSortOrderClause({ name: ['title', 'id'] }, 'name', 'asc'), {
|
|
clause: ' ORDER BY title ASC, id ASC',
|
|
sortKey: 'name',
|
|
sortDirection: 'asc'
|
|
});
|
|
assert.deepEqual(buildSortOrderClause({ name: 'title' }, 'missing', 'desc'), {
|
|
clause: '',
|
|
sortKey: 'missing',
|
|
sortDirection: 'desc'
|
|
});
|
|
});
|
|
|
|
test('buildSearchFilter generates escaped LIKE clauses', () => {
|
|
assert.deepEqual(buildSearchFilter(['name', 'description'], '100%_ready'), {
|
|
clause: " WHERE (LOWER(COALESCE(CAST(name AS CHAR), '')) LIKE ? ESCAPE '\\\\' OR LOWER(COALESCE(CAST(description AS CHAR), '')) LIKE ? ESCAPE '\\\\')",
|
|
params: ['%100\\%\\_ready%', '%100\\%\\_ready%']
|
|
});
|
|
assert.deepEqual(buildSearchFilter([], 'anything'), { clause: '', params: [] });
|
|
});
|
|
|
|
test('findTopLevelOrderByIndex skips nested subqueries', () => {
|
|
const sql = 'SELECT * FROM (SELECT * FROM items ORDER BY created_at DESC) AS nested ORDER BY id ASC';
|
|
assert.equal(findTopLevelOrderByIndex(sql), sql.lastIndexOf('ORDER BY id ASC'));
|
|
});
|
|
|
|
test('fetchPagedRows combines search, ordering, and pagination parameters', async () => {
|
|
const queries = [];
|
|
const pool = {
|
|
async query(sql, params) {
|
|
queries.push({ sql, params });
|
|
if (sql.startsWith('SELECT COUNT(*)')) {
|
|
return [[{ count: 3 }]];
|
|
}
|
|
return [[{ id: 1 }]];
|
|
}
|
|
};
|
|
|
|
const result = await fetchPagedRows(pool, {
|
|
selectSql: 'SELECT id, name FROM items WHERE active = 1 ORDER BY name ASC',
|
|
countSql: 'SELECT COUNT(*) AS count FROM items WHERE active = 1',
|
|
params: ['active'],
|
|
searchColumns: ['name'],
|
|
searchTerm: 'alpha',
|
|
sortColumns: { name: 'name' },
|
|
sortKey: 'name',
|
|
sortDirection: 'desc',
|
|
pageSize: 2,
|
|
page: 2
|
|
});
|
|
|
|
assert.deepEqual(result, {
|
|
rows: [{ id: 1 }],
|
|
totalItems: 3,
|
|
totalPages: 2,
|
|
currentPage: 2,
|
|
pageSize: 2
|
|
});
|
|
assert.equal(queries.length, 2);
|
|
assert.equal(queries[0].sql, "SELECT COUNT(*) AS count FROM (SELECT id, name FROM items WHERE active = 1 AND (LOWER(COALESCE(CAST(name AS CHAR), '')) LIKE ? ESCAPE '\\\\')) AS filtered_rows");
|
|
assert.deepEqual(queries[0].params, ['active', '%alpha%']);
|
|
assert.equal(queries[1].sql, "SELECT id, name FROM items WHERE active = 1 AND (LOWER(COALESCE(CAST(name AS CHAR), '')) LIKE ? ESCAPE '\\\\') ORDER BY name DESC LIMIT ? OFFSET ?");
|
|
assert.deepEqual(queries[1].params, ['active', '%alpha%', 2, 2]);
|
|
}); |