group editor code display changed
Sonarqube Scanner / Prepare environment (push) Successful in 6s
Sonarqube Scanner / Build and test (push) Successful in 22s
Sonarqube Scanner / SonarQube analysis (push) Successful in 56s
Sonarqube Scanner / Deploy to Server (push) Successful in 6s

This commit is contained in:
Florian Zumpe
2026-10-18 23:03:12 +02:00
parent 04e05ecfd4
commit a66a795407
10 changed files with 109 additions and 111 deletions
+34 -33
View File
@@ -27,7 +27,7 @@ function key(node, value) {
}
async function harness(loading = false) {
const ids = ['group-join-open', 'editor-group-join', 'editor-group-list', 'group-dialog', 'group-close',
'group-share-dialog', 'group-share-route', 'group-share-pictures', 'group-share-start', 'group-share-close',
'group-entry-dialog', 'group-entry-close', 'group-entry-status', 'group-route',
'group-status', 'group-wheels', 'group-entry', 'group-invitation', 'group-code', 'group-join', 'group-edit', 'group-expiry'];
const nodes = new Map(ids.map(id => [id, new Element()]));
const document = new EventTarget();
@@ -66,9 +66,9 @@ test('group code wheels support arrows, keyboard wrapping, scrolling and joining
const h = await harness(true);
h.context.document.dispatchEvent(new Event('DOMContentLoaded'));
pointer(h.nodes.get('group-join-open'), { isPrimary: false });
assert.equal(h.nodes.get('group-dialog').open, false);
assert.equal(h.nodes.get('group-entry-dialog').open, false);
pointer(h.nodes.get('group-join-open'));
assert.equal(h.nodes.get('group-dialog').open, true);
assert.equal(h.nodes.get('group-entry-dialog').open, true);
const columns = h.nodes.get('group-wheels').children;
assert.equal(columns.length, 5);
const [up, viewport, down] = columns[0].children;
@@ -82,7 +82,7 @@ test('group code wheels support arrows, keyboard wrapping, scrolling and joining
key(viewport, 'Home'); key(viewport, 'ArrowDown');
pointer(viewport.children[5]);
assert.equal(viewport.attributes.get('aria-valuetext'), 'Vogel');
viewport.scrollTop = 3 * 52; viewport.dispatchEvent(new Event('scroll'));
viewport.scrollTop = 3 * 96; viewport.dispatchEvent(new Event('scroll'));
key(h.nodes.get('group-join'), ' ');
await tick();
const joined = h.calls.find(call => call.url.endsWith('/join'));
@@ -91,10 +91,10 @@ test('group code wheels support arrows, keyboard wrapping, scrolling and joining
assert.equal(body.code[0], '🌼');
assert.equal(body.creator_id, 'a'.repeat(64));
assert.deepEqual(h.edits, [22]);
assert.equal(h.nodes.get('group-dialog').open, false);
assert.equal(h.nodes.get('group-entry-dialog').open, false);
pointer(h.nodes.get('editor-group-join'));
pointer(h.nodes.get('group-close'));
assert.equal(h.nodes.get('group-dialog').open, false);
pointer(h.nodes.get('group-entry-close'));
assert.equal(h.nodes.get('group-entry-dialog').open, false);
});
test('sharing displays five motifs and the owner can renew or close access with confirmation', async () => {
@@ -102,11 +102,14 @@ test('sharing displays five motifs and the owner can renew or close access with
await h.groups.share(7);
assert.equal(JSON.parse(h.calls[0].body).routeId, 7);
assert.equal(h.nodes.get('group-code').children.length, 5);
assert.equal(h.nodes.get('group-entry').hidden, true);
assert.equal(h.nodes.get('group-entry-dialog').open, false);
assert.equal(h.nodes.get('group-dialog').open, true);
assert.match(h.nodes.get('group-expiry').textContent, /Code gilt/);
const shareButton = h.groups.shareButton('share-route');
assert.equal(shareButton.dataset.editorAction, 'share-route');
assert.equal(shareButton.textContent, '👥');
assert.equal(shareButton.children.length, 1);
assert.equal(shareButton.children[0].src, '/images/icons/group-edit.svg');
assert.equal(shareButton.children[0].alt, '');
assert.equal(shareButton.attributes.get('aria-haspopup'), 'dialog');
pointer(h.nodes.get('group-edit')); await tick();
assert.deepEqual(h.edits, [22]);
@@ -140,13 +143,13 @@ test('code failures are localized and group list refresh never advances an editi
for (const [status, text] of [[404, /Code stimmt/], [401, /nicht geöffnet/], [403, /nicht geöffnet/], [409, /inzwischen geändert/], [429, /eine Minute/], [500, /Internetverbindung/]]) {
h.controls.error = status;
pointer(h.nodes.get('group-join')); await tick();
assert.match(h.nodes.get('group-status').textContent, text);
assert.match(h.nodes.get('group-entry-status').textContent, text);
assert.equal(h.nodes.get('group-join').disabled, false);
}
h.controls.error = 0; h.controls.offline = true;
h.context.Wegwichtel.I18n.setLanguage('en', null);
pointer(h.nodes.get('group-join')); await tick();
assert.match(h.nodes.get('group-status').textContent, /internet connection/);
assert.match(h.nodes.get('group-entry-status').textContent, /internet connection/);
await h.groups.refresh();
});
@@ -161,10 +164,10 @@ test('a late join response does not reopen a cancelled dialog or editor', async
pointer(h.nodes.get('group-join-open'));
pointer(h.nodes.get('group-join'));
await tick();
pointer(h.nodes.get('group-close'));
pointer(h.nodes.get('group-entry-close'));
release();
await tick();
assert.equal(h.nodes.get('group-dialog').open, false);
assert.equal(h.nodes.get('group-entry-dialog').open, false);
assert.deepEqual(h.edits, []);
});
@@ -189,29 +192,27 @@ test('unsent station changes are listed before network access and discarded only
assert.equal(list.children.length, 0);
});
test('compact sharing button opens a large gnome preview and requires confirmation before starting', async () => {
test('sharing opens the actual five-symbol invitation directly without a two-symbol preview', async () => {
const h = await harness();
const decision = h.groups.confirmShare('Blumenweg');
const dialog = h.nodes.get('group-share-dialog');
assert.equal(dialog.open, true);
assert.equal(h.nodes.get('group-share-route').textContent, 'Blumenweg');
const pictures = h.nodes.get('group-share-pictures').children;
assert.equal(pictures.length, 2);
assert.match(pictures[0].src, /🐦/);
assert.match(pictures[1].src, /🪨/);
assert.equal(h.calls.length, 0);
assert.equal(await h.groups.confirmShare('Zweiter Weg'), false);
pointer(h.nodes.get('group-share-close'));
assert.equal(await decision, false);
const accepted = h.groups.confirmShare('Blumenweg');
key(h.nodes.get('group-share-start'), 'Enter');
assert.equal(await accepted, true);
assert.equal(dialog.open, false);
const dismissed = h.groups.confirmShare('Blumenweg');
dialog.close();
assert.equal(await dismissed, false);
await h.groups.share(7);
assert.equal(h.nodes.get('group-dialog').open, true);
assert.equal(h.nodes.get('group-entry-dialog').open, false);
assert.equal(h.nodes.get('group-code').children.length, 5);
assert.equal(h.nodes.get('group-route').textContent, 'Waldweg');
pointer(h.nodes.get('group-close'));
pointer(h.nodes.get('editor-group-join'));
assert.equal(h.nodes.get('group-entry-dialog').open, true);
assert.equal(h.nodes.get('group-dialog').open, false);
assert.equal(h.nodes.get('group-wheels').children.length, 5);
});
test('an incomplete invitation is never displayed as a two-symbol group code', async () => {
const h = await harness();
h.context.fetch = async () => ({ ok: true, json: async () => ({ group: { route: { id: 7 } }, code: ['🐦', '🪨'] }) });
await assert.rejects(h.groups.share(7));
assert.equal(h.nodes.get('group-dialog').open, false);
assert.equal(h.nodes.get('group-code').children.length, 0);
});
test('the open invitation refreshes its code automatically and shows a deferred renewal during station editing', async () => {
const h = await harness();