mirror of
https://github.com/nexu-io/open-design.git
synced 2026-06-01 03:14:35 +07:00
- Introduced a new plugin upload mechanism with file size limits and memory storage, allowing users to upload plugins directly. - Implemented fallback logic for plugin application, ensuring projects can be created without explicit plugin requests. - Enhanced the UI to support plugin selection and integration, including a new `PluginsView` component for managing plugins. - Updated various components to utilize localized text for plugin queries, improving user experience across different languages. - Added tests for new plugin functionalities and local skill loading, ensuring reliability and correctness. This update significantly improves the plugin management experience, providing users with better tools for plugin integration and interaction.
113 lines
3.3 KiB
TypeScript
113 lines
3.3 KiB
TypeScript
// @vitest-environment jsdom
|
|
|
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react';
|
|
import { HomeView } from '../../src/components/HomeView';
|
|
import { I18nProvider } from '../../src/i18n';
|
|
|
|
const PLUGIN_ROW = {
|
|
id: 'localized-plugin',
|
|
title: 'Localized Plugin',
|
|
version: '1.0.0',
|
|
trust: 'trusted' as const,
|
|
sourceKind: 'bundled' as const,
|
|
source: '/tmp/localized',
|
|
capabilitiesGranted: ['prompt:inject'],
|
|
fsPath: '/tmp/localized',
|
|
installedAt: 0,
|
|
updatedAt: 0,
|
|
manifest: {
|
|
name: 'localized-plugin',
|
|
title: 'Localized Plugin',
|
|
version: '1.0.0',
|
|
description: 'A localized fixture',
|
|
od: {
|
|
kind: 'scenario',
|
|
taskKind: 'new-generation',
|
|
useCase: {
|
|
query: {
|
|
en: 'Make a {{topic}} brief.',
|
|
'zh-CN': '生成一份关于 {{topic}} 的简报。',
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
const APPLY_RESULT = {
|
|
ok: true,
|
|
query: '生成一份关于 {{topic}} 的简报。',
|
|
contextItems: [],
|
|
inputs: [{ name: 'topic', type: 'string', default: '设计系统' }],
|
|
assets: [],
|
|
mcpServers: [],
|
|
trust: 'trusted',
|
|
capabilitiesGranted: ['prompt:inject'],
|
|
capabilitiesRequired: ['prompt:inject'],
|
|
appliedPlugin: {
|
|
snapshotId: 'snap-1',
|
|
pluginId: 'localized-plugin',
|
|
pluginVersion: '1.0.0',
|
|
manifestSourceDigest: 'a'.repeat(64),
|
|
inputs: {},
|
|
resolvedContext: { items: [] },
|
|
capabilitiesGranted: ['prompt:inject'],
|
|
capabilitiesRequired: ['prompt:inject'],
|
|
assetsStaged: [],
|
|
taskKind: 'new-generation',
|
|
appliedAt: 0,
|
|
connectorsRequired: [],
|
|
connectorsResolved: [],
|
|
mcpServers: [],
|
|
status: 'fresh',
|
|
},
|
|
projectMetadata: {},
|
|
};
|
|
|
|
describe('HomeView plugin i18n', () => {
|
|
afterEach(() => {
|
|
vi.unstubAllGlobals();
|
|
cleanup();
|
|
});
|
|
|
|
it('hydrates the Home prompt with the localized apply query', async () => {
|
|
const fetchMock = vi.fn(async (url) => {
|
|
if (typeof url === 'string' && url === '/api/plugins') {
|
|
return new Response(JSON.stringify({ plugins: [PLUGIN_ROW] }), {
|
|
status: 200,
|
|
headers: { 'content-type': 'application/json' },
|
|
});
|
|
}
|
|
if (typeof url === 'string' && url.includes('/apply')) {
|
|
return new Response(JSON.stringify(APPLY_RESULT), {
|
|
status: 200,
|
|
headers: { 'content-type': 'application/json' },
|
|
});
|
|
}
|
|
throw new Error(`unexpected fetch ${url}`);
|
|
});
|
|
vi.stubGlobal('fetch', fetchMock);
|
|
|
|
render(
|
|
<I18nProvider initial="zh-CN">
|
|
<HomeView
|
|
projects={[]}
|
|
onSubmit={() => undefined}
|
|
onOpenProject={() => undefined}
|
|
onViewAllProjects={() => undefined}
|
|
/>
|
|
</I18nProvider>,
|
|
);
|
|
|
|
fireEvent.click(await waitFor(() => screen.getByTestId('plugins-home-use-localized-plugin')));
|
|
|
|
const input = await screen.findByTestId('home-hero-input');
|
|
await waitFor(() => {
|
|
expect((input as HTMLTextAreaElement).value).toBe('生成一份关于 设计系统 的简报。');
|
|
});
|
|
const [, init] = fetchMock.mock.calls.find(([url]) => (
|
|
typeof url === 'string' && url.includes('/apply')
|
|
))!;
|
|
expect(JSON.parse(String(init?.body))).toMatchObject({ locale: 'zh-CN' });
|
|
});
|
|
});
|