aps-agent/tests/node/authenticated-download.test...

88 lines
3.3 KiB
JavaScript
Raw Normal View History

import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import { createRequire } from 'node:module';
import test from 'node:test';
const requireWeb = createRequire(new URL('../../apps/web/package.json', import.meta.url));
const ts = requireWeb('typescript');
function loadCommonJs(source, requireForModule) {
const compiled = ts.transpileModule(source, { compilerOptions: {
module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022,
}}).outputText;
const exported = {};
new Function('require', 'exports', 'module', compiled)(requireForModule, exported, { exports: exported });
return exported;
}
const clientSource = readFileSync(new URL('../../apps/web/src/api/client.ts', import.meta.url), 'utf8');
const downloadSource = readFileSync(new URL('../../apps/web/src/api/download.ts', import.meta.url), 'utf8');
const client = loadCommonJs(clientSource, requireWeb);
const download = loadCommonJs(downloadSource, specifier => {
if (specifier === './client') return client;
return requireWeb(specifier);
});
test('parses RFC 5987 and plain Content-Disposition filenames', () => {
assert.equal(download.filenameFromContentDisposition(
`attachment; filename*=UTF-8''%E6%8E%92%E4%BA%A7%E8%AE%A1%E5%88%92.xlsx`,
'fallback.xlsx',
), '排产计划.xlsx');
assert.equal(
download.filenameFromContentDisposition('attachment; filename="report plan.xlsx"', 'fallback.xlsx'),
'report plan.xlsx',
);
assert.equal(download.filenameFromContentDisposition(null, 'fallback.xlsx'), 'fallback.xlsx');
});
test('authenticated download carries credentials and client headers before saving the blob', async () => {
const originalWindow = globalThis.window;
const originalDocument = globalThis.document;
const originalCreateObjectURL = URL.createObjectURL;
const originalRevokeObjectURL = URL.revokeObjectURL;
const clicked = [];
const revoked = [];
let captured = null;
try {
globalThis.window = {
apsDesktop: undefined,
localStorage: {
getItem: () => 'visitor-12345678',
setItem: () => {},
},
fetch: async (_input, init) => {
captured = init;
return new Response(new Blob(['xlsx']), {
status: 200,
headers: { 'Content-Disposition': `attachment; filename*=UTF-8''%E8%AE%A1%E5%88%92.xlsx` },
});
},
setTimeout: callback => { callback(); return 0; },
dispatchEvent: () => true,
};
globalThis.document = {
createElement: () => ({
style: {},
click() { clicked.push(this.download); },
remove() {},
}),
body: { appendChild: () => {} },
};
URL.createObjectURL = () => 'blob:test';
URL.revokeObjectURL = value => { revoked.push(value); };
const filename = await download.downloadAuthenticatedFile('/api/reports/plan?format=xlsx', 'fallback.xlsx');
assert.equal(filename, '计划.xlsx');
assert.deepEqual(clicked, ['计划.xlsx']);
assert.deepEqual(revoked, ['blob:test']);
assert.equal(captured.credentials, 'include');
assert.equal(new Headers(captured.headers).get('X-APS-Visitor-ID'), 'visitor-12345678');
} finally {
globalThis.window = originalWindow;
globalThis.document = originalDocument;
URL.createObjectURL = originalCreateObjectURL;
URL.revokeObjectURL = originalRevokeObjectURL;
}
});