Files
switchnote/tests/audio_upload_page_test.js
2026-10-29 03:55:40 +00:00

71 lines
2.7 KiB
JavaScript

'use strict';
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const vm = require('node:vm');
async function main() {
const source = fs.readFileSync(path.join(__dirname, '..', 'source', 'audio_upload_server.cpp'), 'utf8');
const script = source.match(/<script>([\s\S]*?)<\/script>/)?.[1];
assert.ok(script, 'embedded upload script exists');
const handlers = {};
const elements = new Map();
for (const id of ['code', 'pair', 'pairStatus', 'connected', 'uploadPanel', 'track', 'file', 'send', 'status']) {
elements.set(id, {
value: '', hidden: id === 'connected' || id === 'uploadPanel',
className: 'status', textContent: '', files: [], disabled: false,
addEventListener(event, handler) { handlers[id + ':' + event] = handler; },
});
}
elements.get('track').value = '0';
elements.get('file').files = [{
name: 'short.wav', size: 4, arrayBuffer: async () => new ArrayBuffer(4),
}];
const token = 'a'.repeat(64);
const requests = [];
const fetch = async (url, options) => {
requests.push({url, options});
if (url === '/api/connect') return {ok: true, text: async () => token};
if (url === '/api/upload') return {ok: true, text: async () => 'Received'};
if (url === '/api/status') return {ok: true, text: async () => 'imported'};
throw new Error('Unexpected request: ' + url);
};
class AudioContext {
async decodeAudioData() {
return {
length: 1, sampleRate: 48000, numberOfChannels: 1,
getChannelData: () => new Float32Array([0]),
};
}
async close() {}
}
vm.runInNewContext(script, {
document: {getElementById: id => elements.get(id)},
window: {AudioContext}, fetch, Blob, ArrayBuffer, DataView,
setTimeout: callback => callback(),
});
elements.get('code').value = '123456';
handlers['code:input']();
await new Promise(setImmediate);
assert.equal(elements.get('code').value, '123-456');
assert.equal(requests[0].url, '/api/connect');
assert.equal(requests[0].options.headers.Authorization, 'Bearer 123-456');
assert.equal(elements.get('pair').hidden, true);
assert.equal(elements.get('connected').hidden, false);
assert.match(source, /id="connected"[^>]*>Connected to Nintendo Switch<\/div>/);
assert.equal(elements.get('uploadPanel').hidden, false);
await handlers['send:click']();
assert.equal(requests[1].url, '/api/upload');
assert.equal(requests[1].options.headers.Authorization, 'Bearer ' + token);
assert.equal(requests[2].url, '/api/status');
assert.equal(requests[2].options.headers.Authorization, 'Bearer ' + token);
assert.equal(elements.get('status').className, 'status ok');
}
main().catch(error => { console.error(error); process.exitCode = 1; });