import { describe, it, expect, beforeEach } from 'vitest';
import { GateClaudeInvocationUseCase } from '../../../../../modules/review-execution/usecases/gateClaudeInvocation.usecase.js';
import { StubPendingReviewRequestGateway } from '../../../../../tests/stubs/pendingReviewRequest.stub.js';
import { createStubLogger } from '../../../../../tests/stubs/logger.stub.js';
function buildReviewJob(overrides = {}) {
    return {
        id: 'gitlab:group/project:42',
        platform: 'gitlab',
        projectPath: 'group/project',
        localPath: '/home/user/projects/test',
        mrNumber: 42,
        skill: 'review-code',
        mrUrl: 'https://gitlab.example.com/group/project/-/merge_requests/42',
        sourceBranch: 'feature/x',
        targetBranch: 'main',
        jobType: 'review',
        ...overrides,
    };
}
describe('GateClaudeInvocationUseCase', () => {
    let gateway;
    let enqueueCalls;
    let processorRuns;
    let broadcasts;
    const logger = createStubLogger();
    beforeEach(() => {
        gateway = new StubPendingReviewRequestGateway();
        enqueueCalls = [];
        processorRuns = 0;
        broadcasts = 0;
    });
    const enqueueSuccess = async (job, processor) => {
        enqueueCalls.push(job);
        await processor(job, new AbortController().signal);
        return true;
    };
    const processor = async () => {
        processorRuns += 1;
    };
    describe('Rule: full-auto delegates directly to enqueue', () => {
        it('returns enqueued status and invokes the processor', async () => {
            const useCase = new GateClaudeInvocationUseCase({
                triggerMode: 'full-auto',
                pendingReviewRequestGateway: gateway,
                enqueue: enqueueSuccess,
                broadcastPendingChanged: () => { },
                logger,
            });
            const result = await useCase.execute({
                job: buildReviewJob(),
                triggerSource: 'webhook-initial',
                processor,
            });
            expect(result.status).toBe('enqueued');
            expect(enqueueCalls).toHaveLength(1);
            expect(processorRuns).toBe(1);
        });
        it('returns rejected status when enqueue refuses the job', async () => {
            const enqueueRejects = async () => false;
            const useCase = new GateClaudeInvocationUseCase({
                triggerMode: 'full-auto',
                pendingReviewRequestGateway: gateway,
                enqueue: enqueueRejects,
                broadcastPendingChanged: () => { },
                logger,
            });
            const result = await useCase.execute({
                job: buildReviewJob(),
                triggerSource: 'webhook-initial',
                processor,
            });
            expect(result.status).toBe('rejected');
        });
    });
    describe('Rule: semi-auto persists a pending request and skips enqueue', () => {
        it('saves the pending request and never calls enqueue', async () => {
            const useCase = new GateClaudeInvocationUseCase({
                triggerMode: 'semi-auto',
                pendingReviewRequestGateway: gateway,
                enqueue: enqueueSuccess,
                broadcastPendingChanged: () => {
                    broadcasts += 1;
                },
                logger,
            });
            const result = await useCase.execute({
                job: buildReviewJob(),
                triggerSource: 'webhook-initial',
                processor,
            });
            expect(result.status).toBe('pending');
            expect(enqueueCalls).toHaveLength(0);
            expect(processorRuns).toBe(0);
            expect(gateway.saveCount).toBe(1);
            expect(broadcasts).toBe(1);
        });
        it('persists followup job type when triggered from webhook-followup source', async () => {
            const useCase = new GateClaudeInvocationUseCase({
                triggerMode: 'semi-auto',
                pendingReviewRequestGateway: gateway,
                enqueue: enqueueSuccess,
                broadcastPendingChanged: () => { },
                logger,
            });
            await useCase.execute({
                job: buildReviewJob({ jobType: 'followup' }),
                triggerSource: 'webhook-followup',
                processor,
            });
            const allPending = await gateway.listAll();
            expect(allPending).toHaveLength(1);
            expect(allPending[0].jobType).toBe('followup');
            expect(allPending[0].triggerSource).toBe('webhook-followup');
        });
        it('full-auto followup is unchanged: delegates to enqueue and invokes Claude', async () => {
            const useCase = new GateClaudeInvocationUseCase({
                triggerMode: 'full-auto',
                pendingReviewRequestGateway: gateway,
                enqueue: enqueueSuccess,
                broadcastPendingChanged: () => { },
                logger,
            });
            const result = await useCase.execute({
                job: buildReviewJob({ jobType: 'followup' }),
                triggerSource: 'webhook-followup',
                processor,
            });
            expect(result.status).toBe('enqueued');
            expect(processorRuns).toBe(1);
            expect(gateway.saveCount).toBe(0);
        });
    });
});
//# sourceMappingURL=gateClaudeInvocation.usecase.test.js.map