import { UserRole } from './UserRole';

describe('UserRole', () => {
  describe('TDD - Test First', () => {
    it('should create a valid role from string', () => {
      // Arrange & Act
      const role = UserRole.fromString('owner');

      // Assert
      expect(role.value).toBe('owner');
    });

    it('should trim whitespace', () => {
      // Arrange & Act
      const role = UserRole.fromString('  admin  ');

      // Assert
      expect(role.value).toBe('admin');
    });

    it('should throw error for empty string', () => {
      // Arrange & Act & Assert
      expect(() => UserRole.fromString('')).toThrow('Role cannot be empty');
      expect(() => UserRole.fromString('   ')).toThrow('Role cannot be empty');
    });

    it('should throw error for null or undefined', () => {
      // Arrange & Act & Assert
      expect(() => UserRole.fromString(null as unknown as string)).toThrow('Role cannot be empty');
      expect(() => UserRole.fromString(undefined as unknown as string)).toThrow('Role cannot be empty');
    });

    it('should handle all valid roles', () => {
      // Arrange & Act
      const owner = UserRole.fromString('owner');
      const admin = UserRole.fromString('admin');
      const user = UserRole.fromString('user');

      // Assert
      expect(owner.value).toBe('owner');
      expect(admin.value).toBe('admin');
      expect(user.value).toBe('user');
    });

    it('should detect system admin roles', () => {
      // Arrange
      const owner = UserRole.fromString('owner');
      const admin = UserRole.fromString('admin');
      const user = UserRole.fromString('user');

      // Assert
      expect(owner.isSystemAdmin()).toBe(true);
      expect(admin.isSystemAdmin()).toBe(true);
      expect(user.isSystemAdmin()).toBe(false);
    });

    it('should support equals comparison', () => {
      // Arrange
      const role1 = UserRole.fromString('owner');
      const role2 = UserRole.fromString('owner');
      const role3 = UserRole.fromString('admin');

      // Assert
      expect(role1.equals(role2)).toBe(true);
      expect(role1.equals(role3)).toBe(false);
    });

    it('should support toString', () => {
      // Arrange
      const role = UserRole.fromString('owner');

      // Assert
      expect(role.toString()).toBe('owner');
    });

    it('should handle custom roles', () => {
      // Arrange & Act
      const customRole = UserRole.fromString('steward');

      // Assert
      expect(customRole.value).toBe('steward');
      expect(customRole.isSystemAdmin()).toBe(false);
    });

    it('should handle case sensitivity', () => {
      // Arrange & Act
      const role1 = UserRole.fromString('Owner');
      const role2 = UserRole.fromString('owner');

      // Assert - Should preserve case but compare as-is
      expect(role1.value).toBe('Owner');
      expect(role2.value).toBe('owner');
    });

    it('should handle special characters in role names', () => {
      // Arrange & Act
      const role = UserRole.fromString('admin-steward');

      // Assert
      expect(role.value).toBe('admin-steward');
    });
  });
});