| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- import Client from './helpers/Client.js'
- import ClsiApp from './helpers/ClsiApp.js'
- import Path from 'node:path'
- import fs from 'node:fs'
- import { pipeline } from 'node:stream/promises'
- import { buffer } from 'node:stream/consumers'
- import yauzl from 'yauzl'
- import { expect } from 'chai'
- import { fetchStreamWithResponse } from '@overleaf/fetch-utils'
- import Settings from '@overleaf/settings'
- describe('Conversions', function () {
- describe('docx conversion', function () {
- before(async function () {
- await ClsiApp.ensureRunning()
- try {
- this.body = await Client.compile(this.project_id, this.request)
- } catch (error) {
- this.error = error
- }
- })
- it('should convert file to docx', async function () {
- const sourcePath = Path.join(
- import.meta.dirname,
- '../fixtures/conversion-source.docx'
- )
- const outputStream = fs.createWriteStream(
- '/tmp/clsi_acceptance_tests_' + crypto.randomUUID() + '.zip'
- )
- const { stream } = await Client.convertDocument(sourcePath, 'docx')
- await pipeline(stream, outputStream)
- await new Promise((resolve, reject) => {
- yauzl.open(outputStream.path, { lazyEntries: true }, (err, zipfile) => {
- if (err) {
- return reject(err)
- }
- zipfile.on('error', reject)
- zipfile.on('end', resolve)
- zipfile.readEntry()
- zipfile.on('entry', entry => {
- if (entry.fileName === 'main.tex') {
- zipfile.openReadStream(entry, (err, readStream) => {
- if (err) {
- return reject(err)
- }
- let data = ''
- readStream.on('data', chunk => {
- data += chunk.toString()
- })
- readStream.on('end', () => {
- try {
- expect(data).to.include('\\begin{document}')
- expect(data).to.include(
- '\\[x = \\frac{- b \\pm \\sqrt{b^{2} - 4ac}}{2a}\\]'
- )
- zipfile.readEntry()
- } catch (err) {
- reject(err)
- }
- })
- })
- } else if (entry.fileName === 'media/') {
- // Skip the media directory entry
- zipfile.readEntry()
- } else if (entry.fileName.startsWith('media/')) {
- expect(entry.fileName).to.equal('media/image1.png')
- zipfile.readEntry()
- } else {
- reject(new Error('Unexpected file in zip: ' + entry.fileName))
- }
- })
- })
- })
- })
- it('should fail with 422 and surface pandoc stderr when file is not a docx', async function () {
- const sourcePath = Path.join(
- import.meta.dirname,
- '../fixtures/minimal.pdf'
- )
- const { status, body } = await Client.convertDocument(sourcePath, 'docx')
- expect(status).to.equal(422)
- expect(body.error).to.include("couldn't unpack docx container")
- })
- })
- describe('project-to-document conversion (responseFormat=json)', function () {
- before(async function () {
- await ClsiApp.ensureRunning()
- })
- it('returns ids and serves the docx output via nginx', async function () {
- const projectId = Client.randomId()
- const userId = '0123456789abcdef01234567'
- const request = {
- rootResourcePath: 'main.tex',
- resources: [
- {
- path: 'main.tex',
- content: `\
- \\documentclass{article}
- \\begin{document}
- Hello world
- \\end{document}\
- `,
- },
- ],
- }
- const { conversionId, buildId, file } =
- await Client.convertProjectToDocument(
- projectId,
- userId,
- 'docx',
- request,
- 'json'
- )
- expect(conversionId).to.match(
- /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/
- )
- expect(buildId).to.match(/^[0-9a-f]+-[0-9a-f]+$/)
- const downloadUrl = new URL(Settings.apis.clsi.downloadHost)
- downloadUrl.pathname = `/project/${conversionId}/build/${buildId}/output/${file}`
- const { stream, response } = await fetchStreamWithResponse(
- downloadUrl.href
- )
- expect(response.status).to.equal(200)
- const body = await buffer(stream)
- expect(body.length).to.be.greaterThan(0)
- // .docx is a zip archive — verify the PK\x03\x04 magic bytes
- expect(body[0]).to.equal(0x50)
- expect(body[1]).to.equal(0x4b)
- expect(body[2]).to.equal(0x03)
- expect(body[3]).to.equal(0x04)
- })
- })
- })
|