// Unit tests for the JWT storage helpers. These cover the logic the
// original Angular AuthenticationService.isLoggedIn() performed with
// no guards: a malformed token would have thrown inside atob/JSON.parse.
import {
  saveToken,
  getToken,
  clearToken,
  decodeTokenPayload,
  isTokenValid
} from '../context/token-storage';

// Build an unsigned JWT-shaped token with the given payload.
function buildToken(payload: object): string {
  const encode = (part: object) =>
    btoa(JSON.stringify(part)).replace(/=+$/, '');
  return `${encode({ alg: 'none' })}.${encode(payload)}.signature`;
}

describe('token storage', () => {
  beforeEach(() => {
    localStorage.clear();
  });

  test('saves and retrieves a token under the travlr-token key', () => {
    saveToken('abc123');
    expect(getToken()).toBe('abc123');
    expect(localStorage.getItem('travlr-token')).toBe('abc123');
  });

  test('returns an empty string when no token is stored', () => {
    expect(getToken()).toBe('');
  });

  test('clearToken removes the stored token', () => {
    saveToken('abc123');
    clearToken();
    expect(getToken()).toBe('');
  });

  test('decodes a well-formed token payload', () => {
    const token = buildToken({ email: 'admin@travlr.com', name: 'Admin' });
    expect(decodeTokenPayload(token)).toMatchObject({
      email: 'admin@travlr.com',
      name: 'Admin'
    });
  });

  test('returns null for a malformed token instead of throwing', () => {
    expect(decodeTokenPayload('not-a-jwt')).toBeNull();
  });

  test('accepts an unexpired token', () => {
    const token = buildToken({ exp: Date.now() / 1000 + 3600 });
    expect(isTokenValid(token)).toBe(true);
  });

  test('rejects an expired token', () => {
    const token = buildToken({ exp: Date.now() / 1000 - 60 });
    expect(isTokenValid(token)).toBe(false);
  });

  test('rejects a token with no expiration claim', () => {
    const token = buildToken({ email: 'admin@travlr.com' });
    expect(isTokenValid(token)).toBe(false);
  });
});
