import { NotificationsService } from './notifications.service';

describe('Notification event idempotency', () => {
  const dto = {
    eventId: 'event-duplicate',
    actorId: '507f1f77bcf86cd799439011',
    recipientId: '507f191e810c19729de860ea',
    requestId: '507f1f77bcf86cd799439012',
  };

  it('returns the existing record when the same event is delivered twice', async () => {
    const existing = { _id: 'notification-1' };
    const repository = {
      findByEventId: jest.fn().mockResolvedValue(existing),
      create: jest.fn(),
    };
    const gateway = { emitCreated: jest.fn() };
    const service = new NotificationsService(repository as never, gateway as never);

    await expect(service.createFollowRequestApprovedNotification(dto)).resolves.toBe(existing);
    await expect(service.createFollowRequestApprovedNotification(dto)).resolves.toBe(existing);
    expect(repository.findByEventId).toHaveBeenCalledTimes(2);
    expect(repository.create).not.toHaveBeenCalled();
    expect(gateway.emitCreated).not.toHaveBeenCalled();
  });

  it('recovers from a concurrent duplicate-key insert', async () => {
    const existing = { _id: 'notification-1' };
    const repository = {
      findByEventId: jest.fn().mockResolvedValueOnce(null).mockResolvedValueOnce(existing),
      create: jest.fn().mockRejectedValue({ code: 11000 }),
    };
    const service = new NotificationsService(repository as never, { emitCreated: jest.fn() } as never);

    await expect(service.createFollowRequestApprovedNotification(dto)).resolves.toBe(existing);
    expect(repository.create).toHaveBeenCalledTimes(1);
  });
});
