Files
PiAgentUI/src/components/ExtensionPanel.test.tsx
T
Evandro b3489e1ede
Build & Push Frontend Docker Image / build-and-push (push) Canceled after 0s
Build Validation / validate (push) Canceled after 6s
Build & Push Backend Docker Image / build-and-push (push) Failing after 10m10s
Build & Push Gateway Docker Image / build-and-push (push) Failing after 10m9s
🎉 Initial commit: PiAgentUI — AI Agent Desktop & Web UI
A professional workspace for AI coding agents with:
- Real-time streaming chat with SSE
- Session management (fork, clone, tree navigation)
- MCP tools browser & metadata panel
- Skills browser (global, project, package sources)
- Voice input & STT provider configuration
- Integrated terminal & file explorer
- Model selector with capability metadata
- Keyboard-first UI with command palette
- 8 languages (en, pt-BR, es, ja, zh-CN, ar, bn, hi)
- Tauri 2 desktop app
- React 19 + TypeScript + Vite 8 + Tailwind CSS 4
- Pi Agent extension runtime

Originally forked from OpenCodeUI, now an independent project.
License: GPL-3.0-only
2026-06-01 00:50:06 -03:00

104 lines
4.0 KiB
TypeScript

import { fireEvent, render, screen, waitFor } from '@testing-library/react'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { ExtensionPanel } from './ExtensionPanel'
const getExtensionsMock = vi.fn()
const installExtensionMock = vi.fn()
const removeExtensionPackageMock = vi.fn()
vi.mock('../api/extension', () => ({
getExtensions: (...args: unknown[]) => getExtensionsMock(...args),
installExtension: (...args: unknown[]) => installExtensionMock(...args),
removeExtensionPackage: (...args: unknown[]) => removeExtensionPackageMock(...args),
}))
vi.mock('../hooks', () => ({
useDirectory: () => ({ currentDirectory: '/workspace/demo' }),
}))
vi.mock('../utils', () => ({
apiErrorHandler: vi.fn(),
}))
describe('ExtensionPanel', () => {
beforeEach(() => {
getExtensionsMock.mockReset()
installExtensionMock.mockReset()
removeExtensionPackageMock.mockReset()
vi.spyOn(window, 'confirm').mockReturnValue(true)
getExtensionsMock.mockResolvedValue({
summary: { total: 3, active: 1, inactive: 1, missing: 1, error: 0 },
packages: [
{
source: 'npm:pi-hud',
scope: 'user',
filtered: false,
packageName: 'pi-hud',
version: '0.4.3',
description: 'Persistent HUD extension',
status: 'active',
installedPath: '/home/user/.pi/agent/npm/node_modules/pi-hud',
resources: {
extensions: [{ name: 'index.ts', path: '/pkg/index.ts', enabled: true }],
skills: [{ name: 'release', path: '/pkg/skills/release/SKILL.md', enabled: true }],
prompts: [],
themes: [],
},
},
{
source: 'npm:pi-muted',
scope: 'user',
filtered: true,
packageName: 'pi-muted',
version: '1.0.0',
description: 'Disabled package',
status: 'inactive',
installedPath: '/home/user/.pi/agent/npm/node_modules/pi-muted',
resources: {
extensions: [{ name: 'muted.ts', path: '/pkg/muted.ts', enabled: false }],
skills: [],
prompts: [],
themes: [],
},
},
{
source: 'npm:missing-extension',
scope: 'project',
filtered: false,
status: 'missing',
resources: { extensions: [], skills: [], prompts: [], themes: [] },
},
],
})
installExtensionMock.mockResolvedValue({ source: 'npm:pi-new', scope: 'user', reloadRequired: true })
removeExtensionPackageMock.mockResolvedValue({ source: 'npm:pi-hud', scope: 'user', reloadRequired: true })
})
it('renders installed extension packages, active state, install command, and uninstall action', async () => {
render(<ExtensionPanel />)
await waitFor(() => expect(screen.getByText('pi-hud')).toBeInTheDocument())
expect(screen.getByText('(3)')).toBeInTheDocument()
expect(screen.getAllByText('Active').length).toBeGreaterThan(0)
expect(screen.getAllByText('Inactive').length).toBeGreaterThan(0)
expect(screen.getAllByText('Missing').length).toBeGreaterThan(0)
expect(screen.getByText('Persistent HUD extension')).toBeInTheDocument()
expect(screen.getAllByText('Extensions 1').length).toBeGreaterThan(0)
expect(screen.getByText('Skills 1')).toBeInTheDocument()
expect(screen.getByText('index.ts')).toBeInTheDocument()
const installInput = screen.getByRole('textbox', { name: 'Install command' })
fireEvent.change(installInput, { target: { value: 'pi install npm:pi-new' } })
fireEvent.click(screen.getByRole('button', { name: 'Install extension' }))
await waitFor(() => expect(installExtensionMock).toHaveBeenCalledWith('pi install npm:pi-new', '/workspace/demo'))
expect(await screen.findByText('Reload Pi Agent to apply extension changes.')).toBeInTheDocument()
fireEvent.click(screen.getByRole('button', { name: 'Uninstall pi-hud' }))
await waitFor(() =>
expect(removeExtensionPackageMock).toHaveBeenCalledWith('npm:pi-hud', 'user', '/workspace/demo'),
)
})
})