/**
 * Regression guard — privilege escalation via mixed auth storage.
 *
 * The admin JWT lives in sessionStorage; guest JWTs in localStorage; reads are
 * sessionStorage-first. So a guest login MUST displace any resident admin token — otherwise
 * a leftover admin session on a shared "event laptop" would shadow the guest's own token and
 * silently hand the next person who joins full admin rights. This exercises the real UI flow.
 */
import { test, expect } from '../../fixtures/test';
import { JoinPage } from '../../page-objects';

function roleOf(page: import('@playwright/test').Page) {
  return page.evaluate(() => {
    const t = sessionStorage.getItem('eventsnap_jwt') ?? localStorage.getItem('eventsnap_jwt');
    if (!t) return null;
    try {
      return JSON.parse(atob(t.split('.')[1])).role;
    } catch {
      return null;
    }
  });
}

test.describe('AuthZ — guest join displaces a resident admin session', () => {
  test('joining as a guest with an admin token resident in sessionStorage yields GUEST rights', async ({
    page,
    api,
  }) => {
    // Simulate an admin who logged in on a shared device and walked away without closing the
    // tab — their token sits in sessionStorage.
    const adminJwt = await api.adminLogin();
    await page.goto('/');
    await page.evaluate((jwt) => sessionStorage.setItem('eventsnap_jwt', jwt), adminJwt);

    // A different person now joins as a guest in that same tab.
    const join = new JoinPage(page);
    await join.goto();
    await join.joinAs('DisplacementGuest');
    await join.continueToFeed();

    // The effective identity must be the GUEST — not the leftover admin.
    expect(await roleOf(page)).toBe('guest');
    // The admin token must have been cleared from sessionStorage by the guest login.
    expect(await page.evaluate(() => sessionStorage.getItem('eventsnap_jwt'))).toBeNull();

    // And the guest must NOT be able to reach the admin dashboard.
    await page.goto('/admin');
    await page.waitForURL(/admin\/login|join|feed/, { timeout: 5_000 });
    expect(page.url()).not.toMatch(/\/admin(\/)?$/);
  });
});
