add delete buttons to editor
Sonarqube Scanner / Build and analyze (push) Successful in 1m4s

This commit is contained in:
Florian Zumpe
2026-09-27 17:59:09 +02:00
parent 6b3f228ad8
commit becd48b487
4 changed files with 504 additions and 63 deletions
+61 -9
View File
@@ -28,6 +28,12 @@ test('editor markup and source describe local draft creation instead of immediat
assert.match(html, /id="editor-poi-images-add"[^>]+type="button"/);
assert.match(html, /id="editor-poi-audio"[^>]+accept="audio\/\*"[^>]+hidden/);
assert.match(html, /id="editor-poi-images"[^>]+accept="image\/\*"[^>]+multiple[^>]+hidden/);
assert.match(html, /id="editor-poi-lat"[^>]+type="hidden"/);
assert.match(html, /id="editor-poi-lon"[^>]+type="hidden"/);
assert.match(html, /id="editor-poi-radius"[^>]+type="hidden"/);
assert.doesNotMatch(html, /id="editor-poi-(?:lat|lon)"[^>]+step=/);
assert.match(html, /id="editor-poi-media-preview"/);
assert.match(html, /id="editor-poi-delete"[^>]+editor-danger-button/);
assert.doesNotMatch(html, /accept="video\//);
assert.match(html, /ausschließlich in diesem Browser/i);
@@ -35,6 +41,9 @@ test('editor markup and source describe local draft creation instead of immediat
assert.match(css, /\.editor-poi-list/);
assert.match(css, /\.editor-route-group/);
assert.match(css, /\.editor-media-button/);
assert.match(css, /\.editor-media-preview/);
assert.match(css, /\.editor-media-remove/);
assert.match(css, /\.editor-danger-button/);
assert.match(ui, /readJson\(['"]\/routes\?activatedOnly=true['"]\)/);
assert.match(ui, /ns\.LocalRoutes\.save\(/);
@@ -51,6 +60,8 @@ test('editor markup and source describe local draft creation instead of immediat
assert.match(ui, /\/pictures/);
assert.match(ui, /'picture'/);
assert.match(ui, /'audio'/);
assert.match(ui, /method:\s*'DELETE'/);
assert.match(ui, /position\?\.accuracy/);
});
class FakeElement extends EventTarget {
@@ -167,6 +178,7 @@ function buildEditorContext() {
'editor-poi-audio',
'editor-poi-audio-add',
'editor-poi-cancel',
'editor-poi-delete',
'editor-poi-description',
'editor-poi-form',
'editor-poi-form-title',
@@ -177,6 +189,7 @@ function buildEditorContext() {
'editor-poi-lat',
'editor-poi-list',
'editor-poi-lon',
'editor-poi-media-preview',
'editor-poi-media-status',
'editor-poi-radius',
'editor-poi-title',
@@ -228,7 +241,10 @@ function buildEditorContext() {
}
if (url === '/api/routes/1/pois' && method === 'POST') return jsonResponse({ poi: { id: 12, title: 'Neue Serverstation' } });
if (/^\/api\/routes\/1\/pois\/\d+$/.test(url) && method === 'PUT') return jsonResponse({ poi: { id: Number(url.split('/').pop()), title: 'Station' } });
if (/^\/api\/routes\/1\/pois\/\d+\/(audio|pictures)$/.test(url) && method === 'POST') return jsonResponse({ ok: true });
if (/^\/api\/routes\/1\/pois\/\d+\/(audio|pictures)$/.test(url) && (method === 'POST' || method === 'PUT')) return jsonResponse({ ok: true });
if (/^\/api\/routes\/1\/pois\/\d+\/audio$/.test(url) && method === 'DELETE') return jsonResponse({ deleted: true });
if (/^\/api\/routes\/1\/pois\/\d+\/pictures\/\d+$/.test(url) && method === 'DELETE') return jsonResponse({ deleted: true });
if (/^\/api\/routes\/1\/pois\/\d+$/.test(url) && method === 'DELETE') return jsonResponse({ deleted: true });
return { ok: false, status: 404, text: async () => `unexpected ${method} ${url}` };
}
@@ -270,7 +286,7 @@ function buildEditorContext() {
globalThis: null,
structuredClone,
Wegwichtel: {
App: { currentPosition: () => ({ lat: 50.5, lon: 10.5 }) },
App: { currentPosition: () => ({ lat: 50.123456789, lon: 10.987654321, accuracy: 4.321 }) },
Config: { apiBase: '/api/' },
LocalRoutes
}
@@ -311,27 +327,63 @@ test('public editor workflow saves new route and GPX POI locally without POSTing
elements.get('editor-poi-images-add').dispatchEvent(pointerEvent());
assert.equal(elements.get('editor-poi-audio').clickCount, 1);
assert.equal(elements.get('editor-poi-images').clickCount, 1);
assert.equal(elements.get('editor-poi-lat').value, '50.123456789');
assert.equal(elements.get('editor-poi-lon').value, '10.987654321');
assert.equal(elements.get('editor-poi-radius').value, '4.321');
elements.get('editor-poi-title').value = 'Aussicht';
elements.get('editor-poi-description').value = 'Text zur Station';
elements.get('editor-poi-lat').value = '50.51';
elements.get('editor-poi-lon').value = '10.52';
elements.get('editor-poi-radius').value = '35';
elements.get('editor-poi-audio').files = [{ name: 'aussicht.mp3', size: 5, type: 'audio/mpeg' }];
elements.get('editor-poi-audio').dispatchEvent(new Event('change'));
elements.get('editor-poi-images').files = [{ name: 'aussicht.jpg', size: 7, type: 'image/jpeg' }];
elements.get('editor-poi-images').dispatchEvent(new Event('change'));
await tick();
elements.get('editor-poi-form').dispatchEvent(submitEvent());
await tick();
await tick();
const local = packages.get('local-new');
let local = packages.get('local-new');
assert.equal(local.pois.length, 1);
assert.equal(local.pois[0].title, 'Aussicht');
assert.equal(local.pois[0].lat, 50.51);
assert.equal(local.pois[0].lon, 10.52);
assert.equal(local.pois[0].triggerRadiusM, 35);
assert.equal(local.pois[0].lat, 50.123456789);
assert.equal(local.pois[0].lon, 10.987654321);
assert.equal(local.pois[0].triggerRadiusM, 4.321);
assert.match(local.pois[0].audio.dataUrl, /^data:audio\/mpeg/);
assert.equal(local.pois[0].images.length, 1);
assert.match(local.pois[0].images[0].dataUrl, /^data:image\/jpeg/);
const poiList = elements.get('editor-poi-list');
const poiItem = poiList.children.find(child => child.dataset.poiId);
const poiEditButton = poiItem.children[1].children[2];
poiList.dispatchEvent(pointerEvent(poiEditButton));
const mediaPreview = elements.get('editor-poi-media-preview');
assert.equal(mediaPreview.children.length, 2);
let imageCard = mediaPreview.children.find(card => card.children[1]?.dataset.mediaKind === 'image');
mediaPreview.dispatchEvent(pointerEvent(imageCard.children[0]));
imageCard = mediaPreview.children.find(card => card.children[1]?.dataset.mediaKind === 'image');
assert.equal(imageCard.children[1].hidden, false);
mediaPreview.dispatchEvent(pointerEvent(imageCard.children[1]));
await tick();
await tick();
local = packages.get('local-new');
assert.equal(local.pois[0].images.length, 0);
let audioCard = elements.get('editor-poi-media-preview').children.find(card => card.children[1]?.dataset.mediaKind === 'audio');
elements.get('editor-poi-media-preview').dispatchEvent(pointerEvent(audioCard.children[0]));
audioCard = elements.get('editor-poi-media-preview').children.find(card => card.children[1]?.dataset.mediaKind === 'audio');
elements.get('editor-poi-media-preview').dispatchEvent(pointerEvent(audioCard.children[1]));
await tick();
await tick();
local = packages.get('local-new');
assert.equal(local.pois[0].audio, null);
assert.equal(elements.get('editor-poi-delete').hidden, false);
elements.get('editor-poi-delete').dispatchEvent(pointerEvent());
await tick();
await tick();
local = packages.get('local-new');
assert.equal(local.pois.length, 0);
context.Wegwichtel.EditorUi.close();
assert.equal(elements.get('editor-dialog').open, false);
assert.equal(elements.get('editor-button').attributes.get('aria-expanded'), 'false');