test: fix browse request option forwarding coverage

This commit is contained in:
Jonathan Finley 2026-03-13 21:32:56 -04:00
parent 3579341f6c
commit d28d96ff94
3 changed files with 94 additions and 6 deletions

View file

@ -393,9 +393,11 @@ module.exports = {
* @param {number} limit * @param {number} limit
* @param {number} offset * @param {number} offset
* @param {boolean} isHomePage for home page shelves * @param {boolean} isHomePage for home page shelves
* @param {{ cursor?: string|null, pageMode?: string, collapseseries?: boolean }} requestOptions
* @returns {{ libraryItems: import('../../models/LibraryItem')[], count: number }} * @returns {{ libraryItems: import('../../models/LibraryItem')[], count: number }}
*/ */
async getFilteredLibraryItems(libraryId, user, filterGroup, filterValue, sortBy, sortDesc, collapseseries, include, limit, offset, isHomePage = false) { async getFilteredLibraryItems(libraryId, user, filterGroup, filterValue, sortBy, sortDesc, collapseseries, include, limit, offset, isHomePage = false, requestOptions = {}) {
collapseseries = requestOptions.collapseseries ?? collapseseries
// TODO: Handle collapse sub-series // TODO: Handle collapse sub-series
if (filterGroup === 'series' && collapseseries) { if (filterGroup === 'series' && collapseseries) {
collapseseries = false collapseseries = false

View file

@ -141,9 +141,12 @@ module.exports = {
* @param {string[]} include * @param {string[]} include
* @param {number} limit * @param {number} limit
* @param {number} offset * @param {number} offset
* @param {{ cursor?: string|null, pageMode?: string, collapseseries?: boolean }} requestOptions
* @returns {Promise<{ libraryItems: import('../../models/LibraryItem')[], count: number }>} * @returns {Promise<{ libraryItems: import('../../models/LibraryItem')[], count: number }>}
*/ */
async getFilteredLibraryItems(libraryId, user, filterGroup, filterValue, sortBy, sortDesc, include, limit, offset) { async getFilteredLibraryItems(libraryId, user, filterGroup, filterValue, sortBy, sortDesc, include, limit, offset, requestOptions = {}) {
requestOptions.cursor = requestOptions.cursor || null
requestOptions.pageMode = requestOptions.pageMode || 'paged'
const includeRSSFeed = include.includes('rssfeed') const includeRSSFeed = include.includes('rssfeed')
const includeNumEpisodesIncomplete = include.includes('numepisodesincomplete') const includeNumEpisodesIncomplete = include.includes('numepisodesincomplete')

View file

@ -4,7 +4,8 @@ const sinon = require('sinon')
const Database = require('../../../server/Database') const Database = require('../../../server/Database')
const LibraryController = require('../../../server/controllers/LibraryController') const LibraryController = require('../../../server/controllers/LibraryController')
const libraryFilters = require('../../../server/utils/queries/libraryFilters') const libraryItemsBookFilters = require('../../../server/utils/queries/libraryItemsBookFilters')
const libraryItemsPodcastFilters = require('../../../server/utils/queries/libraryItemsPodcastFilters')
describe('LibraryController large-library browse contract', () => { describe('LibraryController large-library browse contract', () => {
beforeEach(async () => { beforeEach(async () => {
@ -80,8 +81,58 @@ describe('LibraryController large-library browse contract', () => {
}) })
}) })
it('forwards cursor, pageMode, and collapseseries through the real browse stack', async () => { it('uses forwarded browse request options inside the book query helper', async () => {
const getFilteredLibraryItemsStub = sinon.stub(libraryFilters, 'getFilteredLibraryItems').resolves({ const getOrderStub = sinon.stub(libraryItemsBookFilters, 'getOrder').returns([])
sinon.stub(libraryItemsBookFilters, 'getMediaGroupQuery').returns({ mediaWhere: {}, replacements: {} })
sinon.stub(libraryItemsBookFilters, 'getUserPermissionBookWhereQuery').returns({ bookWhere: [], replacements: {} })
sinon.stub(Database.bookModel, 'findAndCountAll').resolves({ rows: [], count: 0 })
await libraryItemsBookFilters.getFilteredLibraryItems(
'lib_1',
{ id: 'user_1', isAdminOrUp: false, canAccessExplicitContent: true, accessAllTags: true },
null,
null,
'media.metadata.title',
false,
false,
[],
40,
0,
false,
{ cursor: 'cursor-1', pageMode: 'endless', collapseseries: true }
)
expect(getOrderStub.firstCall.args[2]).to.equal(true)
})
it('uses forwarded browse request options inside the podcast query helper', async () => {
const requestOptions = { cursor: 'cursor-9' }
sinon.stub(libraryItemsPodcastFilters, 'getMediaGroupQuery').returns({ mediaWhere: {}, replacements: {} })
sinon.stub(libraryItemsPodcastFilters, 'getUserPermissionPodcastWhereQuery').returns({ podcastWhere: [], replacements: {} })
sinon.stub(libraryItemsPodcastFilters, 'getOrder').returns([])
sinon.stub(Database.podcastModel, 'findAndCountAll').resolves({ rows: [], count: 0 })
await libraryItemsPodcastFilters.getFilteredLibraryItems(
'lib_2',
{ id: 'user_2', canAccessExplicitContent: true, accessAllTags: true },
null,
null,
'media.metadata.title',
false,
[],
40,
0,
requestOptions
)
expect(requestOptions).to.deep.equal({
cursor: 'cursor-9',
pageMode: 'paged'
})
})
it('forwards cursor, pageMode, and collapseseries through libraryFilters into the book query helper', async () => {
const getFilteredLibraryItemsStub = sinon.stub(libraryItemsBookFilters, 'getFilteredLibraryItems').resolves({
libraryItems: [], libraryItems: [],
count: 0, count: 0,
nextCursor: 'cursor-2', nextCursor: 'cursor-2',
@ -105,10 +156,42 @@ describe('LibraryController large-library browse contract', () => {
} }
) )
expect(getFilteredLibraryItemsStub.firstCall.args[2]).to.include({ expect(getFilteredLibraryItemsStub.firstCall.args[11]).to.deep.equal({
cursor: 'cursor-1', cursor: 'cursor-1',
pageMode: 'endless', pageMode: 'endless',
collapseseries: true collapseseries: true
}) })
}) })
it('forwards cursor, pageMode, and collapseseries through libraryFilters into the podcast query helper', async () => {
const getFilteredLibraryItemsStub = sinon.stub(libraryItemsPodcastFilters, 'getFilteredLibraryItems').resolves({
libraryItems: [],
count: 0,
nextCursor: 'cursor-2',
paginationMode: 'keyset',
countMode: 'deferred-exact',
isCountDeferred: true
})
await Database.libraryItemModel.getByFilterAndSort(
{ id: 'lib_2', mediaType: 'podcast' },
{ id: 'user_2' },
{
sortBy: 'media.metadata.title',
limit: 40,
offset: 0,
cursor: 'cursor-9',
pageMode: 'endless',
include: [],
collapseseries: false,
mediaType: 'podcast'
}
)
expect(getFilteredLibraryItemsStub.firstCall.args[9]).to.deep.equal({
cursor: 'cursor-9',
pageMode: 'endless',
collapseseries: false
})
})
}) })