"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("@testing-library/react");
require("@testing-library/jest-dom");
const ModelRegistry_1 = require("../ModelRegistry");
const BFUIProvider_1 = require("../../../core/BFUIProvider");
const ModelRegistryProvider_1 = require("../ModelRegistryProvider");
// Mock the API service
jest.mock('../../../services/api', () => ({
    modelRegistryApi: {
        getModels: jest.fn(),
        createModel: jest.fn(),
        updateModel: jest.fn(),
        deleteModel: jest.fn(),
        deployModel: jest.fn(),
        getModelVersions: jest.fn(),
        rollbackModel: jest.fn(),
    }
}));
// Mock bfapi endpoints
const mockApi = require('../../../services/api').modelRegistryApi;
const TestWrapper = ({ children }) => ((0, jsx_runtime_1.jsx)(BFUIProvider_1.BFUIProvider, { children: (0, jsx_runtime_1.jsx)(ModelRegistryProvider_1.ModelRegistryProvider, { children: children }) }));
describe('ModelRegistry Component', () => {
    beforeEach(() => {
        jest.clearAllMocks();
    });
    /**
     * TDD Test 1: Component Rendering and Initial State
     */
    describe('Initial Rendering', () => {
        it('should render the model registry with loading state', async () => {
            mockApi.getModels.mockImplementation(() => new Promise(resolve => setTimeout(() => resolve({ models: [] }), 100)));
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            // Should show loading indicator initially
            expect(react_1.screen.getByTestId('model-registry-loading')).toBeInTheDocument();
            expect(react_1.screen.getByText(/Loading models.../i)).toBeInTheDocument();
        });
        it('should render empty state when no models exist', async () => {
            mockApi.getModels.mockResolvedValue({ models: [] });
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByTestId('model-registry-empty')).toBeInTheDocument();
            });
            expect(react_1.screen.getByText(/No models found/i)).toBeInTheDocument();
            expect(react_1.screen.getByText(/Add your first model/i)).toBeInTheDocument();
            expect(react_1.screen.getByRole('button', { name: /Add Model/i })).toBeInTheDocument();
        });
        it('should render model list when models exist', async () => {
            const mockModels = [
                {
                    id: 'llama-2-13b',
                    name: 'LLaMA 2 13B',
                    version: '1.2.0',
                    provider: 'meta',
                    status: 'active',
                    description: 'Meta LLaMA 2 13B parameter model',
                    created_at: '2024-01-15T10:30:00Z',
                    metrics: { accuracy: 0.95, latency: 120 }
                },
                {
                    id: 'mistral-7b',
                    name: 'Mistral 7B',
                    version: '1.0.3',
                    provider: 'mistral',
                    status: 'inactive',
                    description: 'Mistral 7B parameter model',
                    created_at: '2024-01-10T14:20:00Z',
                    metrics: { accuracy: 0.92, latency: 85 }
                }
            ];
            mockApi.getModels.mockResolvedValue({ models: mockModels });
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByTestId('model-registry-list')).toBeInTheDocument();
            });
            // Check if all models are rendered
            expect(react_1.screen.getByText('LLaMA 2 13B')).toBeInTheDocument();
            expect(react_1.screen.getByText('Mistral 7B')).toBeInTheDocument();
            expect(react_1.screen.getByText('v1.2.0')).toBeInTheDocument();
            expect(react_1.screen.getByText('v1.0.3')).toBeInTheDocument();
        });
    });
    /**
     * TDD Test 2: Model Creation Functionality
     */
    describe('Model Creation', () => {
        it('should open create model modal when Add Model button is clicked', async () => {
            mockApi.getModels.mockResolvedValue({ models: [] });
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByRole('button', { name: /Add Model/i })).toBeInTheDocument();
            });
            react_1.fireEvent.click(react_1.screen.getByRole('button', { name: /Add Model/i }));
            expect(react_1.screen.getByTestId('model-create-modal')).toBeInTheDocument();
            expect(react_1.screen.getByRole('heading', { name: /Create New Model/i })).toBeInTheDocument();
        });
        it('should validate required fields in create model form', async () => {
            mockApi.getModels.mockResolvedValue({ models: [] });
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            await (0, react_1.waitFor)(() => {
                react_1.fireEvent.click(react_1.screen.getByRole('button', { name: /Add Model/i }));
            });
            // Try to submit without filling required fields
            react_1.fireEvent.click(react_1.screen.getByRole('button', { name: /Create Model/i }));
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByText(/Model name is required/i)).toBeInTheDocument();
                expect(react_1.screen.getByText(/Provider is required/i)).toBeInTheDocument();
                expect(react_1.screen.getByText(/Version is required/i)).toBeInTheDocument();
            });
        });
        it('should create model successfully with valid data', async () => {
            const newModel = {
                id: 'new-model-123',
                name: 'Test Model',
                version: '1.0.0',
                provider: 'openai',
                description: 'Test model description'
            };
            mockApi.getModels.mockResolvedValue({ models: [] });
            mockApi.createModel.mockResolvedValue({ model: newModel });
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            await (0, react_1.waitFor)(() => {
                react_1.fireEvent.click(react_1.screen.getByRole('button', { name: /Add Model/i }));
            });
            // Fill form fields
            react_1.fireEvent.change(react_1.screen.getByLabelText(/Model Name/i), {
                target: { value: 'Test Model' }
            });
            react_1.fireEvent.change(react_1.screen.getByLabelText(/Provider/i), {
                target: { value: 'openai' }
            });
            react_1.fireEvent.change(react_1.screen.getByLabelText(/Version/i), {
                target: { value: '1.0.0' }
            });
            react_1.fireEvent.change(react_1.screen.getByLabelText(/Description/i), {
                target: { value: 'Test model description' }
            });
            // Submit form
            react_1.fireEvent.click(react_1.screen.getByRole('button', { name: /Create Model/i }));
            await (0, react_1.waitFor)(() => {
                expect(mockApi.createModel).toHaveBeenCalledWith({
                    name: 'Test Model',
                    provider: 'openai',
                    version: '1.0.0',
                    description: 'Test model description'
                });
            });
            // Should show success message
            expect(react_1.screen.getByText(/Model created successfully/i)).toBeInTheDocument();
        });
    });
    /**
     * TDD Test 3: Model Management Operations
     */
    describe('Model Management', () => {
        const mockModel = {
            id: 'test-model',
            name: 'Test Model',
            version: '1.2.0',
            provider: 'openai',
            status: 'active',
            description: 'Test model',
            created_at: '2024-01-15T10:30:00Z',
            metrics: { accuracy: 0.95, latency: 120 }
        };
        beforeEach(() => {
            mockApi.getModels.mockResolvedValue({ models: [mockModel] });
        });
        it('should display model actions menu when clicking actions button', async () => {
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByText('Test Model')).toBeInTheDocument();
            });
            react_1.fireEvent.click(react_1.screen.getByTestId('model-actions-test-model'));
            expect(react_1.screen.getByText(/Edit Model/i)).toBeInTheDocument();
            expect(react_1.screen.getByText(/Deploy Model/i)).toBeInTheDocument();
            expect(react_1.screen.getByText(/View Versions/i)).toBeInTheDocument();
            expect(react_1.screen.getByText(/Delete Model/i)).toBeInTheDocument();
        });
        it('should open edit modal when Edit Model is clicked', async () => {
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            await (0, react_1.waitFor)(() => {
                react_1.fireEvent.click(react_1.screen.getByTestId('model-actions-test-model'));
            });
            react_1.fireEvent.click(react_1.screen.getByText(/Edit Model/i));
            expect(react_1.screen.getByTestId('model-edit-modal')).toBeInTheDocument();
            expect(react_1.screen.getByDisplayValue('Test Model')).toBeInTheDocument();
            expect(react_1.screen.getByDisplayValue('1.2.0')).toBeInTheDocument();
        });
        it('should handle model deployment with environment selection', async () => {
            mockApi.deployModel.mockResolvedValue({
                deployment_id: 'deploy-123',
                status: 'in_progress'
            });
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            await (0, react_1.waitFor)(() => {
                react_1.fireEvent.click(react_1.screen.getByTestId('model-actions-test-model'));
            });
            react_1.fireEvent.click(react_1.screen.getByText(/Deploy Model/i));
            expect(react_1.screen.getByTestId('model-deploy-modal')).toBeInTheDocument();
            // Select environment
            react_1.fireEvent.change(react_1.screen.getByLabelText(/Environment/i), {
                target: { value: 'production' }
            });
            react_1.fireEvent.click(react_1.screen.getByRole('button', { name: /Deploy/i }));
            await (0, react_1.waitFor)(() => {
                expect(mockApi.deployModel).toHaveBeenCalledWith('test-model', {
                    environment: 'production',
                    strategy: 'blue_green'
                });
            });
        });
    });
    /**
     * TDD Test 4: Model Versioning and History
     */
    describe('Model Versioning', () => {
        it('should display model version history', async () => {
            const mockVersions = [
                { version: '1.2.0', status: 'active', created_at: '2024-01-15T10:30:00Z' },
                { version: '1.1.0', status: 'inactive', created_at: '2024-01-10T14:20:00Z' },
                { version: '1.0.0', status: 'archived', created_at: '2024-01-05T09:15:00Z' }
            ];
            mockApi.getModels.mockResolvedValue({
                models: [{
                        id: 'test-model',
                        name: 'Test Model',
                        version: '1.2.0',
                        provider: 'openai',
                        status: 'active'
                    }]
            });
            mockApi.getModelVersions.mockResolvedValue({ versions: mockVersions });
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            await (0, react_1.waitFor)(() => {
                react_1.fireEvent.click(react_1.screen.getByTestId('model-actions-test-model'));
            });
            react_1.fireEvent.click(react_1.screen.getByText(/View Versions/i));
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByTestId('model-versions-modal')).toBeInTheDocument();
            });
            // Check version list
            expect(react_1.screen.getByText('v1.2.0')).toBeInTheDocument();
            expect(react_1.screen.getByText('v1.1.0')).toBeInTheDocument();
            expect(react_1.screen.getByText('v1.0.0')).toBeInTheDocument();
        });
        it('should handle model rollback functionality', async () => {
            mockApi.rollbackModel.mockResolvedValue({
                rollback_id: 'rollback-456',
                status: 'in_progress'
            });
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            await (0, react_1.waitFor)(() => {
                react_1.fireEvent.click(react_1.screen.getByTestId('model-actions-test-model'));
            });
            react_1.fireEvent.click(react_1.screen.getByText(/View Versions/i));
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByTestId('model-versions-modal')).toBeInTheDocument();
            });
            // Click rollback on version 1.1.0
            react_1.fireEvent.click(react_1.screen.getByTestId('rollback-button-1.1.0'));
            // Confirm rollback
            react_1.fireEvent.click(react_1.screen.getByRole('button', { name: /Confirm Rollback/i }));
            await (0, react_1.waitFor)(() => {
                expect(mockApi.rollbackModel).toHaveBeenCalledWith('test-model', '1.1.0');
            });
        });
    });
    /**
     * TDD Test 5: Error Handling
     */
    describe('Error Handling', () => {
        it('should display error message when API request fails', async () => {
            mockApi.getModels.mockRejectedValue(new Error('Network error'));
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByTestId('model-registry-error')).toBeInTheDocument();
            });
            expect(react_1.screen.getByText(/Failed to load models/i)).toBeInTheDocument();
            expect(react_1.screen.getByText(/Network error/i)).toBeInTheDocument();
            expect(react_1.screen.getByRole('button', { name: /Retry/i })).toBeInTheDocument();
        });
        it('should handle create model API error', async () => {
            mockApi.getModels.mockResolvedValue({ models: [] });
            mockApi.createModel.mockRejectedValue(new Error('Validation failed'));
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            await (0, react_1.waitFor)(() => {
                react_1.fireEvent.click(react_1.screen.getByRole('button', { name: /Add Model/i }));
            });
            // Fill and submit form
            react_1.fireEvent.change(react_1.screen.getByLabelText(/Model Name/i), {
                target: { value: 'Test Model' }
            });
            react_1.fireEvent.click(react_1.screen.getByRole('button', { name: /Create Model/i }));
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByText(/Failed to create model/i)).toBeInTheDocument();
                expect(react_1.screen.getByText(/Validation failed/i)).toBeInTheDocument();
            });
        });
        it('should retry failed requests when retry button is clicked', async () => {
            mockApi.getModels
                .mockRejectedValueOnce(new Error('Network error'))
                .mockResolvedValueOnce({ models: [] });
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByTestId('model-registry-error')).toBeInTheDocument();
            });
            react_1.fireEvent.click(react_1.screen.getByRole('button', { name: /Retry/i }));
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByTestId('model-registry-empty')).toBeInTheDocument();
            });
            expect(mockApi.getModels).toHaveBeenCalledTimes(2);
        });
    });
    /**
     * TDD Test 6: Search and Filtering
     */
    describe('Search and Filtering', () => {
        const mockModels = [
            {
                id: 'llama-2-13b',
                name: 'LLaMA 2 13B',
                version: '1.2.0',
                provider: 'meta',
                status: 'active'
            },
            {
                id: 'mistral-7b',
                name: 'Mistral 7B',
                version: '1.0.3',
                provider: 'mistral',
                status: 'inactive'
            },
            {
                id: 'gpt-4',
                name: 'GPT-4',
                version: '1.1.0',
                provider: 'openai',
                status: 'active'
            }
        ];
        beforeEach(() => {
            mockApi.getModels.mockResolvedValue({ models: mockModels });
        });
        it('should filter models by search term', async () => {
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByText('LLaMA 2 13B')).toBeInTheDocument();
            });
            // Search for "mistral"
            react_1.fireEvent.change(react_1.screen.getByPlaceholderText(/Search models.../i), {
                target: { value: 'mistral' }
            });
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByText('Mistral 7B')).toBeInTheDocument();
                expect(react_1.screen.queryByText('LLaMA 2 13B')).not.toBeInTheDocument();
                expect(react_1.screen.queryByText('GPT-4')).not.toBeInTheDocument();
            });
        });
        it('should filter models by status', async () => {
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByText('LLaMA 2 13B')).toBeInTheDocument();
            });
            // Filter by active status
            react_1.fireEvent.change(react_1.screen.getByLabelText(/Filter by status/i), {
                target: { value: 'active' }
            });
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByText('LLaMA 2 13B')).toBeInTheDocument();
                expect(react_1.screen.getByText('GPT-4')).toBeInTheDocument();
                expect(react_1.screen.queryByText('Mistral 7B')).not.toBeInTheDocument();
            });
        });
        it('should filter models by provider', async () => {
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByText('LLaMA 2 13B')).toBeInTheDocument();
            });
            // Filter by OpenAI provider
            react_1.fireEvent.change(react_1.screen.getByLabelText(/Filter by provider/i), {
                target: { value: 'openai' }
            });
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByText('GPT-4')).toBeInTheDocument();
                expect(react_1.screen.queryByText('LLaMA 2 13B')).not.toBeInTheDocument();
                expect(react_1.screen.queryByText('Mistral 7B')).not.toBeInTheDocument();
            });
        });
    });
    /**
     * TDD Test 7: Model Metrics and Performance
     */
    describe('Model Metrics', () => {
        it('should display model performance metrics', async () => {
            const mockModelWithMetrics = {
                id: 'test-model',
                name: 'Test Model',
                version: '1.2.0',
                provider: 'openai',
                status: 'active',
                metrics: {
                    accuracy: 0.95,
                    latency: 120,
                    throughput: 50,
                    error_rate: 0.02,
                    uptime: 99.9
                }
            };
            mockApi.getModels.mockResolvedValue({ models: [mockModelWithMetrics] });
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByText('Test Model')).toBeInTheDocument();
            });
            // Check metrics display
            expect(react_1.screen.getByText('95%')).toBeInTheDocument(); // Accuracy
            expect(react_1.screen.getByText('120ms')).toBeInTheDocument(); // Latency
            expect(react_1.screen.getByText('50 req/s')).toBeInTheDocument(); // Throughput
            expect(react_1.screen.getByText('99.9%')).toBeInTheDocument(); // Uptime
        });
        it('should handle missing metrics gracefully', async () => {
            const mockModelWithoutMetrics = {
                id: 'test-model',
                name: 'Test Model',
                version: '1.2.0',
                provider: 'openai',
                status: 'active'
                // No metrics property
            };
            mockApi.getModels.mockResolvedValue({ models: [mockModelWithoutMetrics] });
            (0, react_1.render)((0, jsx_runtime_1.jsx)(ModelRegistry_1.ModelRegistry, {}), { wrapper: TestWrapper });
            await (0, react_1.waitFor)(() => {
                expect(react_1.screen.getByText('Test Model')).toBeInTheDocument();
            });
            // Should show placeholder for missing metrics
            expect(react_1.screen.getByText(/No metrics available/i)).toBeInTheDocument();
        });
    });
});
//# sourceMappingURL=ModelRegistry.test.js.map