import { ValidationPipe } from '@nestjs/common';
import { AdminUsersQueryDto, MAX_LIMIT } from './users-query.dto';

const pipe = new ValidationPipe({
  whitelist: true,
  forbidNonWhitelisted: true,
  transform: true,
});

async function transform(input: unknown): Promise<AdminUsersQueryDto> {
  return (await pipe.transform(input, {
    type: 'query',
    metatype: AdminUsersQueryDto,
  })) as AdminUsersQueryDto;
}

describe('AdminUsersQueryDto', () => {
  it('accepts an empty query', async () => {
    await expect(transform({})).resolves.toEqual({});
  });

  it('coerces numeric strings (URL query format) into numbers', async () => {
    const out = await transform({ limit: '25', offset: '50' });
    expect(out.limit).toBe(25);
    expect(out.offset).toBe(50);
  });

  it('rejects a limit above MAX_LIMIT', async () => {
    await expect(transform({ limit: String(MAX_LIMIT + 1) })).rejects.toThrow();
  });

  it('rejects a negative offset', async () => {
    await expect(transform({ offset: '-1' })).rejects.toThrow();
  });

  it('accepts a valid audience enum value', async () => {
    await expect(transform({ audience: 'workforce' })).resolves.toMatchObject({
      audience: 'workforce',
    });
    await expect(transform({ audience: 'customer' })).resolves.toMatchObject({
      audience: 'customer',
    });
  });

  it('rejects an unknown audience', async () => {
    await expect(transform({ audience: 'admin' })).rejects.toThrow();
  });

  it('rejects an ill-formed lastSeenAtFrom', async () => {
    await expect(transform({ lastSeenAtFrom: 'yesterday' })).rejects.toThrow();
  });

  it('rejects an unknown query key (forbidNonWhitelisted)', async () => {
    await expect(transform({ password: 'leak' })).rejects.toThrow();
  });

  it('rejects an over-long username', async () => {
    await expect(transform({ username: 'a'.repeat(129) })).rejects.toThrow();
  });
});
