fix(account): Konto-Menü zeichnet bei unverändertem Namen nicht neu (Dropdown und Fokus bleiben)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
04404ffdae
commit
f46a69df68
2 files changed
+60
-1
No files matched your search
@@ -262,6 +262,57 @@ describe('Konto-Menü: Benutzername', () => {
|
|||||||
expect(buttonByText('Benutzername ändern')).toBeDefined();
|
expect(buttonByText('Benutzername ändern')).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('meldet onUsernameChange denselben Namen noch einmal (Lesen des eigenen Profils nach dem Start), bleibt das Menü unangetastet: offen und mit dem Fokus', () => {
|
||||||
|
signedIn();
|
||||||
|
mocks.name = 'Kenso';
|
||||||
|
menu.ready();
|
||||||
|
avatar()!.click();
|
||||||
|
const before = { avatar: avatar(), panel: panel(), head: head() };
|
||||||
|
const signOut = buttonByText('Abmelden')!;
|
||||||
|
signOut.focus();
|
||||||
|
setName('u1', 'Kenso');
|
||||||
|
expect(avatar()).toBe(before.avatar); // dieselben Elemente, nichts wurde neu gebaut
|
||||||
|
expect(panel()).toBe(before.panel);
|
||||||
|
expect(head()).toBe(before.head);
|
||||||
|
expect(panel()?.hidden).toBe(false);
|
||||||
|
expect(avatar()?.getAttribute('aria-expanded')).toBe('true');
|
||||||
|
expect(document.activeElement).toBe(signOut);
|
||||||
|
expect(nameLine()?.textContent).toBe('@Kenso');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('ein anderer Name oder nur eine andere Schreibweise zeichnet dagegen neu', () => {
|
||||||
|
signedIn();
|
||||||
|
mocks.name = 'kenso';
|
||||||
|
menu.ready();
|
||||||
|
const before = avatar();
|
||||||
|
setName('u1', 'Kenso'); // „kenso“ → „Kenso“ ist erlaubt (Spec § 4) und soll zu sehen sein
|
||||||
|
expect(avatar()).not.toBe(before);
|
||||||
|
expect(nameLine()?.textContent).toBe('@Kenso');
|
||||||
|
const second = avatar();
|
||||||
|
setName('u1', 'Mia');
|
||||||
|
expect(avatar()).not.toBe(second);
|
||||||
|
expect(nameLine()?.textContent).toBe('@Mia');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('die Namensmeldung eines anderen Kontos ändert nichts am Menü des angemeldeten', () => {
|
||||||
|
signedIn();
|
||||||
|
mocks.name = 'Kenso'; // der Name des angemeldeten Kontos bleibt
|
||||||
|
menu.ready();
|
||||||
|
avatar()!.click();
|
||||||
|
const before = panel();
|
||||||
|
for (const fn of [...mocks.nameListeners]) fn('u2', 'Mia'); // das Konto u2 hat sich umbenannt (etwa in einem eben beendeten Aufruf)
|
||||||
|
expect(panel()).toBe(before);
|
||||||
|
expect(panel()?.hidden).toBe(false);
|
||||||
|
expect(nameLine()?.textContent).toBe('@Kenso');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('abgemeldet bleibt der Anmelden-Knopf stehen, auch wenn ein Name gemeldet wird (das Konto, das speicherte, ist nicht mehr angemeldet)', () => {
|
||||||
|
menu.ready();
|
||||||
|
const signIn = buttonByText('Anmelden');
|
||||||
|
for (const fn of [...mocks.nameListeners]) fn('u2', 'Mia');
|
||||||
|
expect(buttonByText('Anmelden')).toBe(signIn);
|
||||||
|
});
|
||||||
|
|
||||||
it('nach dem Abmelden ist das Menü unabhängig vom Namen wieder „Anmelden“', () => {
|
it('nach dem Abmelden ist das Menü unabhängig vom Namen wieder „Anmelden“', () => {
|
||||||
signedIn();
|
signedIn();
|
||||||
mocks.name = 'Kenso';
|
mocks.name = 'Kenso';
|
||||||
|
|||||||
@@ -20,10 +20,14 @@ export function mountAccountMenu(slot: HTMLElement): AccountMenu {
|
|||||||
let isReady = false;
|
let isReady = false;
|
||||||
// Hebt die Dokument-Listener des gerade offenen Menüs wieder auf (null: kein Menü gezeichnet).
|
// Hebt die Dokument-Listener des gerade offenen Menüs wieder auf (null: kein Menü gezeichnet).
|
||||||
let detach: (() => void) | null = null;
|
let detach: (() => void) | null = null;
|
||||||
|
// Der Name, den das gezeichnete Menü zeigt (null: keiner oder gar kein Konto-Menü). Meldet `onUsernameChange` denselben Namen noch einmal
|
||||||
|
// (etwa das Lesen des eigenen Profils nach dem Start), bleibt das Menü stehen: ein neu gebautes Dropdown wäre zu und verlöre den Fokus.
|
||||||
|
let shownName: string | null = null;
|
||||||
|
|
||||||
function render(): void {
|
function render(): void {
|
||||||
detach?.();
|
detach?.();
|
||||||
detach = null;
|
detach = null;
|
||||||
|
shownName = null;
|
||||||
if (!isReady) {
|
if (!isReady) {
|
||||||
slot.replaceChildren();
|
slot.replaceChildren();
|
||||||
return;
|
return;
|
||||||
@@ -50,6 +54,7 @@ export function mountAccountMenu(slot: HTMLElement): AccountMenu {
|
|||||||
);
|
);
|
||||||
// Mit Benutzernamen steht „@name“ oben und die E-Mail klein darunter; ohne Namen (noch nicht gelesen oder nicht gewählt) nur die E-Mail.
|
// Mit Benutzernamen steht „@name“ oben und die E-Mail klein darunter; ohne Namen (noch nicht gelesen oder nicht gewählt) nur die E-Mail.
|
||||||
const name = myUsername();
|
const name = myUsername();
|
||||||
|
shownName = name;
|
||||||
const email = el('span', { class: 'account-email', title: user.email }, user.email);
|
const email = el('span', { class: 'account-email', title: user.email }, user.email);
|
||||||
const head = el(
|
const head = el(
|
||||||
'div',
|
'div',
|
||||||
@@ -112,7 +117,10 @@ export function mountAccountMenu(slot: HTMLElement): AccountMenu {
|
|||||||
|
|
||||||
const off = onAuthChange(render);
|
const off = onAuthChange(render);
|
||||||
// Der Name steht fest oder ändert sich (gelesen nach dem Start, gespeichert im Dialog): das Menü zeigt gleich den neuen.
|
// Der Name steht fest oder ändert sich (gelesen nach dem Start, gespeichert im Dialog): das Menü zeigt gleich den neuen.
|
||||||
const offName = onUsernameChange(render);
|
const offName = onUsernameChange(() => {
|
||||||
|
if (myUsername() === shownName) return; // nichts Neues zu zeigen (derselbe Name, oder ein anderes Konto hat gespeichert)
|
||||||
|
render();
|
||||||
|
});
|
||||||
render();
|
render();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in new issue
Block a user