library-pages.test.js 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. import test from 'node:test';
  2. import assert from 'node:assert/strict';
  3. import { createLibraryPageReader } from '../src/services/library-pages.js';
  4. function legacyReader(total = 474) {
  5. const calls = [];
  6. const read = async request => {
  7. calls.push(request);
  8. if (Object.hasOwn(request, 'page')) throw Object.assign(Error('old interface'), { code: 'UNKNOWN_REQUEST_FIELD' });
  9. const offset = Number(request.cursor || 0), end = Math.min(total, offset + request.limit);
  10. return { generation: 'g1', totalMatched: total, records: Array.from({ length: end - offset }, (_, i) => ({ record_id: `jd:${offset + i}` })), nextCursor: end < total ? String(end) : null };
  11. };
  12. return { calls, read };
  13. }
  14. test('新版读取器直接按页读取一次,不走游标兼容路径', async () => {
  15. const pager = createLibraryPageReader();let calls = 0;
  16. const result = await pager({ op: 'browse', page: 50, limit: 24 }, async request => { calls++;return { page: request.page, totalPages: 100 }; }, '/new');
  17. assert.equal(calls, 1);assert.equal(result.page, 50);
  18. });
  19. test('旧接口跨远页按100条跳读,并缓存精确范围/版本下的游标', async () => {
  20. const pager = createLibraryPageReader(), { read, calls } = legacyReader();
  21. const request = { op: 'browse', entity: 'products', filters: { brand: 'ksf' }, quality: 'audit', generation: 'g1', page: 1, limit: 24 };
  22. const first = await pager(request, read, '/legacy');assert.equal(first.records.length, 24);
  23. const last = await pager({ ...request, page: 999 }, read, '/legacy');
  24. assert.equal(last.page, 20);assert.equal(last.totalPages, 20);assert.equal(last.records.length, 18);
  25. assert.equal(last.records[0].record_id, 'jd:456');
  26. assert.ok(calls.length <= 8);assert.ok(calls.some(call => call.limit === 100));
  27. const before = calls.length;
  28. await pager({ ...request, page: 20 }, read, '/legacy');assert.equal(calls.length, before + 1);
  29. await pager({ ...request, filters: { brand: 'tongyi' }, page: 1 }, read, '/legacy');
  30. assert.ok(calls.at(-1).filters.brand === 'tongyi' && !calls.at(-1).cursor);
  31. });
  32. test('旧接口空范围正确显示0页,读取失败与代际变更不转成空页', async () => {
  33. const pager = createLibraryPageReader(), empty = legacyReader(0);
  34. const request = { op: 'browse', entity: 'products', page: 5, limit: 24, generation: 'g1' };
  35. const result = await pager(request, empty.read, '/empty');
  36. assert.deepEqual([result.page, result.totalPages, result.records], [1, 0, []]);
  37. const reader = legacyReader();let changed = false;
  38. const read = async request => { const result = await reader.read(request);return changed ? { ...result, generation: 'g2' } : result; };
  39. await pager({ ...request, page: 1 }, read, '/changes');changed = true;
  40. await assert.rejects(() => pager(request, read, '/changes'), { code: 'LIBRARY_VERSION_CHANGED' });
  41. await assert.rejects(() => createLibraryPageReader()(request, async () => { throw Object.assign(Error('读取失败'), { code: 'LIBRARY_BUSY' }); }, '/busy'), { code: 'LIBRARY_BUSY' });
  42. });