53 lines
2.5 KiB
JavaScript
53 lines
2.5 KiB
JavaScript
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const vm = require('node:vm');
|
|
const root = path.resolve(__dirname,'..');
|
|
const walk = directory => fs.readdirSync(directory,{withFileTypes:true}).flatMap(entry=>
|
|
entry.isDirectory()?walk(path.join(directory,entry.name)):[path.join(directory,entry.name)]);
|
|
|
|
test('the release contains source files and assets, with no server credentials or nested bundles',()=>{
|
|
for(const file of walk(root)){
|
|
assert.doesNotMatch(path.relative(root,file),/\.(?:key|pem|sqlite3|zip|xpi|pyc)$/i);
|
|
if(/\.(?:html|js|css|json|md|txt)$/i.test(file)){
|
|
assert.doesNotMatch(fs.readFileSync(file,'utf8'),/-----BEGIN (?:RSA )?PRIVATE KEY-----/);
|
|
}
|
|
}
|
|
});
|
|
|
|
test('all shipped JavaScript is valid and the editor has no server fetch calls',()=>{
|
|
for(const file of walk(path.join(root,'assets')).filter(file=>file.endsWith('.js'))){
|
|
const source=fs.readFileSync(file,'utf8');
|
|
new vm.Script(source,{filename:file});
|
|
if(!file.includes(path.join('assets','vendor'))&&!file.endsWith('arabic-text.js')){
|
|
assert.doesNotMatch(source,/\bfetch\s*\(|XMLHttpRequest|sendBeacon|WebSocket/);
|
|
}
|
|
}
|
|
});
|
|
|
|
test('the page keeps local import and video output without site navigation',()=>{
|
|
const html=fs.readFileSync(path.join(root,'index.html'),'utf8');
|
|
assert.match(html,/id="flipnote-open-ppm-button"/);
|
|
assert.match(html,/id="flipnote-audio-file-input"/);
|
|
assert.match(html,/id="export-btn"/);
|
|
assert.doesNotMatch(html,/class="site-(?:header|footer)"|<nav\b|action="\//);
|
|
assert.doesNotMatch(html,/__[A-Z][A-Z0-9_]+__/);
|
|
});
|
|
|
|
test('all literal page images, scripts, styles and font URLs exist locally',()=>{
|
|
const files=walk(root).filter(file=>/\.(?:html|css|js)$/.test(file)&&!file.includes(path.sep+'vendor'+path.sep));
|
|
for(const file of files){
|
|
const text=fs.readFileSync(file,'utf8');
|
|
const references=[];
|
|
for(const match of text.matchAll(/(?:src|href)=["'](\.\/[^"']+)["']/g))references.push(match[1]);
|
|
for(const match of text.matchAll(/url\(["']?(\.\/[^)'"\s]+)["']?\)/g))references.push(match[1]);
|
|
for(const match of text.matchAll(/["'](\.\/assets\/[^"'$`]+)["']/g))references.push(match[1]);
|
|
for(const reference of references){
|
|
const clean=reference.split(/[?#]/)[0];
|
|
const base=file.endsWith('.css')?path.dirname(file):root;
|
|
assert.ok(fs.existsSync(path.resolve(base,clean)),path.relative(root,file)+': missing '+clean);
|
|
}
|
|
}
|
|
});
|
