allow update for uploaded routes and implement creator id for routes
This commit is contained in:
+64
-5
@@ -188,6 +188,7 @@ function submitEvent() {
|
||||
}
|
||||
|
||||
function buildEditorContext() {
|
||||
const controls = { failPicture: false, approved: false, recording: null };
|
||||
const ids = [
|
||||
'editor-add-poi',
|
||||
'editor-button',
|
||||
@@ -254,13 +255,22 @@ function buildEditorContext() {
|
||||
async function fetch(url, options = {}) {
|
||||
const method = options.method || 'GET';
|
||||
calls.push({ body: options.body, method, url });
|
||||
if (controls.failPicture && url.endsWith('/pictures/24') && method === 'PUT') {
|
||||
controls.failPicture = false;
|
||||
return jsonResponse({ message: 'Testfehler' }, false, 500);
|
||||
}
|
||||
|
||||
if (String(url).startsWith('data:')) {
|
||||
return { ok: true, status: 200, blob: async () => new Blob(['media'], { type: 'application/octet-stream' }) };
|
||||
}
|
||||
if (url === '/api/routes?activatedOnly=true' && method === 'GET') return jsonResponse({ routes: [serverRoute] });
|
||||
if (url === '/api/routes' && method === 'POST') return jsonResponse({ id: 22, name: 'Neue lokale Strecke', pois: [] }, true, 201);
|
||||
if (url === '/api/routes/22/pois' && method === 'POST') return jsonResponse({ id: 23, title: 'Aussicht' }, true, 201);
|
||||
if (/^\/api\/routes\/22\/pois\/23\/(audio|pictures)$/.test(url) && method === 'POST') return jsonResponse({ ok: true }, true, 201);
|
||||
if (/^\/api\/routes\/22\/pois\/23\/(audio|pictures)(?:\/24)?$/.test(url) && (method === 'POST' || method === 'PUT')) return jsonResponse({ id: 24 }, true, 201);
|
||||
if (url === '/api/routes/22' && method === 'GET') return jsonResponse({ id: 22, activatedAt: controls.approved ? '2026-10-03' : null, pois: [{ id: 23, audioUrl: '/audio', images: [{ id: 24 }] }] });
|
||||
if (url === '/api/routes/22' && method === 'PUT') return jsonResponse({ id: 22 });
|
||||
if (url === '/api/routes/22/pois/23' && method === 'PUT') return jsonResponse({ id: 23 });
|
||||
if (/^\/api\/routes\/22\/pois\/23(?:\/audio|\/pictures\/24)?$/.test(url) && method === 'DELETE') return jsonResponse({ deleted: true });
|
||||
if (url === '/api/routes/22' && method === 'DELETE') return jsonResponse({ deleted: true });
|
||||
if (url === '/api/routes/1' && method === 'GET') return jsonResponse({ route: serverRoute });
|
||||
if (url === '/api/routes/1' && method === 'DELETE') return jsonResponse({ deleted: true });
|
||||
@@ -280,6 +290,7 @@ function buildEditorContext() {
|
||||
const mediaBlobs = new Map();
|
||||
const storedMediaCalls = [];
|
||||
const LocalRoutes = {
|
||||
creatorId: () => "a".repeat(64),
|
||||
createPoiId: () => 9001,
|
||||
createRouteId: () => 'local-new',
|
||||
emptyGpx: name => `<gpx><metadata><name>${name}</name></metadata><trk><trkseg></trkseg></trk></gpx>`,
|
||||
@@ -354,17 +365,25 @@ function buildEditorContext() {
|
||||
Wegwichtel: {
|
||||
App: { currentPosition: () => ({ lat: 50.123456789, lon: 10.987654321, accuracy: 4.321 }) },
|
||||
Config: { apiBase: '/api/' },
|
||||
RouteRecorder: {
|
||||
beginEditing(id) { controls.recording = id; },
|
||||
endEditing() { controls.recording = null; },
|
||||
renderPoints() {},
|
||||
editGpx: gpx => gpx,
|
||||
get routeId() { return controls.recording; },
|
||||
get position() { return { lat: 50.123456789, lon: 10.987654321, accuracy: 4.321 }; }
|
||||
},
|
||||
LocalRoutes
|
||||
}
|
||||
};
|
||||
context.globalThis = context;
|
||||
return { calls, context, elements, packages, saves, storedMediaCalls };
|
||||
return { calls, context, elements, packages, saves, storedMediaCalls, controls };
|
||||
}
|
||||
|
||||
test('public editor workflow saves new route and GPX Station locally without POSTing a route', async () => {
|
||||
const sourcePath = path.join(root, 'public/js/editor-ui.js');
|
||||
const source = await fs.readFile(sourcePath, 'utf8');
|
||||
const { calls, context, elements, packages, saves } = buildEditorContext();
|
||||
const { calls, context, elements, packages, saves, controls } = buildEditorContext();
|
||||
|
||||
await loadI18n(context);
|
||||
|
||||
@@ -390,6 +409,7 @@ test('public editor workflow saves new route and GPX Station locally without POS
|
||||
assert.equal(calls.some(call => call.method === 'POST' && call.url === '/api/routes'), false);
|
||||
assert.match(elements.get('editor-route-activated').textContent, /Dieser Entwurf bleibt auf deinem Gerät/);
|
||||
assert.equal(elements.get('editor-status').textContent, 'Gespeichert.');
|
||||
assert.equal(controls.recording, 'local-new');
|
||||
assert.equal(elements.get('editor-route-upload').hidden, false);
|
||||
assert.equal(elements.get('editor-route-upload').disabled, false);
|
||||
assert.equal(elements.get('editor-route-gpx-group').hidden, true);
|
||||
@@ -452,9 +472,35 @@ test('public editor workflow saves new route and GPX Station locally without POS
|
||||
local = packages.get('local-new');
|
||||
assert.equal(local.route.serverRouteId, '22');
|
||||
assert.ok(local.route.uploadedAt);
|
||||
assert.equal(elements.get('editor-route-upload').disabled, true);
|
||||
assert.equal(elements.get('editor-route-upload').textContent, 'Schon zur Prüfung gesendet');
|
||||
assert.equal(elements.get('editor-route-upload').disabled, false);
|
||||
assert.equal(elements.get('editor-route-upload').textContent, 'Erneut zur Prüfung senden');
|
||||
assert.equal(elements.get('editor-status').textContent, 'Zur Prüfung gesendet.');
|
||||
elements.get('editor-route-upload').dispatchEvent(pointerEvent());
|
||||
for (let i = 0; i < 10; i += 1) await tick();
|
||||
assert.equal(calls.filter(call => call.method === 'POST' && call.url === '/api/routes').length, 1);
|
||||
assert.equal(calls.filter(call => call.method === 'POST' && call.url === '/api/routes/22/pois').length, 1);
|
||||
assert.equal(calls.filter(call => call.method === 'POST' && call.url === '/api/routes/22/pois/23/pictures').length, 1);
|
||||
assert.ok(calls.some(call => call.method === 'PUT' && call.url === '/api/routes/22'));
|
||||
assert.ok(calls.some(call => call.method === 'PUT' && call.url === '/api/routes/22/pois/23/audio'));
|
||||
assert.ok(calls.some(call => call.method === 'PUT' && call.url === '/api/routes/22/pois/23/pictures/24'));
|
||||
controls.failPicture = true;
|
||||
elements.get('editor-route-upload').dispatchEvent(pointerEvent());
|
||||
for (let i = 0; i < 10; i += 1) await tick();
|
||||
assert.equal(packages.get('local-new').pois[0].serverPictureId, undefined);
|
||||
assert.equal(packages.get('local-new').pois[0].images[0].serverPictureId, 24);
|
||||
assert.equal(packages.get('local-new').route.serverRouteId, '22');
|
||||
assert.equal(elements.get('editor-route-upload').disabled, false);
|
||||
elements.get('editor-route-upload').dispatchEvent(pointerEvent());
|
||||
for (let i = 0; i < 10; i += 1) await tick();
|
||||
assert.equal(calls.filter(call => call.method === 'POST' && call.url === '/api/routes').length, 1);
|
||||
controls.approved = true;
|
||||
const writesBeforeApproval = calls.filter(call => call.method !== 'GET').length;
|
||||
elements.get('editor-route-upload').dispatchEvent(pointerEvent());
|
||||
for (let i = 0; i < 10; i += 1) await tick();
|
||||
assert.equal(calls.filter(call => call.method !== 'GET').length, writesBeforeApproval);
|
||||
controls.approved = false;
|
||||
|
||||
|
||||
|
||||
const poiList = elements.get('editor-poi-list');
|
||||
const poiItem = poiList.children.find(child => child.dataset.poiId);
|
||||
@@ -481,15 +527,28 @@ test('public editor workflow saves new route and GPX Station locally without POS
|
||||
await tick();
|
||||
local = packages.get('local-new');
|
||||
assert.equal(local.pois[0].audio, null);
|
||||
elements.get('editor-route-upload').dispatchEvent(pointerEvent());
|
||||
for (let i = 0; i < 10; i += 1) await tick();
|
||||
assert.ok(calls.some(call => call.method === 'DELETE' && call.url === '/api/routes/22/pois/23/audio'));
|
||||
assert.ok(calls.some(call => call.method === 'DELETE' && call.url === '/api/routes/22/pois/23/pictures/24'));
|
||||
|
||||
|
||||
const currentList = elements.get('editor-poi-list');
|
||||
const currentItem = currentList.children.find(child => child.dataset.poiId);
|
||||
currentList.dispatchEvent(pointerEvent(currentItem.children[1].children[2]));
|
||||
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);
|
||||
elements.get('editor-route-upload').dispatchEvent(pointerEvent());
|
||||
for (let i = 0; i < 10; i += 1) await tick();
|
||||
assert.ok(calls.some(call => call.method === 'DELETE' && call.url === '/api/routes/22/pois/23'));
|
||||
|
||||
|
||||
context.Wegwichtel.EditorUi.close();
|
||||
assert.equal(controls.recording, null);
|
||||
assert.equal(elements.get('editor-dialog').open, false);
|
||||
assert.equal(elements.get('editor-button').attributes.get('aria-expanded'), 'false');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user