import { describe, expect, it, vi } from 'vitest';
import { emailIngestionIngestResolver } from '../resolvers/email-ingestion-ingest.resolver.js';
import { EmailIngestionIngestProvider } from '../providers/email-ingestion-ingest.provider.js';
import { IngestOutcome, IngestReasonCode } from '../contracts.js';
// ---------------------------------------------------------------------------
// Mock helpers
// ---------------------------------------------------------------------------
const BASE_INPUT = {
    grantJti: 'jti-uuid',
    idempotencyKey: 'idem-key-001',
    tenantId: 'tenant-uuid-a',
    messageId: 'msg-abc-123',
    rawMessageHash: 'sha256-abc',
    correlationId: 'corr-001',
    extractedDocuments: [{ hash: 'doc-hash', sizeBytes: 1024, mimeType: 'application/pdf', filename: 'invoice.pdf' }],
};
function makeInjector(ingestResult) {
    const ingestProvider = {
        performIngest: vi.fn().mockResolvedValue(ingestResult),
    };
    return {
        get: (token) => {
            if (token === EmailIngestionIngestProvider)
                return ingestProvider;
            throw new Error(`Unexpected provider: ${String(token)}`);
        },
    };
}
// ---------------------------------------------------------------------------
// Mutation.ingestEmail resolver
// ---------------------------------------------------------------------------
describe('Mutation.ingestEmail', () => {
    const resolver = emailIngestionIngestResolver.Mutation.ingestEmail;
    it('returns IngestEmailSuccess with INSERTED outcome on happy path', async () => {
        const injector = makeInjector({
            outcome: IngestOutcome.INSERTED,
            ingestId: 'ingest-uuid-1',
            auditId: 'audit-uuid-1',
        });
        const result = await resolver({}, { input: BASE_INPUT }, { injector }, {});
        expect(result).toMatchObject({
            __typename: 'IngestEmailSuccess',
            outcome: 'INSERTED',
            ingestId: 'ingest-uuid-1',
            auditId: 'audit-uuid-1',
        });
    });
    it('returns IngestEmailSuccess with DUPLICATE outcome when idempotency key was seen', async () => {
        const injector = makeInjector({
            outcome: IngestOutcome.DUPLICATE,
            existingIngestId: 'ingest-uuid-prior',
            auditId: 'audit-uuid-prior',
        });
        const result = await resolver({}, { input: BASE_INPUT }, { injector }, {});
        expect(result).toMatchObject({
            __typename: 'IngestEmailSuccess',
            outcome: 'DUPLICATE',
            existingIngestId: 'ingest-uuid-prior',
        });
    });
    it('returns IngestEmailSuccess with DUPLICATE outcome when dedup fingerprint was seen', async () => {
        const injector = makeInjector({
            outcome: IngestOutcome.DUPLICATE,
            existingIngestId: 'ingest-uuid-dedup',
            auditId: 'audit-uuid-dedup',
        });
        const result = await resolver({}, { input: BASE_INPUT }, { injector }, {});
        expect(result).toMatchObject({
            __typename: 'IngestEmailSuccess',
            outcome: 'DUPLICATE',
            existingIngestId: 'ingest-uuid-dedup',
        });
    });
    it('returns IngestEmailSuccess with QUARANTINED outcome when no documents extracted', async () => {
        const injector = makeInjector({
            outcome: IngestOutcome.QUARANTINED,
            auditId: 'audit-uuid-q',
            reasonCode: IngestReasonCode.NO_DOCUMENTS,
        });
        const result = await resolver({}, { input: { ...BASE_INPUT, extractedDocuments: [] } }, { injector }, {});
        expect(result).toMatchObject({
            __typename: 'IngestEmailSuccess',
            outcome: 'QUARANTINED',
            reasonCode: IngestReasonCode.NO_DOCUMENTS,
        });
    });
    it('returns IngestEmailSuccess with REJECTED outcome when grant is invalid', async () => {
        const injector = makeInjector({
            outcome: IngestOutcome.REJECTED,
            reasonCode: IngestReasonCode.GRANT_INVALID,
        });
        const result = await resolver({}, { input: BASE_INPUT }, { injector }, {});
        expect(result).toMatchObject({
            __typename: 'IngestEmailSuccess',
            outcome: 'REJECTED',
            reasonCode: IngestReasonCode.GRANT_INVALID,
        });
    });
    it('returns IngestEmailSuccess with REJECTED outcome on tenant mismatch', async () => {
        const injector = makeInjector({
            outcome: IngestOutcome.REJECTED,
            reasonCode: IngestReasonCode.TENANT_MISMATCH,
        });
        const result = await resolver({}, { input: BASE_INPUT }, { injector }, {});
        expect(result).toMatchObject({
            __typename: 'IngestEmailSuccess',
            outcome: 'REJECTED',
            reasonCode: IngestReasonCode.TENANT_MISMATCH,
        });
    });
    it('returns CommonError on unexpected provider failure', async () => {
        const ingestProvider = {
            performIngest: vi.fn().mockRejectedValue(new Error('DB connection lost')),
        };
        const injector = {
            get: (token) => {
                if (token === EmailIngestionIngestProvider)
                    return ingestProvider;
                throw new Error(`Unexpected provider: ${String(token)}`);
            },
        };
        const result = await resolver({}, { input: BASE_INPUT }, { injector }, {});
        expect(result).toMatchObject({
            __typename: 'CommonError',
            message: expect.stringContaining('ingest'),
        });
    });
    it('passes all input fields to performIngest', async () => {
        const performIngest = vi.fn().mockResolvedValue({
            outcome: IngestOutcome.INSERTED,
            ingestId: 'x',
            auditId: 'y',
        });
        const injector = {
            get: (token) => {
                if (token === EmailIngestionIngestProvider)
                    return { performIngest };
                throw new Error(`Unexpected provider: ${String(token)}`);
            },
        };
        await resolver({}, { input: BASE_INPUT }, { injector }, {});
        expect(performIngest).toHaveBeenCalledWith(expect.objectContaining({
            grantJti: 'jti-uuid',
            idempotencyKey: 'idem-key-001',
            tenantId: 'tenant-uuid-a',
            messageId: 'msg-abc-123',
            rawMessageHash: 'sha256-abc',
            correlationId: 'corr-001',
        }), 
        // the resolver forwards its operation injector so the provider can run OCR
        injector);
    });
});
//# sourceMappingURL=email-ingestion-ingest.resolver.test.js.map