mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-07-14 05:11:45 +00:00
Add tests for download path: LibraryItemController.download, fileUtils.downloadFile, zipHelpers.zipDirectoryPipe
This commit is contained in:
parent
e74dbf5f40
commit
def602a30a
3 changed files with 263 additions and 0 deletions
87
test/server/utils/zipHelpers.test.js
Normal file
87
test/server/utils/zipHelpers.test.js
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
const { expect } = require('chai')
|
||||
const sinon = require('sinon')
|
||||
const { PassThrough } = require('stream')
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
const os = require('os')
|
||||
const zipHelpers = require('../../../server/utils/zipHelpers')
|
||||
const Logger = require('../../../server/Logger')
|
||||
|
||||
describe('zipHelpers', () => {
|
||||
let tmpDir
|
||||
|
||||
beforeEach(() => {
|
||||
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'abs-zip-test-'))
|
||||
sinon.stub(Logger, 'info')
|
||||
sinon.stub(Logger, 'debug')
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore()
|
||||
fs.rmSync(tmpDir, { recursive: true, force: true })
|
||||
})
|
||||
|
||||
describe('zipDirectoryPipe', () => {
|
||||
function makeMockRes() {
|
||||
const stream = new PassThrough()
|
||||
stream.attachment = sinon.spy()
|
||||
// zipDirectoryPipe resolves on 'close'. PassThrough emits 'finish' but not 'close'
|
||||
// automatically — destroy() triggers 'close', so bridge the two events here.
|
||||
stream.on('finish', () => stream.destroy())
|
||||
return stream
|
||||
}
|
||||
|
||||
it('should call res.attachment with the provided filename', async () => {
|
||||
fs.writeFileSync(path.join(tmpDir, 'book.mp3'), 'audio content')
|
||||
const res = makeMockRes()
|
||||
await zipHelpers.zipDirectoryPipe(tmpDir, 'my-book.zip', res)
|
||||
expect(res.attachment.calledWith('my-book.zip')).to.be.true
|
||||
})
|
||||
|
||||
it('should resolve and produce data for a non-empty directory', async () => {
|
||||
fs.writeFileSync(path.join(tmpDir, 'chapter1.mp3'), 'audio data chapter 1')
|
||||
fs.writeFileSync(path.join(tmpDir, 'chapter2.mp3'), 'audio data chapter 2')
|
||||
|
||||
const res = makeMockRes()
|
||||
const chunks = []
|
||||
res.on('data', (chunk) => chunks.push(chunk))
|
||||
|
||||
await zipHelpers.zipDirectoryPipe(tmpDir, 'book.zip', res)
|
||||
const totalBytes = chunks.reduce((sum, c) => sum + c.length, 0)
|
||||
expect(totalBytes).to.be.greaterThan(0)
|
||||
})
|
||||
|
||||
it('should resolve for an empty directory', async () => {
|
||||
const res = makeMockRes()
|
||||
// Should not throw
|
||||
await zipHelpers.zipDirectoryPipe(tmpDir, 'empty.zip', res)
|
||||
})
|
||||
|
||||
it('should produce a valid zip containing the expected files', async () => {
|
||||
fs.writeFileSync(path.join(tmpDir, 'test.txt'), 'Hello audiobookshelf')
|
||||
const res = makeMockRes()
|
||||
const chunks = []
|
||||
res.on('data', (chunk) => chunks.push(chunk))
|
||||
|
||||
await zipHelpers.zipDirectoryPipe(tmpDir, 'archive.zip', res)
|
||||
|
||||
// ZIP files start with the PK signature (0x50 0x4B)
|
||||
const combined = Buffer.concat(chunks)
|
||||
expect(combined[0]).to.equal(0x50) // 'P'
|
||||
expect(combined[1]).to.equal(0x4b) // 'K'
|
||||
})
|
||||
|
||||
it('should resolve (not throw) when the source directory does not exist', async () => {
|
||||
// archiver treats a missing directory as a warning (ENOENT), not a fatal error,
|
||||
// so zipDirectoryPipe resolves with an empty archive rather than rejecting.
|
||||
const res = makeMockRes()
|
||||
let threw = false
|
||||
try {
|
||||
await zipHelpers.zipDirectoryPipe('/nonexistent/path/that/does/not/exist', 'fail.zip', res)
|
||||
} catch (e) {
|
||||
threw = true
|
||||
}
|
||||
expect(threw).to.be.false
|
||||
})
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue