import {
  AssignRoleDto,
  GrantPermissionDto,
  CheckPermissionDto,
} from '../rbac.dto';

describe('RBAC DTOs', () => {
  describe('AssignRoleDto', () => {
    it('should validate valid assign role data', () => {
      const validData = {
        userId: 'user-123',
        roleId: 'role-admin',
        expiresAt: '2024-12-31T23:59:59.999Z',
      };

      const result = AssignRoleDto.safeParse(validData);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data).toEqual(validData);
      }
    });

    it('should validate assign role data without expiresAt', () => {
      const validData = {
        userId: 'user-123',
        roleId: 'role-admin',
      };

      const result = AssignRoleDto.safeParse(validData);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.userId).toBe(validData.userId);
        expect(result.data.roleId).toBe(validData.roleId);
        expect(result.data.expiresAt).toBeUndefined();
      }
    });

    it('should reject empty userId', () => {
      const invalidData = {
        userId: '',
        roleId: 'role-admin',
      };

      const result = AssignRoleDto.safeParse(invalidData);
      expect(result.success).toBe(false);
      if (!result.success) {
        expect(result.error.issues[0].path).toContain('userId');
      }
    });

    it('should reject empty roleId', () => {
      const invalidData = {
        userId: 'user-123',
        roleId: '',
      };

      const result = AssignRoleDto.safeParse(invalidData);
      expect(result.success).toBe(false);
      if (!result.success) {
        expect(result.error.issues[0].path).toContain('roleId');
      }
    });

    it('should reject invalid datetime format', () => {
      const invalidData = {
        userId: 'user-123',
        roleId: 'role-admin',
        expiresAt: 'invalid-date',
      };

      const result = AssignRoleDto.safeParse(invalidData);
      expect(result.success).toBe(false);
      if (!result.success) {
        expect(result.error.issues[0].path).toContain('expiresAt');
      }
    });
  });

  describe('GrantPermissionDto', () => {
    it('should validate valid grant permission data', () => {
      const validData = {
        userId: 'user-123',
        permissionId: 'perm-read-users',
        expiresAt: '2024-12-31T23:59:59.999Z',
      };

      const result = GrantPermissionDto.safeParse(validData);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data).toEqual(validData);
      }
    });

    it('should validate grant permission data without expiresAt', () => {
      const validData = {
        userId: 'user-123',
        permissionId: 'perm-read-users',
      };

      const result = GrantPermissionDto.safeParse(validData);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.userId).toBe(validData.userId);
        expect(result.data.permissionId).toBe(validData.permissionId);
        expect(result.data.expiresAt).toBeUndefined();
      }
    });

    it('should reject empty userId', () => {
      const invalidData = {
        userId: '',
        permissionId: 'perm-read-users',
      };

      const result = GrantPermissionDto.safeParse(invalidData);
      expect(result.success).toBe(false);
      if (!result.success) {
        expect(result.error.issues[0].path).toContain('userId');
      }
    });

    it('should reject empty permissionId', () => {
      const invalidData = {
        userId: 'user-123',
        permissionId: '',
      };

      const result = GrantPermissionDto.safeParse(invalidData);
      expect(result.success).toBe(false);
      if (!result.success) {
        expect(result.error.issues[0].path).toContain('permissionId');
      }
    });
  });

  describe('CheckPermissionDto', () => {
    it('should validate valid check permission data', () => {
      const validData = {
        resource: 'users',
        action: 'read',
        scope: 'own',
      };

      const result = CheckPermissionDto.safeParse(validData);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data).toEqual(validData);
      }
    });

    it('should validate check permission data without scope', () => {
      const validData = {
        resource: 'users',
        action: 'read',
      };

      const result = CheckPermissionDto.safeParse(validData);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.resource).toBe(validData.resource);
        expect(result.data.action).toBe(validData.action);
        expect(result.data.scope).toBeUndefined();
      }
    });

    it('should reject empty resource', () => {
      const invalidData = {
        resource: '',
        action: 'read',
      };

      const result = CheckPermissionDto.safeParse(invalidData);
      expect(result.success).toBe(false);
      if (!result.success) {
        expect(result.error.issues[0].path).toContain('resource');
      }
    });

    it('should reject empty action', () => {
      const invalidData = {
        resource: 'users',
        action: '',
      };

      const result = CheckPermissionDto.safeParse(invalidData);
      expect(result.success).toBe(false);
      if (!result.success) {
        expect(result.error.issues[0].path).toContain('action');
      }
    });
  });
});