import { describe, it, expect, beforeEach, vi } from 'vitest';
import { RoleAuthManager } from '../role-auth-manager';

// Mock fetch
global.fetch = vi.fn();

describe('RoleAuthManager', () => {
  beforeEach(() => {
    RoleAuthManager.clearCache();
    vi.clearAllMocks();
  });

  it('should authenticate and cache token', async () => {
    const mockToken = 'mock-jwt-token-12345';
    (global.fetch as any).mockResolvedValueOnce({
      ok: true,
      json: async () => ({ data: { token: mockToken } })
    });

    const token = await RoleAuthManager.getRoleToken('admin');
    
    expect(token).toBe(mockToken);
    expect(global.fetch).toHaveBeenCalledWith(
      expect.stringContaining('/api/auth/login'),
      expect.objectContaining({
        method: 'POST',
        body: expect.stringContaining('admin')
      })
    );
  });

  it('should return cached token on second call', async () => {
    const mockToken = 'cached-token';
    (global.fetch as any).mockResolvedValueOnce({
      ok: true,
      json: async () => ({ data: { token: mockToken } })
    });

    const token1 = await RoleAuthManager.getRoleToken('admin');
    const token2 = await RoleAuthManager.getRoleToken('admin');

    expect(token1).toBe(token2);
    expect(global.fetch).toHaveBeenCalledTimes(1);
  });

  it('should throw error for unknown role', async () => {
    await expect(RoleAuthManager.getRoleToken('unknown')).rejects.toThrow("Role 'unknown' not found");
  });

  it('should throw error on authentication failure', async () => {
    (global.fetch as any).mockResolvedValueOnce({
      ok: false,
      statusText: 'Unauthorized'
    });

    await expect(RoleAuthManager.getRoleToken('admin')).rejects.toThrow('Authentication failed');
  });

  it('should clear specific role token', async () => {
    const mockToken = 'token-to-clear';
    (global.fetch as any).mockResolvedValueOnce({
      ok: true,
      json: async () => ({ data: { token: mockToken } })
    });

    await RoleAuthManager.getRoleToken('admin');
    RoleAuthManager.clearRoleToken('admin');
    
    // 再次获取应该重新认证
    (global.fetch as any).mockResolvedValueOnce({
      ok: true,
      json: async () => ({ data: { token: 'new-token' } })
    });
    
    const newToken = await RoleAuthManager.getRoleToken('admin');
    expect(newToken).toBe('new-token');
    expect(global.fetch).toHaveBeenCalledTimes(2);
  });
});
