import { afterEach, expect, test, vi } from 'vitest';
import { canAdminister, canOperate, clearAccessToken, getAccessToken, notifyUnauthorizedSession, PLATFORM_UNAUTHORIZED_EVENT, setAccessToken } from './session';

afterEach(() => {
  window.sessionStorage.clear();
  window.localStorage.clear();
});

test('access token is scoped to the browser session and can be cleared', () => {
  setAccessToken('  secret-token  ');
  expect(getAccessToken()).toBe('secret-token');
  expect(window.localStorage.length).toBe(0);
  clearAccessToken();
  expect(getAccessToken()).toBe('');
});

test('role helpers follow the server permission hierarchy', () => {
  expect(canOperate({ name: 'v', role: 'viewer', authMode: 'enforce' })).toBe(false);
  expect(canOperate({ name: 'o', role: 'operator', authMode: 'enforce' })).toBe(true);
  expect(canAdminister({ name: 'o', role: 'operator', authMode: 'enforce' })).toBe(false);
  expect(canAdminister({ name: 'a', role: 'admin', authMode: 'enforce' })).toBe(true);
});

test('invalidates only the currently active rejected token', () => {
  const unauthorized = vi.fn();
  window.addEventListener(PLATFORM_UNAUTHORIZED_EVENT, unauthorized);
  setAccessToken('new-token');

  expect(notifyUnauthorizedSession('old-token')).toBe(false);
  expect(getAccessToken()).toBe('new-token');
  expect(notifyUnauthorizedSession('new-token')).toBe(true);
  expect(getAccessToken()).toBe('');
  expect(notifyUnauthorizedSession('new-token')).toBe(false);
  expect(unauthorized).toHaveBeenCalledTimes(1);

  window.removeEventListener(PLATFORM_UNAUTHORIZED_EVENT, unauthorized);
});
