GooDrive/frontend/tests/upload-multipart.test.js
Louis Mazin ac44c6ed8b nice
2026-10-13 23:47:19 +02:00

76 lines
3.2 KiB
JavaScript

import test from 'node:test'
import assert from 'node:assert/strict'
import { readFile } from 'node:fs/promises'
// The live client uses Axios. This isolated test checks its request construction
// without needing a browser or an installed dependency tree.
const clientSource = await readFile(new URL('../src/api/client.js', import.meta.url), 'utf8')
const calls = []
const clients = []
globalThis.window ??= { location: { hostname: 'localhost' } }
globalThis.__goodDriveTestAxios = {
create(defaults) {
const instance = {
defaults,
interceptors: { request: { use() {} }, response: { use() {} } },
async post(url, body, config) {
calls.push({ url, body, config, defaults })
if (url.endsWith('/uploads/start/')) return { data: { id: 'test-upload-id', offset: 0 } }
if (url.endsWith('/chunk/')) {
return { data: { offset: Number(body.get('offset')) + body.get('part').size } }
}
return { data: { items: [] } }
},
}
clients.push(instance)
return instance
},
}
assert.match(clientSource, /import axios from ['"]axios['"]/, 'Unexpected Axios import')
const sourceWithMock = clientSource.replace(/import axios from ['"]axios['"]/, 'const axios = globalThis.__goodDriveTestAxios')
const { drive } = await import(`data:text/javascript;base64,${Buffer.from(sourceWithMock).toString('base64')}`)
function assertMultipartRequest(call) {
assert.ok(call.body instanceof FormData, `${call.url} must send FormData`)
assert.ok(
!Object.keys(call.defaults.headers ?? {}).some(key => key.toLowerCase() === 'content-type'),
'Do not force application/json globally; let Axios/browser set multipart boundary',
)
assert.ok(
!Object.keys(call.config?.headers ?? {}).some(key => key.toLowerCase() === 'content-type' && call.config.headers[key] === 'application/json'),
'Do not override multipart with application/json on this request',
)
}
test('small-file upload sends FormData, with no global JSON content type', async () => {
calls.length = 0
const file = new File(['abc'], 'demo.txt', { type: 'text/plain' })
await drive.upload([file], 12, 7)
const upload = calls.find(call => call.url === '/drive/uploads/')
assert.ok(upload)
assertMultipartRequest(upload)
assert.equal(upload.body.get('files').name, 'demo.txt')
assert.equal(upload.body.get('parent'), '12')
assert.equal(upload.body.get('space'), '7')
})
test('resumable upload sends JSON metadata and multipart binary chunks', async () => {
calls.length = 0
const file = new File([new Uint8Array(8 * 1024 * 1024 + 3)], 'video.bin')
await drive.uploadResumable(file, null, 7)
const start = calls.find(call => call.url === '/drive/uploads/start/')
const parts = calls.filter(call => call.url.endsWith('/chunk/'))
const finish = calls.find(call => call.url.endsWith('/finish/'))
assert.ok(start)
assert.equal(start.body.name, 'video.bin')
assert.equal(start.body.size, file.size)
assert.ok(!(start.body instanceof FormData))
assert.equal(parts.length, 2)
for (const part of parts) assertMultipartRequest(part)
assert.equal(parts[0].body.get('part').size, 8 * 1024 * 1024)
assert.equal(parts[1].body.get('part').size, 3)
assert.ok(finish)
})