| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- import sinon from 'sinon'
- import { beforeEach, describe, expect, it, vi } from 'vitest'
- import { Errors } from '@overleaf/object-persistor'
- const modulePath = '../../../app/js/LocalFileWriter.js'
- describe('LocalFileWriter', function () {
- const writeStream = 'writeStream'
- const readStream = 'readStream'
- const settings = { path: { uploadFolder: '/uploads' } }
- const fsPath = '/uploads/wombat'
- const filename = 'wombat'
- let stream, fs, LocalFileWriter
- beforeEach(async function () {
- fs = {
- createWriteStream: sinon.stub().returns(writeStream),
- promises: {
- unlink: sinon.stub().resolves(),
- },
- }
- stream = {
- pipeline: sinon.stub().yields(),
- }
- const ObjectPersistor = { Errors }
- vi.doMock('fs', () => ({
- default: fs,
- }))
- vi.doMock('stream', () => ({
- default: stream,
- }))
- vi.doMock('@overleaf/settings', () => ({
- default: settings,
- }))
- vi.doMock('@overleaf/metrics', () => ({
- default: {
- inc: sinon.stub(),
- Timer: sinon.stub().returns({ done: sinon.stub() }),
- },
- }))
- vi.doMock('@overleaf/object-persistor', () => ObjectPersistor)
- LocalFileWriter = (await import(modulePath)).default
- })
- describe('writeStream', function () {
- it('writes the stream to the upload folder', async function () {
- await new Promise(resolve => {
- LocalFileWriter.writeStream(readStream, filename, (err, path) => {
- expect(err).not.to.exist
- expect(fs.createWriteStream).to.have.been.calledWith(fsPath)
- expect(stream.pipeline).to.have.been.calledWith(
- readStream,
- writeStream
- )
- expect(path).to.equal(fsPath)
- resolve()
- })
- })
- })
- describe('when there is an error', function () {
- const error = new Error('not enough ketchup')
- beforeEach(function () {
- stream.pipeline.yields(error)
- })
- it('should wrap the error', async function () {
- await expect(
- LocalFileWriter.promises.writeStream(readStream, filename)
- ).to.be.rejected.and.eventually.have.property('cause', error)
- })
- it('should delete the temporary file', async function () {
- await expect(LocalFileWriter.promises.writeStream(readStream, filename))
- .to.be.rejected
- expect(fs.promises.unlink).to.have.been.calledWith(fsPath)
- })
- })
- })
- describe('deleteFile', function () {
- it('should unlink the file', async function () {
- await LocalFileWriter.promises.deleteFile(fsPath)
- expect(fs.promises.unlink).to.have.been.calledWith(fsPath)
- })
- it('should not call unlink with an empty path', async function () {
- await LocalFileWriter.promises.deleteFile('')
- expect(fs.promises.unlink).not.to.have.been.called
- })
- it('should not throw a error if the file does not exist', async function () {
- const error = new Error('file not found')
- error.code = 'ENOENT'
- fs.promises.unlink = sinon.stub().rejects(error)
- await LocalFileWriter.promises.deleteFile(fsPath)
- })
- it('should wrap the error', async function () {
- const error = new Error('failed to reticulate splines')
- fs.promises.unlink = sinon.stub().rejects(error)
- await expect(
- LocalFileWriter.promises.deleteFile(fsPath)
- ).to.be.rejectedWith(Errors.WriteError)
- })
- })
- })
|