import { describe, expect, it, vi } from 'vitest';
import * as fs from 'node:fs';
import * as path from 'node:path';

import { TypeOrmRaceRepository } from './TypeOrmRaceRepository';

describe('TypeOrmRaceRepository', () => {
  it('does not construct its own mapper dependencies', () => {
    const sourcePath = path.resolve(__dirname, 'TypeOrmRaceRepository.ts');
    const source = fs.readFileSync(sourcePath, 'utf8');

    expect(source).not.toMatch(/new\s+RaceOrmMapper\s*\(/);
    expect(source).not.toMatch(/=\s*new\s+RaceOrmMapper\s*\(/);
  });

  it('requires mapper injection via constructor (no default mapper)', () => {
    expect(TypeOrmRaceRepository.length).toBe(2);
  });

  it('uses the injected mapper at runtime (DB-free)', async () => {
    const ormRepo = {
      findOne: vi.fn().mockResolvedValue({ id: 'r1' }),
    };

    const dataSource = {
      getRepository: vi.fn().mockReturnValue(ormRepo),
    };

    const mapper = {
      toDomain: vi.fn().mockReturnValue({ id: 'domain' }),
      toOrmEntity: vi.fn(),
    };

    const repo = new TypeOrmRaceRepository(dataSource as any, mapper as any);

    const race = await repo.findById('r1');

    expect(dataSource.getRepository).toHaveBeenCalledTimes(1);
    expect(ormRepo.findOne).toHaveBeenCalledTimes(1);
    expect(mapper.toDomain).toHaveBeenCalledTimes(1);
    expect(race).toEqual({ id: 'domain' });
  });
});