disable cachebuster to show local media
Sonarqube Scanner / Build and analyze (push) Successful in 1m13s
Sonarqube Scanner / Build and analyze (push) Successful in 1m13s
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
function mediaUrl(url) {
|
function mediaUrl(url) {
|
||||||
if (!url) return '';
|
if (!url) return '';
|
||||||
|
if (url.startsWith('data:') || url.startsWith('blob:')) return url;
|
||||||
const separator = url.includes('?') ? '&' : '?';
|
const separator = url.includes('?') ? '&' : '?';
|
||||||
return `${url}${separator}v=${Date.now()}`;
|
return `${url}${separator}v=${Date.now()}`;
|
||||||
}
|
}
|
||||||
@@ -23,7 +24,6 @@
|
|||||||
load(url) {
|
load(url) {
|
||||||
unload();
|
unload();
|
||||||
if (!url) return;
|
if (!url) return;
|
||||||
|
|
||||||
const audio = element();
|
const audio = element();
|
||||||
audio.src = mediaUrl(url);
|
audio.src = mediaUrl(url);
|
||||||
$(audio).removeAttr('hidden').css('display', 'block');
|
$(audio).removeAttr('hidden').css('display', 'block');
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
function mediaUrl(url) {
|
function mediaUrl(url) {
|
||||||
if (!url) return '';
|
if (!url) return '';
|
||||||
|
if (url.startsWith('data:') || url.startsWith('blob:')) return url;
|
||||||
const separator = url.includes('?') ? '&' : '?';
|
const separator = url.includes('?') ? '&' : '?';
|
||||||
return `${url}${separator}v=${Date.now()}`;
|
return `${url}${separator}v=${Date.now()}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import fs from 'node:fs/promises';
|
||||||
|
import path from 'node:path';
|
||||||
|
import test from 'node:test';
|
||||||
|
import vm from 'node:vm';
|
||||||
|
|
||||||
|
const root = path.resolve(import.meta.dirname, '..');
|
||||||
|
|
||||||
|
function createHarness() {
|
||||||
|
const document = {};
|
||||||
|
const elements = new Map();
|
||||||
|
|
||||||
|
function makeElement(id) {
|
||||||
|
if (elements.has(id)) return elements.get(id);
|
||||||
|
const element = {
|
||||||
|
id,
|
||||||
|
attrs: {},
|
||||||
|
css: {},
|
||||||
|
hidden: false,
|
||||||
|
textValue: '',
|
||||||
|
toggled: null,
|
||||||
|
paused: false,
|
||||||
|
loadCount: 0,
|
||||||
|
pause() { this.paused = true; },
|
||||||
|
load() { this.loadCount += 1; },
|
||||||
|
play() { return Promise.resolve(); },
|
||||||
|
removeAttribute(name) {
|
||||||
|
delete this.attrs[name];
|
||||||
|
if (name === 'src') delete this.src;
|
||||||
|
},
|
||||||
|
getAttribute(name) {
|
||||||
|
if (name === 'src') return this.src ?? this.attrs.src ?? null;
|
||||||
|
return this.attrs[name] ?? null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
elements.set(id, element);
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Wrapper {
|
||||||
|
constructor(target) {
|
||||||
|
this.target = target;
|
||||||
|
this[0] = target;
|
||||||
|
this.length = target ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
on() { return this; }
|
||||||
|
off() { return this; }
|
||||||
|
button() { return this; }
|
||||||
|
hide() { if (this.target) this.target.hidden = true; return this; }
|
||||||
|
removeAttr(name) {
|
||||||
|
this.target?.removeAttribute?.(name);
|
||||||
|
if (this.target && name === 'hidden') this.target.hidden = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
attr(name, value) {
|
||||||
|
if (!this.target) return this;
|
||||||
|
if (value === undefined) return this.target.attrs?.[name];
|
||||||
|
this.target.attrs[name] = String(value);
|
||||||
|
if (name === 'src') this.target.src = String(value);
|
||||||
|
if (name === 'hidden') this.target.hidden = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
css(name, value) { if (this.target) this.target.css[name] = value; return this; }
|
||||||
|
toggle(value) { if (this.target) this.target.toggled = Boolean(value); return this; }
|
||||||
|
text(value) { if (this.target) this.target.textValue = String(value); return this; }
|
||||||
|
prop(name, value) { if (this.target) this.target[name] = value; return this; }
|
||||||
|
hasClass() { return false; }
|
||||||
|
closest() { return { length: 0 }; }
|
||||||
|
}
|
||||||
|
|
||||||
|
function jquery(target) {
|
||||||
|
if (target === document) return new Wrapper(document);
|
||||||
|
if (typeof target === 'string' && target.startsWith('#')) return new Wrapper(makeElement(target.slice(1)));
|
||||||
|
return new Wrapper(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
const context = {
|
||||||
|
Date,
|
||||||
|
Math,
|
||||||
|
Promise,
|
||||||
|
document,
|
||||||
|
globalThis: null,
|
||||||
|
jQuery: jquery,
|
||||||
|
Wegwichtel: {}
|
||||||
|
};
|
||||||
|
context.globalThis = context;
|
||||||
|
return { context, elements };
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadModule(relativePath, harness) {
|
||||||
|
const sourcePath = path.join(root, relativePath);
|
||||||
|
const source = await fs.readFile(sourcePath, 'utf8');
|
||||||
|
vm.runInNewContext(source, harness.context, { filename: sourcePath });
|
||||||
|
}
|
||||||
|
|
||||||
|
test('audio player preserves local data/blob URLs and cache-busts server URLs', async () => {
|
||||||
|
const harness = createHarness();
|
||||||
|
await loadModule('public/js/audio-player.js', harness);
|
||||||
|
|
||||||
|
const dataUrl = 'data:audio/mpeg;base64,QUJDRA==';
|
||||||
|
harness.context.Wegwichtel.AudioPlayer.load(dataUrl);
|
||||||
|
assert.equal(harness.elements.get('poi-audio').src, dataUrl);
|
||||||
|
|
||||||
|
const blobUrl = 'blob:https://wegwichtel.de/1234';
|
||||||
|
harness.context.Wegwichtel.AudioPlayer.load(blobUrl);
|
||||||
|
assert.equal(harness.elements.get('poi-audio').src, blobUrl);
|
||||||
|
|
||||||
|
harness.context.Wegwichtel.AudioPlayer.load('/api/routes/1/pois/2/audio');
|
||||||
|
assert.match(harness.elements.get('poi-audio').src, /^\/api\/routes\/1\/pois\/2\/audio\?v=\d+$/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('slideshow preserves local data/blob URLs and cache-busts server URLs', async () => {
|
||||||
|
const harness = createHarness();
|
||||||
|
await loadModule('public/js/slideshow.js', harness);
|
||||||
|
|
||||||
|
const dataUrl = 'data:image/jpeg;base64,QUJDRA==';
|
||||||
|
harness.context.Wegwichtel.Slideshow.show([{ url: dataUrl, caption: 'Lokal' }]);
|
||||||
|
assert.equal(harness.elements.get('slide-image').src, dataUrl);
|
||||||
|
assert.equal(harness.elements.get('slideshow').toggled, true);
|
||||||
|
|
||||||
|
const blobUrl = 'blob:https://wegwichtel.de/5678';
|
||||||
|
harness.context.Wegwichtel.Slideshow.show([{ url: blobUrl }]);
|
||||||
|
assert.equal(harness.elements.get('slide-image').src, blobUrl);
|
||||||
|
|
||||||
|
harness.context.Wegwichtel.Slideshow.show([{ url: '/api/routes/1/pois/2/pictures/3' }]);
|
||||||
|
assert.match(harness.elements.get('slide-image').src, /^\/api\/routes\/1\/pois\/2\/pictures\/3\?v=\d+$/);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user