mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-07-07 09:51:37 +00:00
219 lines
6.2 KiB
JavaScript
219 lines
6.2 KiB
JavaScript
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 secondaryLibraryFolder
|
|
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 })
|
|
secondaryLibraryFolder = await Database.libraryFolderModel.create({ path: '/secondary', 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
|
|
})
|
|
|
|
it('rejects cover url payloads for placeholder creation', async () => {
|
|
const fakeReq = {
|
|
params: {
|
|
id: library.id,
|
|
seriesId: series.id
|
|
},
|
|
user,
|
|
body: {
|
|
url: 'http://example.com/cover.jpg'
|
|
}
|
|
}
|
|
|
|
const fakeRes = {
|
|
status: sinon.stub().returnsThis(),
|
|
json: sinon.spy(),
|
|
send: sinon.spy(),
|
|
sendStatus: sinon.spy()
|
|
}
|
|
|
|
await SeriesController.createPlaceholder.bind(apiRouter)(fakeReq, fakeRes)
|
|
|
|
expect(fakeRes.status.calledWith(400)).to.be.true
|
|
expect(fakeRes.send.calledWith('Cover uploads are not supported for placeholders')).to.be.true
|
|
})
|
|
|
|
it('rejects cover file payloads for placeholder creation', async () => {
|
|
const fakeReq = {
|
|
params: {
|
|
id: library.id,
|
|
seriesId: series.id
|
|
},
|
|
user,
|
|
body: {},
|
|
files: {
|
|
cover: {
|
|
name: 'cover.jpg'
|
|
}
|
|
}
|
|
}
|
|
|
|
const fakeRes = {
|
|
status: sinon.stub().returnsThis(),
|
|
json: sinon.spy(),
|
|
send: sinon.spy(),
|
|
sendStatus: sinon.spy()
|
|
}
|
|
|
|
await SeriesController.createPlaceholder.bind(apiRouter)(fakeReq, fakeRes)
|
|
|
|
expect(fakeRes.status.calledWith(400)).to.be.true
|
|
expect(fakeRes.send.calledWith('Cover uploads are not supported for placeholders')).to.be.true
|
|
})
|
|
|
|
it('uses the series library folder when creating a placeholder', async () => {
|
|
const existingBook = await Database.bookModel.create({
|
|
title: 'Existing Book',
|
|
audioFiles: [],
|
|
tags: [],
|
|
narrators: [],
|
|
genres: [],
|
|
chapters: []
|
|
})
|
|
await Database.bookSeriesModel.create({ bookId: existingBook.id, seriesId: series.id })
|
|
await Database.libraryItemModel.create({
|
|
libraryFiles: [],
|
|
mediaId: existingBook.id,
|
|
mediaType: 'book',
|
|
libraryId: library.id,
|
|
libraryFolderId: secondaryLibraryFolder.id
|
|
})
|
|
|
|
const fakeReq = {
|
|
params: {
|
|
id: library.id,
|
|
seriesId: series.id
|
|
},
|
|
user,
|
|
body: {}
|
|
}
|
|
|
|
const fakeRes = {
|
|
status: sinon.stub().returnsThis(),
|
|
json: sinon.spy(),
|
|
sendStatus: sinon.spy(),
|
|
send: 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.folderId).to.equal(secondaryLibraryFolder.id)
|
|
expect(payload.path.startsWith(secondaryLibraryFolder.path)).to.be.true
|
|
})
|
|
|
|
it('honors a requested folderId when creating a placeholder', async () => {
|
|
const existingBook = await Database.bookModel.create({
|
|
title: 'Existing Book 2',
|
|
audioFiles: [],
|
|
tags: [],
|
|
narrators: [],
|
|
genres: [],
|
|
chapters: []
|
|
})
|
|
await Database.bookSeriesModel.create({ bookId: existingBook.id, seriesId: series.id })
|
|
await Database.libraryItemModel.create({
|
|
libraryFiles: [],
|
|
mediaId: existingBook.id,
|
|
mediaType: 'book',
|
|
libraryId: library.id,
|
|
libraryFolderId: secondaryLibraryFolder.id
|
|
})
|
|
|
|
const fakeReq = {
|
|
params: {
|
|
id: library.id,
|
|
seriesId: series.id
|
|
},
|
|
user,
|
|
body: {
|
|
folderId: libraryFolder.id
|
|
}
|
|
}
|
|
|
|
const fakeRes = {
|
|
status: sinon.stub().returnsThis(),
|
|
json: sinon.spy(),
|
|
sendStatus: sinon.spy(),
|
|
send: 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.folderId).to.equal(libraryFolder.id)
|
|
expect(payload.path.startsWith(libraryFolder.path)).to.be.true
|
|
})
|
|
})
|