import { describe, it, expect, beforeEach } from 'vitest';
import { ConfirmPendingReviewUseCase } from '../../../../../modules/review-execution/usecases/confirmPendingReview.usecase.js';
import { StubPendingReviewRequestGateway } from '../../../../../tests/stubs/pendingReviewRequest.stub.js';
import { PendingReviewRequestFactory } from '../../../../../tests/factories/pendingReviewRequest.factory.js';
import { createStubLogger } from '../../../../../tests/stubs/logger.stub.js';
describe('ConfirmPendingReviewUseCase', () => {
    let gateway;
    let activeJobs;
    let enqueueCalls;
    let processorRuns;
    const logger = createStubLogger();
    beforeEach(() => {
        gateway = new StubPendingReviewRequestGateway();
        activeJobs = new Set();
        enqueueCalls = [];
        processorRuns = 0;
    });
    const enqueueSuccess = async (job, processor) => {
        enqueueCalls.push(job);
        activeJobs.add(job.id);
        await processor(job, new AbortController().signal);
        return true;
    };
    const fakeProcessor = async () => {
        processorRuns += 1;
    };
    function makeUseCase() {
        return new ConfirmPendingReviewUseCase({
            pendingReviewRequestGateway: gateway,
            queuePort: {
                hasActiveJob: (id) => activeJobs.has(id),
                getJobStatus: () => null,
            },
            enqueue: enqueueSuccess,
            resolveProcessor: () => fakeProcessor,
            logger,
        });
    }
    describe('Rule: confirming a pending job enqueues it and invokes Claude', () => {
        it('returns confirmed and deletes the pending entry', async () => {
            const pending = PendingReviewRequestFactory.create();
            gateway.prepopulate(pending);
            const result = await makeUseCase().execute({ pendingId: pending.pendingReviewRequestId });
            expect(result.status).toBe('confirmed');
            expect(enqueueCalls).toHaveLength(1);
            expect(processorRuns).toBe(1);
            expect(gateway.deleteCount).toBe(1);
            expect(await gateway.listAll()).toHaveLength(0);
        });
    });
    describe('Rule: confirming a missing job returns not-found', () => {
        it('returns not-found when the pending id is unknown', async () => {
            const result = await makeUseCase().execute({ pendingId: 'unknown-id' });
            expect(result.status).toBe('not-found');
        });
    });
    describe('Rule: confirming an already-running review is rejected with a French message', () => {
        it('returns already-running and the exact French message from the spec', async () => {
            const pending = PendingReviewRequestFactory.create();
            gateway.prepopulate(pending);
            activeJobs.add(pending.job.id);
            const result = await makeUseCase().execute({ pendingId: pending.pendingReviewRequestId });
            expect(result.status).toBe('already-running');
            if (result.status === 'already-running') {
                expect(result.message).toBe('Cette review est déjà en cours');
            }
            expect(enqueueCalls).toHaveLength(0);
        });
    });
    describe('Rule: confirming a request that the queue refuses returns already-running', () => {
        it('reports already-running when enqueue refuses (race against running job)', async () => {
            const pending = PendingReviewRequestFactory.create();
            gateway.prepopulate(pending);
            const useCase = new ConfirmPendingReviewUseCase({
                pendingReviewRequestGateway: gateway,
                queuePort: { hasActiveJob: () => false, getJobStatus: () => null },
                enqueue: async () => false,
                resolveProcessor: () => fakeProcessor,
                logger,
            });
            const result = await useCase.execute({ pendingId: pending.pendingReviewRequestId });
            expect(result.status).toBe('already-running');
        });
    });
});
//# sourceMappingURL=confirmPendingReview.usecase.test.js.map