"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const cache_1 = require("../../../src/cache");
const constants_1 = require("../../../src/constants");
const logger_1 = __importDefault(require("../../../src/logger"));
const constants_2 = require("../../../src/redteam/constants");
const plugins_1 = require("../../../src/redteam/plugins");
const remoteGeneration_1 = require("../../../src/redteam/remoteGeneration");
jest.mock('../../../src/cache');
jest.mock('../../../src/logger');
jest.mock('../../../src/redteam/remoteGeneration', () => ({
    shouldGenerateRemote: jest.fn().mockReturnValue(false),
    neverGenerateRemote: jest.fn().mockReturnValue(false),
    getRemoteGenerationUrl: jest.fn().mockReturnValue('http://test-url'),
}));
jest.mock('../../../src/cliState', () => ({
    __esModule: true,
    default: { remote: false },
}));
describe('Plugins', () => {
    let mockProvider;
    beforeEach(() => {
        mockProvider = {
            callApi: jest.fn(),
            id: jest.fn().mockReturnValue('test-provider'),
        };
        // Reset all mocks
        jest.clearAllMocks();
        jest.mocked(cache_1.fetchWithCache).mockReset();
    });
    describe('plugin registration', () => {
        it('should register all base plugins', () => {
            const basePluginKeys = [
                'contracts',
                'cross-session-leak',
                'debug-access',
                'excessive-agency',
                'hallucination',
                'imitation',
                'intent',
                'overreliance',
                'politics',
                'policy',
                'prompt-extraction',
                'rbac',
                'shell-injection',
                'sql-injection',
            ];
            basePluginKeys.forEach((key) => {
                const plugin = plugins_1.Plugins.find((p) => p.key === key);
                expect(plugin).toBeDefined();
            });
        });
        it('should register all aligned harm plugins', () => {
            Object.keys(constants_2.REDTEAM_PROVIDER_HARM_PLUGINS).forEach((key) => {
                const plugin = plugins_1.Plugins.find((p) => p.key === key);
                expect(plugin).toBeDefined();
            });
        });
        it('should register all unaligned harm plugins', () => {
            Object.keys(constants_2.UNALIGNED_PROVIDER_HARM_PLUGINS).forEach((key) => {
                const plugin = plugins_1.Plugins.find((p) => p.key === key);
                expect(plugin).toBeDefined();
            });
        });
        it('should register all PII plugins', () => {
            constants_2.PII_PLUGINS.forEach((key) => {
                const plugin = plugins_1.Plugins.find((p) => p.key === key);
                expect(plugin).toBeDefined();
            });
        });
        it('should register all remote plugins', () => {
            const remotePluginKeys = [
                'ascii-smuggling',
                'bfla',
                'bola',
                'competitors',
                'hijacking',
                'religion',
                'ssrf',
                'indirect-prompt-injection',
            ];
            remotePluginKeys.forEach((key) => {
                const plugin = plugins_1.Plugins.find((p) => p.key === key);
                expect(plugin).toBeDefined();
            });
        });
    });
    describe('plugin validation', () => {
        it('should validate intent plugin config', async () => {
            const intentPlugin = plugins_1.Plugins.find((p) => p.key === 'intent');
            expect(() => intentPlugin?.validate?.({})).toThrow('Intent plugin requires `config.intent` to be set');
        });
        it('should validate policy plugin config', async () => {
            const policyPlugin = plugins_1.Plugins.find((p) => p.key === 'policy');
            expect(() => policyPlugin?.validate?.({})).toThrow('Policy plugin requires `config.policy` to be set');
        });
        it('should validate prompt extraction plugin config', async () => {
            const promptExtractionPlugin = plugins_1.Plugins.find((p) => p.key === 'prompt-extraction');
            expect(() => promptExtractionPlugin?.validate?.({})).toThrow('Prompt extraction plugin requires `config.systemPrompt` to be set');
        });
        it('should validate indirect prompt injection plugin config', async () => {
            const indirectPlugin = plugins_1.Plugins.find((p) => p.key === 'indirect-prompt-injection');
            expect(() => indirectPlugin?.validate?.({})).toThrow('Indirect prompt injection plugin requires `config.indirectInjectionVar` to be set');
        });
    });
    describe('remote generation', () => {
        it('should call remote generation with correct parameters', async () => {
            jest.mocked(remoteGeneration_1.shouldGenerateRemote).mockReturnValue(true);
            jest.mocked(remoteGeneration_1.neverGenerateRemote).mockReturnValue(false);
            const mockResponse = {
                data: { result: [{ test: 'case' }] },
                cached: false,
                status: 200,
                statusText: 'OK',
            };
            jest.mocked(cache_1.fetchWithCache).mockResolvedValue(mockResponse);
            const plugin = plugins_1.Plugins.find((p) => p.key === 'contracts');
            const result = await plugin?.action({
                provider: mockProvider,
                purpose: 'test',
                injectVar: 'testVar',
                n: 1,
                config: {},
                delayMs: 0,
            });
            expect(cache_1.fetchWithCache).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    config: {},
                    injectVar: 'testVar',
                    n: 1,
                    purpose: 'test',
                    task: 'contracts',
                    version: constants_1.VERSION,
                    email: null,
                }),
            }), expect.any(Number));
            expect(result).toEqual([{ test: 'case' }]);
        });
        it('should handle remote generation errors', async () => {
            jest.mocked(cache_1.fetchWithCache).mockRejectedValue(new Error('Network error'));
            const plugin = plugins_1.Plugins.find((p) => p.key === 'contracts');
            const result = await plugin?.action({
                provider: mockProvider,
                purpose: 'test',
                injectVar: 'testVar',
                n: 1,
                delayMs: 0,
            });
            expect(logger_1.default.error).toHaveBeenCalledWith(expect.stringContaining('Network error'));
            expect(result).toEqual([]);
        });
        it('should add harmful assertions for harmful remote plugins', async () => {
            jest.mocked(remoteGeneration_1.shouldGenerateRemote).mockReturnValue(true);
            jest.mocked(remoteGeneration_1.neverGenerateRemote).mockReturnValue(false);
            const mockResponse = {
                data: {
                    result: [
                        {
                            vars: { testVar: 'test content' },
                            metadata: { harmCategory: 'Misinformation/Disinformation' },
                        },
                    ],
                },
                cached: false,
                status: 200,
                statusText: 'OK',
            };
            jest.mocked(cache_1.fetchWithCache).mockResolvedValue(mockResponse);
            const plugin = plugins_1.Plugins.find((p) => p.key === 'harmful:misinformation-disinformation');
            const result = await plugin?.action({
                provider: mockProvider,
                purpose: 'test',
                injectVar: 'testVar',
                n: 1,
                config: {},
                delayMs: 0,
            });
            expect(result).toHaveLength(1);
            expect(result[0].assert).toBeDefined();
            expect(result[0].assert).toEqual([
                { metric: 'Harmful', type: 'promptfoo:redteam:harmful' },
                expect.objectContaining({ metric: 'Harmful', type: 'moderation' }),
            ]);
        });
        it('should not modify assertions for non-harmful remote plugins', async () => {
            jest.mocked(remoteGeneration_1.shouldGenerateRemote).mockReturnValue(true);
            jest.mocked(remoteGeneration_1.neverGenerateRemote).mockReturnValue(false);
            const originalTestCase = {
                vars: { testVar: 'test content' },
                assert: [{ metric: 'Original', type: 'test' }],
            };
            const mockResponse = {
                data: { result: [originalTestCase] },
                cached: false,
                status: 200,
                statusText: 'OK',
            };
            jest.mocked(cache_1.fetchWithCache).mockResolvedValue(mockResponse);
            const plugin = plugins_1.Plugins.find((p) => p.key === 'ssrf');
            const result = await plugin?.action({
                provider: mockProvider,
                purpose: 'test',
                injectVar: 'testVar',
                n: 1,
                config: {},
                delayMs: 0,
            });
            expect(result).toHaveLength(1);
            expect(result[0]).toEqual(originalTestCase);
        });
    });
    describe('unaligned harm plugins', () => {
        it('should require remote generation', async () => {
            jest.mocked(remoteGeneration_1.shouldGenerateRemote).mockReturnValue(false);
            jest.mocked(remoteGeneration_1.neverGenerateRemote).mockReturnValue(true);
            const unalignedPlugin = plugins_1.Plugins.find((p) => p.key === Object.keys(constants_2.UNALIGNED_PROVIDER_HARM_PLUGINS)[0]);
            await expect(unalignedPlugin?.action({
                provider: mockProvider,
                purpose: 'test',
                injectVar: 'testVar',
                n: 1,
                delayMs: 0,
            })).rejects.toThrow('requires remote generation to be enabled');
        });
    });
});
//# sourceMappingURL=index.test.js.map