diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-07 00:35:07 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-07 00:35:07 +0300 |
| commit | 1898db985f708f0ff54d04d2d77303c633bc1ba2 (patch) | |
| tree | f608db9059478d72673149a30dd5bfb650b1e025 /web | |
| parent | 9458bf6d9861a6e09c616c8d290cce56fc61ac9f (diff) | |
Fix podcast episode pagination arguments (p0)
Diffstat (limited to 'web')
| -rw-r--r-- | web/js/api.js | 15 | ||||
| -rw-r--r-- | web/js/tests/podcast-episodes-api.test.js | 74 |
2 files changed, 88 insertions, 1 deletions
diff --git a/web/js/api.js b/web/js/api.js index deabf20..28954a1 100644 --- a/web/js/api.js +++ b/web/js/api.js @@ -86,7 +86,20 @@ export const API = { delPermissions: (body) => api('/api/admin/permissions', { method: 'DELETE', body }), rescan: () => api('/api/admin/rescan', { method: 'POST' }), podcasts: () => api('/api/podcasts'), - podcastEpisodes: (setId, limit = 50, offset = 0) => { + podcastEpisodes: (setId, pagination, legacyOffset) => { + let limit = 50; + let offset = 0; + if (typeof pagination === 'number') { + if (typeof legacyOffset === 'number') { + limit = pagination; + offset = legacyOffset; + } else { + offset = pagination; + } + } else if (pagination) { + limit = pagination.limit ?? limit; + offset = pagination.offset ?? offset; + } const params = new URLSearchParams({ limit, offset }); return api(`/api/podcasts/${setId}/episodes?${params}`); }, diff --git a/web/js/tests/podcast-episodes-api.test.js b/web/js/tests/podcast-episodes-api.test.js new file mode 100644 index 0000000..d46d782 --- /dev/null +++ b/web/js/tests/podcast-episodes-api.test.js @@ -0,0 +1,74 @@ +import { API } from '../api.js'; + +const failures = []; +const requested = []; + +function assert(cond, msg) { + if (!cond) failures.push(msg || 'assertion failed'); +} + +globalThis.fetch = async (url) => { + requested.push(url); + return new Response('[]', { + status: 200, + headers: { 'content-type': 'application/json' }, + }); +}; + +globalThis.location = { pathname: '/', href: '' }; + +async function capturesUrl(fn) { + requested.length = 0; + await fn(); + return requested[0]; +} + +function paramsFrom(url) { + return new URL(url, 'http://player.test').searchParams; +} + +async function testDefaults() { + const params = paramsFrom(await capturesUrl(() => API.podcastEpisodes(5))); + assert(params.get('limit') === '50', 'default limit should be 50'); + assert(params.get('offset') === '0', 'default offset should be 0'); +} + +async function testSecondArgumentIsOffset() { + const params = paramsFrom(await capturesUrl(() => API.podcastEpisodes(5, 0))); + assert(params.get('limit') === '50', 'single numeric argument should keep default limit'); + assert(params.get('offset') === '0', 'single numeric argument should set explicit offset'); +} + +async function testOptionsObject() { + const params = paramsFrom(await capturesUrl(() => API.podcastEpisodes(5, { limit: 25, offset: 75 }))); + assert(params.get('limit') === '25', 'options object should set limit'); + assert(params.get('offset') === '75', 'options object should set offset'); +} + +async function testOptionsObjectKeepsZeroLimit() { + const params = paramsFrom(await capturesUrl(() => API.podcastEpisodes(5, { limit: 0 }))); + assert(params.get('limit') === '0', 'options object should preserve explicit zero limit'); + assert(params.get('offset') === '0', 'options object should default offset to 0'); +} + +async function testLegacyLimitOffset() { + const params = paramsFrom(await capturesUrl(() => API.podcastEpisodes(5, 10, 20))); + assert(params.get('limit') === '10', 'legacy third-argument form should preserve limit'); + assert(params.get('offset') === '20', 'legacy third-argument form should preserve offset'); +} + +console.log('Running podcast episodes API pagination tests...'); +await testDefaults(); +await testSecondArgumentIsOffset(); +await testOptionsObject(); +await testOptionsObjectKeepsZeroLimit(); +await testLegacyLimitOffset(); + +if (failures.length) { + console.error('FAILURES:'); + failures.forEach((m) => console.error(' - ' + m)); + process.exit(1); +} else { + console.log('All podcast episodes API pagination tests passed.'); + process.exit(0); +} |
