Multiple improvements
This commit is contained in:
@@ -302,6 +302,13 @@ function buildEditorContext() {
|
||||
type: file.type || 'application/octet-stream'
|
||||
}),
|
||||
get: id => packages.get(String(id)) || null,
|
||||
getPoiWithMedia: async (id, poiId) => {
|
||||
const value = packages.get(String(id))?.pois.find(poi => String(poi.id) === String(poiId));
|
||||
if (!value) return null;
|
||||
return { ...value, audio: value.audio ? { ...value.audio, url: 'blob:test-audio' } : null,
|
||||
images: (value.images || []).map(image => ({ ...image, url: 'blob:test-image' })) };
|
||||
},
|
||||
releasePoiMedia() {},
|
||||
getWithMedia: async id => {
|
||||
const value = packages.get(String(id));
|
||||
if (!value) return null;
|
||||
@@ -659,6 +666,7 @@ test('editing an activated server route uses PUT and never writes activation sta
|
||||
await context.Wegwichtel.EditorUi.open();
|
||||
|
||||
const routeList = elements.get('editor-route-list');
|
||||
await tick();
|
||||
const serverItem = routeList.children.find(child => child.dataset.routeSource === 'server');
|
||||
const serverActions = serverItem.children[1];
|
||||
assert.equal(serverActions.children.length, 1);
|
||||
@@ -737,3 +745,94 @@ test('local media picker keeps File System Access handles for later upload', asy
|
||||
assert.equal(imageStore.handle, handle);
|
||||
assert.equal(imageStore.file, imageFile);
|
||||
});
|
||||
|
||||
|
||||
test('local drafts can be opened and saved while the server request is still pending', async () => {
|
||||
const { context, elements, packages } = buildEditorContext();
|
||||
context.fetch = () => new Promise(() => {});
|
||||
await loadI18n(context);
|
||||
vm.runInNewContext(await fs.readFile(path.join(root, 'public/js/editor-ui.js'), 'utf8'), context);
|
||||
await context.Wegwichtel.EditorUi.open();
|
||||
const list = elements.get('editor-route-list');
|
||||
const item = list.children.find(child => child.dataset.routeId === 'local-existing');
|
||||
assert.ok(item);
|
||||
list.dispatchEvent(pointerEvent(item.children[1].children[0]));
|
||||
await tick();
|
||||
assert.equal(elements.get('editor-route-id').value, 'local-existing');
|
||||
elements.get('editor-route-name').value = 'Offline geändert';
|
||||
elements.get('editor-route-form').dispatchEvent(submitEvent());
|
||||
await tick(); await tick();
|
||||
assert.equal(packages.get('local-existing').route.name, 'Offline geändert');
|
||||
assert.equal(elements.get('editor-status').textContent, 'Gespeichert.');
|
||||
});
|
||||
|
||||
test('a failed public route request preserves local drafts and late replies use the latest local data', async () => {
|
||||
const { context, elements, packages } = buildEditorContext();
|
||||
const requests = [];
|
||||
context.fetch = () => new Promise((resolve, reject) => requests.push({ resolve, reject }));
|
||||
await loadI18n(context);
|
||||
vm.runInNewContext(await fs.readFile(path.join(root, 'public/js/editor-ui.js'), 'utf8'), context);
|
||||
await context.Wegwichtel.EditorUi.open();
|
||||
requests[0].reject(new Error('offline')); await tick();
|
||||
assert.match(elements.get('editor-status').textContent, /nicht erreichbar/);
|
||||
assert.ok(elements.get('editor-route-list').children.some(child => child.dataset.routeId === 'local-existing'));
|
||||
await context.Wegwichtel.EditorUi.refresh();
|
||||
packages.delete('local-existing');
|
||||
requests[1].resolve(jsonResponse({ routes: [{ id: 7, name: 'Veröffentlicht' }] }));
|
||||
await tick(); await tick();
|
||||
assert.equal(elements.get('editor-route-list').children.some(child => child.dataset.routeId === 'local-existing'), false);
|
||||
assert.ok(elements.get('editor-route-list').children.some(child => child.dataset.routeSource === 'server'));
|
||||
});
|
||||
|
||||
|
||||
test('opening and saving a draft does not load files; editing a station loads only that station', async () => {
|
||||
const { context, elements, packages } = buildEditorContext();
|
||||
const local = packages.get('local-existing');
|
||||
local.pois = [0, 1].map(id => ({ id, title: `Station ${id}`, sequence: id, images: [{ id: `image-${id}`, mediaKey: `key-${id}` }] }));
|
||||
const loads = [];
|
||||
context.Wegwichtel.LocalRoutes.getWithMedia = () => { throw new Error('Full route hydration must not run'); };
|
||||
const original = context.Wegwichtel.LocalRoutes.getPoiWithMedia;
|
||||
context.Wegwichtel.LocalRoutes.getPoiWithMedia = (...args) => { loads.push(args); return original(...args); };
|
||||
await loadI18n(context);
|
||||
vm.runInNewContext(await fs.readFile(path.join(root, 'public/js/editor-ui.js'), 'utf8'), context);
|
||||
await context.Wegwichtel.EditorUi.open();
|
||||
const list = elements.get('editor-route-list');
|
||||
const item = list.children.find(child => child.dataset.routeId === 'local-existing');
|
||||
list.dispatchEvent(pointerEvent(item.children[1].children[0])); await tick();
|
||||
assert.equal(loads.length, 0);
|
||||
elements.get('editor-route-name').value = 'Nur Name geändert';
|
||||
elements.get('editor-route-form').dispatchEvent(submitEvent()); await tick(); await tick();
|
||||
assert.equal(loads.length, 0);
|
||||
const poiList = elements.get('editor-poi-list');
|
||||
const poiItem = poiList.children.find(child => child.dataset.poiId === '1');
|
||||
poiList.dispatchEvent(pointerEvent(poiItem.children[1].children[2])); await tick();
|
||||
assert.equal(loads.length, 1);
|
||||
assert.equal(loads[0][1], 1);
|
||||
assert.equal(elements.get('editor-poi-media-preview').children.length, 1);
|
||||
elements.get('editor-poi-title').value = 'Titel geändert';
|
||||
elements.get('editor-poi-form').dispatchEvent(submitEvent()); await tick(); await tick();
|
||||
assert.equal(loads.length, 1);
|
||||
assert.equal(packages.get('local-existing').pois[1].title, 'Titel geändert');
|
||||
});
|
||||
|
||||
test('late station previews are released after the editor closes without replacing unsaved input', async () => {
|
||||
const { context, elements, packages } = buildEditorContext();
|
||||
packages.get('local-existing').pois = [{ id: 0, title: 'Station', images: [] }];
|
||||
let finish;
|
||||
const released = [];
|
||||
context.Wegwichtel.LocalRoutes.getPoiWithMedia = () => new Promise(resolve => { finish = resolve; });
|
||||
context.Wegwichtel.LocalRoutes.releasePoiMedia = poi => { if(poi) released.push(poi); };
|
||||
await loadI18n(context);
|
||||
vm.runInNewContext(await fs.readFile(path.join(root, 'public/js/editor-ui.js'), 'utf8'), context);
|
||||
await context.Wegwichtel.EditorUi.open();
|
||||
const list = elements.get('editor-route-list');
|
||||
const item = list.children.find(child => child.dataset.routeId === 'local-existing');
|
||||
list.dispatchEvent(pointerEvent(item.children[1].children[0])); await tick();
|
||||
const poiList = elements.get('editor-poi-list');
|
||||
poiList.dispatchEvent(pointerEvent(poiList.children[0].children[1].children[2])); await tick();
|
||||
elements.get('editor-poi-title').value = 'Noch nicht gespeichert';
|
||||
context.Wegwichtel.EditorUi.close();
|
||||
finish({ id: 0, title: 'Alter Titel', images: [{ url: 'blob:late' }] }); await tick();
|
||||
assert.equal(released.length, 1);
|
||||
assert.equal(elements.get('editor-poi-title').value, 'Noch nicht gespeichert');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user