UNPKG

@tak-ps/node-tak

Version:

Lightweight JavaScript library for communicating with TAK Server

126 lines 5.36 kB
import test from 'node:test'; import assert from 'node:assert/strict'; import { Readable } from 'node:stream'; import { Client } from 'undici'; import TAKAPI from '../lib/api.js'; import { APIAuthCertificate, APIAuthPassword } from '../lib/auth.js'; import stream2buffer from '../lib/stream.js'; test('Files.uploadPackage serializes multipart for certificate auth', async () => { const originalRequest = Client.prototype.request; let captured; Client.prototype.request = async function (opts) { captured = opts; return { statusCode: 200, headers: { 'content-type': 'text/plain' }, body: Readable.from([Buffer.from('ok')]), trailers: {} }; }; try { const api = new TAKAPI(new URL('https://tak.example.com'), new APIAuthCertificate('cert', 'key')); const res = await api.Files.uploadPackage({ name: 'mission.zip', creatorUid: 'user-1', hash: 'hash-123', keywords: ['alpha'], groups: ['Blue'] }, Buffer.from('zip-bytes')); assert.equal(res, 'ok'); assert.ok(captured); assert.equal(captured.path, '/Marti/sync/missionupload?filename=mission.zip&creatorUid=user-1&hash=hash-123&keyword=missionpackage&keyword=alpha&Groups=Blue'); const headers = captured.headers; assert.equal(typeof headers['Content-Type'], 'string'); assert.equal(typeof headers['Content-Length'], 'string'); assert.match(headers['Content-Type'], /^multipart\/form-data; boundary=----node-tak-/); assert.equal(Number(headers['Content-Length']) > 0, true); assert.ok(captured.body instanceof Readable); const body = await stream2buffer(captured.body); const multipart = body.toString('utf8'); assert.match(multipart, /Content-Disposition: form-data; name="assetfile"; filename="mission.zip"/); assert.match(multipart, /Content-Type: application\/zip/); assert.match(multipart, /zip-bytes/); assert.match(multipart, /--$/m); } finally { Client.prototype.request = originalRequest; } }); test('Files.upload falls back to application/octet-stream when name has no extension', async () => { const originalRequest = Client.prototype.request; let captured; Client.prototype.request = async function (opts) { captured = opts; return { statusCode: 200, headers: { 'content-type': 'application/json' }, body: Readable.from([Buffer.from(JSON.stringify({ UID: 'uid-1', SubmissionDateTime: '2026-01-01T00:00:00.000Z', Keywords: [], MIMEType: 'application/octet-stream', SubmissionUser: 'user-1', PrimaryKey: 'pk-1', Hash: 'hash-1', CreatorUid: 'user-1', Name: 'hash-without-extension' }))]), trailers: {} }; }; try { const api = new TAKAPI(new URL('https://tak.example.com'), new APIAuthCertificate('cert', 'key')); const res = await api.Files.upload({ name: 'hash-without-extension', contentLength: 9, keywords: [], creatorUid: 'user-1' }, Buffer.from('zip-bytes')); assert.equal(res.Hash, 'hash-1'); assert.ok(captured); assert.equal(captured.path, '/Marti/sync/upload?name=hash-without-extension&keywords=&creatorUid=user-1'); const headers = captured.headers; assert.equal(headers['Content-Type'], 'application/octet-stream'); assert.equal(headers['Content-Length'], 9); assert.ok(captured.body instanceof Readable); const body = await stream2buffer(captured.body); assert.equal(body.toString('utf8'), 'zip-bytes'); } finally { Client.prototype.request = originalRequest; } }); test('APIAuthPassword surfaces transport causes during login', async () => { const api = new TAKAPI(new URL('https://tak.example.com'), new APIAuthPassword('alice', 'secret')); const originalFetch = api.auth.fetch; api.auth.fetch = async () => { const cause = new Error('certificate has expired'); cause.code = 'CERT_HAS_EXPIRED'; throw new TypeError('fetch failed', { cause }); }; await assert.rejects(api.auth.init(api), (err) => { assert.ok(err instanceof Error); assert.equal(err.name, 'PublicError'); assert.match(err.message, /CERT_HAS_EXPIRED/); assert.match(err.message, /certificate has expired/); return true; }); api.auth.fetch = async () => { const cause = new Error('connect ECONNREFUSED 127.0.0.1:8443'); cause.code = 'ECONNREFUSED'; throw new TypeError('fetch failed', { cause }); }; await assert.rejects(api.auth.init(api), (err) => { assert.ok(err instanceof Error); assert.equal(err.name, 'PublicError'); assert.match(err.message, /ECONNREFUSED/); assert.match(err.message, /connect ECONNREFUSED 127\.0\.0\.1:8443/); return true; }); api.auth.fetch = originalFetch; }); //# sourceMappingURL=uploadPackage.test.js.map