import type { PluginDeclaration } from '../../types' import { fireEvent, render, screen } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' import { InstallStep, PluginCategoryEnum } from '../../types' import ReadyToInstall from './ready-to-install' // Factory function for test data const createMockManifest = (overrides: Partial = {}): PluginDeclaration => ({ plugin_unique_identifier: 'test-plugin-uid', version: '1.0.0', author: 'test-author', icon: 'test-icon.png', name: 'Test Plugin', category: PluginCategoryEnum.tool, label: { 'en-US': 'Test Plugin' } as PluginDeclaration['label'], description: { 'en-US': 'A test plugin' } as PluginDeclaration['description'], created_at: '2024-01-01T00:00:00Z', resource: {}, plugins: [], verified: true, endpoint: { settings: [], endpoints: [] }, model: null, tags: [], agent_strategy: null, meta: { version: '1.0.0' }, trigger: {} as PluginDeclaration['trigger'], ...overrides, }) // Mock external dependencies const mockRefreshPluginList = vi.fn() vi.mock('../hooks/use-refresh-plugin-list', () => ({ default: () => ({ refreshPluginList: mockRefreshPluginList, }), })) // Mock Install component let _installOnInstalled: ((notRefresh?: boolean) => void) | null = null let _installOnFailed: ((message?: string) => void) | null = null let _installOnCancel: (() => void) | null = null let _installOnStartToInstall: (() => void) | null = null vi.mock('./steps/install', () => ({ default: ({ uniqueIdentifier, payload, onCancel, onStartToInstall, onInstalled, onFailed, }: { uniqueIdentifier: string payload: PluginDeclaration onCancel: () => void onStartToInstall?: () => void onInstalled: (notRefresh?: boolean) => void onFailed: (message?: string) => void }) => { _installOnInstalled = onInstalled _installOnFailed = onFailed _installOnCancel = onCancel _installOnStartToInstall = onStartToInstall ?? null return (
{uniqueIdentifier} {payload.name}
) }, })) // Mock Installed component vi.mock('../base/installed', () => ({ default: ({ payload, isFailed, errMsg, onCancel, }: { payload: PluginDeclaration | null isFailed: boolean errMsg: string | null onCancel: () => void }) => (
{payload?.name || 'null'} {isFailed ? 'true' : 'false'} {errMsg || 'null'}
), })) describe('ReadyToInstall', () => { const defaultProps = { step: InstallStep.readyToInstall, onStepChange: vi.fn(), onStartToInstall: vi.fn(), setIsInstalling: vi.fn(), onClose: vi.fn(), uniqueIdentifier: 'test-unique-identifier', manifest: createMockManifest(), errorMsg: null as string | null, onError: vi.fn(), } beforeEach(() => { vi.clearAllMocks() _installOnInstalled = null _installOnFailed = null _installOnCancel = null _installOnStartToInstall = null }) // ================================ // Rendering Tests // ================================ describe('Rendering', () => { it('should render Install component when step is readyToInstall', () => { render() expect(screen.getByTestId('install-step')).toBeInTheDocument() expect(screen.queryByTestId('installed-step')).not.toBeInTheDocument() }) it('should render Installed component when step is uploadFailed', () => { render() expect(screen.queryByTestId('install-step')).not.toBeInTheDocument() expect(screen.getByTestId('installed-step')).toBeInTheDocument() }) it('should render Installed component when step is installed', () => { render() expect(screen.queryByTestId('install-step')).not.toBeInTheDocument() expect(screen.getByTestId('installed-step')).toBeInTheDocument() }) it('should render Installed component when step is installFailed', () => { render() expect(screen.queryByTestId('install-step')).not.toBeInTheDocument() expect(screen.getByTestId('installed-step')).toBeInTheDocument() }) }) // ================================ // Props Passing Tests // ================================ describe('Props Passing', () => { it('should pass uniqueIdentifier to Install component', () => { render() expect(screen.getByTestId('install-uid')).toHaveTextContent('custom-uid') }) it('should pass manifest to Install component', () => { const manifest = createMockManifest({ name: 'Custom Plugin' }) render() expect(screen.getByTestId('install-payload-name')).toHaveTextContent('Custom Plugin') }) it('should pass manifest to Installed component', () => { const manifest = createMockManifest({ name: 'Installed Plugin' }) render() expect(screen.getByTestId('installed-payload-name')).toHaveTextContent('Installed Plugin') }) it('should pass errorMsg to Installed component', () => { render( , ) expect(screen.getByTestId('installed-err-msg')).toHaveTextContent('Some error') }) it('should pass isFailed=true for uploadFailed step', () => { render() expect(screen.getByTestId('installed-is-failed')).toHaveTextContent('true') }) it('should pass isFailed=true for installFailed step', () => { render() expect(screen.getByTestId('installed-is-failed')).toHaveTextContent('true') }) it('should pass isFailed=false for installed step', () => { render() expect(screen.getByTestId('installed-is-failed')).toHaveTextContent('false') }) }) // ================================ // handleInstalled Callback Tests // ================================ describe('handleInstalled Callback', () => { it('should call onStepChange with installed when handleInstalled is triggered', () => { const onStepChange = vi.fn() render() fireEvent.click(screen.getByTestId('install-installed-btn')) expect(onStepChange).toHaveBeenCalledWith(InstallStep.installed) }) it('should call refreshPluginList when handleInstalled is triggered without notRefresh', () => { const manifest = createMockManifest() render() fireEvent.click(screen.getByTestId('install-installed-btn')) expect(mockRefreshPluginList).toHaveBeenCalledWith(manifest) }) it('should not call refreshPluginList when handleInstalled is triggered with notRefresh=true', () => { render() fireEvent.click(screen.getByTestId('install-installed-no-refresh-btn')) expect(mockRefreshPluginList).not.toHaveBeenCalled() }) it('should call setIsInstalling(false) when handleInstalled is triggered', () => { const setIsInstalling = vi.fn() render() fireEvent.click(screen.getByTestId('install-installed-btn')) expect(setIsInstalling).toHaveBeenCalledWith(false) }) }) // ================================ // handleFailed Callback Tests // ================================ describe('handleFailed Callback', () => { it('should call onStepChange with installFailed when handleFailed is triggered', () => { const onStepChange = vi.fn() render() fireEvent.click(screen.getByTestId('install-failed-btn')) expect(onStepChange).toHaveBeenCalledWith(InstallStep.installFailed) }) it('should call setIsInstalling(false) when handleFailed is triggered', () => { const setIsInstalling = vi.fn() render() fireEvent.click(screen.getByTestId('install-failed-btn')) expect(setIsInstalling).toHaveBeenCalledWith(false) }) it('should call onError when handleFailed is triggered with error message', () => { const onError = vi.fn() render() fireEvent.click(screen.getByTestId('install-failed-msg-btn')) expect(onError).toHaveBeenCalledWith('Error message') }) it('should not call onError when handleFailed is triggered without error message', () => { const onError = vi.fn() render() fireEvent.click(screen.getByTestId('install-failed-btn')) expect(onError).not.toHaveBeenCalled() }) }) // ================================ // onClose Callback Tests // ================================ describe('onClose Callback', () => { it('should call onClose when cancel is clicked in Install component', () => { const onClose = vi.fn() render() fireEvent.click(screen.getByTestId('install-cancel-btn')) expect(onClose).toHaveBeenCalledTimes(1) }) it('should call onClose when cancel is clicked in Installed component', () => { const onClose = vi.fn() render() fireEvent.click(screen.getByTestId('installed-cancel-btn')) expect(onClose).toHaveBeenCalledTimes(1) }) }) // ================================ // onStartToInstall Callback Tests // ================================ describe('onStartToInstall Callback', () => { it('should pass onStartToInstall to Install component', () => { const onStartToInstall = vi.fn() render() fireEvent.click(screen.getByTestId('install-start-btn')) expect(onStartToInstall).toHaveBeenCalledTimes(1) }) }) // ================================ // Step Transitions Tests // ================================ describe('Step Transitions', () => { it('should handle transition from readyToInstall to installed', () => { const onStepChange = vi.fn() const { rerender } = render( , ) // Initially shows Install component expect(screen.getByTestId('install-step')).toBeInTheDocument() // Simulate successful installation fireEvent.click(screen.getByTestId('install-installed-btn')) expect(onStepChange).toHaveBeenCalledWith(InstallStep.installed) // Rerender with new step rerender() // Now shows Installed component expect(screen.getByTestId('installed-step')).toBeInTheDocument() }) it('should handle transition from readyToInstall to installFailed', () => { const onStepChange = vi.fn() const { rerender } = render( , ) // Initially shows Install component expect(screen.getByTestId('install-step')).toBeInTheDocument() // Simulate failed installation fireEvent.click(screen.getByTestId('install-failed-btn')) expect(onStepChange).toHaveBeenCalledWith(InstallStep.installFailed) // Rerender with new step rerender() // Now shows Installed component with failed state expect(screen.getByTestId('installed-step')).toBeInTheDocument() expect(screen.getByTestId('installed-is-failed')).toHaveTextContent('true') }) }) // ================================ // Edge Cases Tests // ================================ describe('Edge Cases', () => { it('should handle null manifest', () => { render() expect(screen.getByTestId('installed-payload-name')).toHaveTextContent('null') }) it('should handle null errorMsg', () => { render() expect(screen.getByTestId('installed-err-msg')).toHaveTextContent('null') }) it('should handle empty string errorMsg', () => { render() expect(screen.getByTestId('installed-err-msg')).toHaveTextContent('null') }) }) // ================================ // Callback Stability Tests // ================================ describe('Callback Stability', () => { it('should maintain stable handleInstalled callback across re-renders', () => { const onStepChange = vi.fn() const setIsInstalling = vi.fn() const { rerender } = render( , ) // Rerender with same props rerender( , ) // Callback should still work fireEvent.click(screen.getByTestId('install-installed-btn')) expect(onStepChange).toHaveBeenCalledWith(InstallStep.installed) expect(setIsInstalling).toHaveBeenCalledWith(false) }) it('should maintain stable handleFailed callback across re-renders', () => { const onStepChange = vi.fn() const setIsInstalling = vi.fn() const onError = vi.fn() const { rerender } = render( , ) // Rerender with same props rerender( , ) // Callback should still work fireEvent.click(screen.getByTestId('install-failed-msg-btn')) expect(onStepChange).toHaveBeenCalledWith(InstallStep.installFailed) expect(setIsInstalling).toHaveBeenCalledWith(false) expect(onError).toHaveBeenCalledWith('Error message') }) }) })