mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-07-07 09:51:37 +00:00
test(placeholders): add server coverage for placeholder creation, serialization, and query visibility
This commit is contained in:
parent
b01facc034
commit
96de890bdd
3 changed files with 209 additions and 0 deletions
|
|
@ -0,0 +1,78 @@
|
||||||
|
const { expect } = require('chai')
|
||||||
|
const { Sequelize } = require('sequelize')
|
||||||
|
const sinon = require('sinon')
|
||||||
|
|
||||||
|
const Database = require('../../../server/Database')
|
||||||
|
const ApiRouter = require('../../../server/routers/ApiRouter')
|
||||||
|
const SeriesController = require('../../../server/controllers/SeriesController')
|
||||||
|
const ApiCacheManager = require('../../../server/managers/ApiCacheManager')
|
||||||
|
const Auth = require('../../../server/Auth')
|
||||||
|
const Logger = require('../../../server/Logger')
|
||||||
|
const User = require('../../../server/models/User')
|
||||||
|
|
||||||
|
describe('SeriesController placeholders', () => {
|
||||||
|
/** @type {ApiRouter} */
|
||||||
|
let apiRouter
|
||||||
|
let library
|
||||||
|
let libraryFolder
|
||||||
|
let series
|
||||||
|
let user
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
global.ServerSettings = {}
|
||||||
|
Database.sequelize = new Sequelize({ dialect: 'sqlite', storage: ':memory:', logging: false })
|
||||||
|
Database.sequelize.uppercaseFirst = (str) => (str ? `${str[0].toUpperCase()}${str.substr(1)}` : '')
|
||||||
|
await Database.buildModels()
|
||||||
|
|
||||||
|
apiRouter = new ApiRouter({
|
||||||
|
auth: new Auth(),
|
||||||
|
apiCacheManager: new ApiCacheManager()
|
||||||
|
})
|
||||||
|
|
||||||
|
sinon.stub(Logger, 'warn')
|
||||||
|
|
||||||
|
library = await Database.libraryModel.create({ name: 'Test Library', mediaType: 'book' })
|
||||||
|
libraryFolder = await Database.libraryFolderModel.create({ path: '/test', libraryId: library.id })
|
||||||
|
series = await Database.seriesModel.create({ name: 'Test Series', libraryId: library.id })
|
||||||
|
|
||||||
|
user = await Database.userModel.create({
|
||||||
|
username: 'Admin',
|
||||||
|
type: 'admin',
|
||||||
|
isActive: true,
|
||||||
|
permissions: User.getDefaultPermissionsForUserType('admin'),
|
||||||
|
bookmarks: [],
|
||||||
|
extraData: { seriesHideFromContinueListening: [] }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
sinon.restore()
|
||||||
|
await Database.sequelize.sync({ force: true })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('creates placeholder items in a series', async () => {
|
||||||
|
expect(SeriesController.createPlaceholder).to.be.a('function')
|
||||||
|
|
||||||
|
const fakeReq = {
|
||||||
|
params: {
|
||||||
|
id: library.id,
|
||||||
|
seriesId: series.id
|
||||||
|
},
|
||||||
|
user,
|
||||||
|
body: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fakeRes = {
|
||||||
|
status: sinon.stub().returnsThis(),
|
||||||
|
json: sinon.spy(),
|
||||||
|
sendStatus: sinon.spy()
|
||||||
|
}
|
||||||
|
|
||||||
|
await SeriesController.createPlaceholder.bind(apiRouter)(fakeReq, fakeRes)
|
||||||
|
|
||||||
|
expect(fakeRes.json.calledOnce).to.be.true
|
||||||
|
const payload = fakeRes.json.firstCall.args[0]
|
||||||
|
expect(payload).to.include({ mediaType: 'book', isPlaceholder: true })
|
||||||
|
expect(payload.media.metadata.series.some((entry) => entry.id === series.id)).to.be.true
|
||||||
|
})
|
||||||
|
})
|
||||||
47
test/server/models/LibraryItem.placeholder.test.js
Normal file
47
test/server/models/LibraryItem.placeholder.test.js
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
const { expect } = require('chai')
|
||||||
|
const { Sequelize } = require('sequelize')
|
||||||
|
|
||||||
|
const Database = require('../../../server/Database')
|
||||||
|
|
||||||
|
describe('LibraryItem placeholder serialization', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
Database.sequelize = new Sequelize({ dialect: 'sqlite', storage: ':memory:', logging: false })
|
||||||
|
Database.sequelize.uppercaseFirst = (str) => (str ? `${str[0].toUpperCase()}${str.substr(1)}` : '')
|
||||||
|
await Database.buildModels()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await Database.sequelize.sync({ force: true })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('includes isPlaceholder in minified and expanded JSON', async () => {
|
||||||
|
const library = await Database.libraryModel.create({ name: 'Test Library', mediaType: 'book' })
|
||||||
|
const libraryFolder = await Database.libraryFolderModel.create({ path: '/test', libraryId: library.id })
|
||||||
|
|
||||||
|
const book = await Database.bookModel.create({
|
||||||
|
title: 'Placeholder Book',
|
||||||
|
audioFiles: [],
|
||||||
|
tags: [],
|
||||||
|
narrators: [],
|
||||||
|
genres: [],
|
||||||
|
chapters: []
|
||||||
|
})
|
||||||
|
|
||||||
|
const libraryItem = await Database.libraryItemModel.create({
|
||||||
|
libraryFiles: [],
|
||||||
|
mediaId: book.id,
|
||||||
|
mediaType: 'book',
|
||||||
|
libraryId: library.id,
|
||||||
|
libraryFolderId: libraryFolder.id,
|
||||||
|
isPlaceholder: true
|
||||||
|
})
|
||||||
|
|
||||||
|
const expanded = await Database.libraryItemModel.getExpandedById(libraryItem.id)
|
||||||
|
|
||||||
|
const minifiedJson = expanded.toOldJSONMinified()
|
||||||
|
const expandedJson = expanded.toOldJSONExpanded()
|
||||||
|
|
||||||
|
expect(minifiedJson).to.have.property('isPlaceholder', true)
|
||||||
|
expect(expandedJson).to.have.property('isPlaceholder', true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
const { expect } = require('chai')
|
||||||
|
const { Sequelize } = require('sequelize')
|
||||||
|
|
||||||
|
const Database = require('../../../../server/Database')
|
||||||
|
const libraryItemsBookFilters = require('../../../../server/utils/queries/libraryItemsBookFilters')
|
||||||
|
const User = require('../../../../server/models/User')
|
||||||
|
|
||||||
|
describe('libraryItemsBookFilters placeholders', () => {
|
||||||
|
let library
|
||||||
|
let libraryFolder
|
||||||
|
let user
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
Database.sequelize = new Sequelize({ dialect: 'sqlite', storage: ':memory:', logging: false })
|
||||||
|
Database.sequelize.uppercaseFirst = (str) => (str ? `${str[0].toUpperCase()}${str.substr(1)}` : '')
|
||||||
|
await Database.buildModels()
|
||||||
|
|
||||||
|
library = await Database.libraryModel.create({ name: 'Test Library', mediaType: 'book' })
|
||||||
|
libraryFolder = await Database.libraryFolderModel.create({ path: '/test', libraryId: library.id })
|
||||||
|
user = await Database.userModel.create({
|
||||||
|
username: 'Admin',
|
||||||
|
type: 'admin',
|
||||||
|
isActive: true,
|
||||||
|
permissions: User.getDefaultPermissionsForUserType('admin'),
|
||||||
|
bookmarks: [],
|
||||||
|
extraData: { seriesHideFromContinueListening: [] }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await Database.sequelize.sync({ force: true })
|
||||||
|
})
|
||||||
|
|
||||||
|
const createBookWithItem = async ({ title, isPlaceholder }) => {
|
||||||
|
const book = await Database.bookModel.create({
|
||||||
|
title,
|
||||||
|
audioFiles: [],
|
||||||
|
tags: [],
|
||||||
|
narrators: [],
|
||||||
|
genres: [],
|
||||||
|
chapters: []
|
||||||
|
})
|
||||||
|
|
||||||
|
return Database.libraryItemModel.create({
|
||||||
|
libraryFiles: [],
|
||||||
|
mediaId: book.id,
|
||||||
|
mediaType: 'book',
|
||||||
|
libraryId: library.id,
|
||||||
|
libraryFolderId: libraryFolder.id,
|
||||||
|
isPlaceholder
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
it('excludes placeholders from general library list queries', async () => {
|
||||||
|
await createBookWithItem({ title: 'Real Book', isPlaceholder: false })
|
||||||
|
await createBookWithItem({ title: 'Placeholder Book', isPlaceholder: true })
|
||||||
|
|
||||||
|
const { libraryItems, count } = await libraryItemsBookFilters.getFilteredLibraryItems(
|
||||||
|
library.id,
|
||||||
|
user,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
'addedAt',
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
[],
|
||||||
|
20,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(count).to.equal(1)
|
||||||
|
expect(libraryItems).to.have.length(1)
|
||||||
|
expect(libraryItems[0].media.title).to.equal('Real Book')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('excludes placeholders from search results', async () => {
|
||||||
|
await createBookWithItem({ title: 'Real Book', isPlaceholder: false })
|
||||||
|
await createBookWithItem({ title: 'Placeholder Book', isPlaceholder: true })
|
||||||
|
|
||||||
|
const results = await libraryItemsBookFilters.search(user, library, 'Placeholder', 20, 0)
|
||||||
|
|
||||||
|
expect(results.book).to.have.length(0)
|
||||||
|
})
|
||||||
|
})
|
||||||
Loading…
Add table
Add a link
Reference in a new issue