import { SetMetadata } from '@nestjs/common';
import { RequireCapability, FEATURE_AVAILABILITY_METADATA_KEY, FeatureAvailabilityMetadata } from './RequireCapability';
import { ActionType } from './PolicyService';

// Mock SetMetadata
vi.mock('@nestjs/common', () => ({
  SetMetadata: vi.fn(),
}));

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

  it('should call SetMetadata with correct key and metadata', () => {
    const capabilityKey = 'test-feature';
    const actionType: ActionType = 'view';

    RequireCapability(capabilityKey, actionType);

    expect(SetMetadata).toHaveBeenCalledWith(
      FEATURE_AVAILABILITY_METADATA_KEY,
      {
        capabilityKey,
        actionType,
      } satisfies FeatureAvailabilityMetadata
    );
  });

  it('should work with mutate action type', () => {
    const capabilityKey = 'test-feature';
    const actionType: ActionType = 'mutate';

    RequireCapability(capabilityKey, actionType);

    expect(SetMetadata).toHaveBeenCalledWith(
      FEATURE_AVAILABILITY_METADATA_KEY,
      {
        capabilityKey,
        actionType,
      } satisfies FeatureAvailabilityMetadata
    );
  });

  it('should work with different capability keys', () => {
    const capabilityKey = 'another-feature';
    const actionType: ActionType = 'view';

    RequireCapability(capabilityKey, actionType);

    expect(SetMetadata).toHaveBeenCalledWith(
      FEATURE_AVAILABILITY_METADATA_KEY,
      {
        capabilityKey,
        actionType,
      } satisfies FeatureAvailabilityMetadata
    );
  });

  it('should return a decorator function', () => {
    const capabilityKey = 'test-feature';
    const actionType: ActionType = 'view';

    const decorator = RequireCapability(capabilityKey, actionType);

    expect(typeof decorator).toBe('function');
  });
});
