Refine desktop setup and remove bundled app center apps
This commit is contained in:
211
tests/unit/agent-system-documents-settings.test.tsx
Normal file
211
tests/unit/agent-system-documents-settings.test.tsx
Normal file
@@ -0,0 +1,211 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
||||
import { AgentSystemDocumentsSettings } from '@/components/settings/AgentSystemDocumentsSettings';
|
||||
import i18n from '@/i18n';
|
||||
|
||||
const hostApiFetchMock = vi.fn();
|
||||
const toastSuccessMock = vi.fn();
|
||||
const toastErrorMock = vi.fn();
|
||||
|
||||
vi.mock('@/lib/host-api', () => ({
|
||||
hostApiFetch: (...args: unknown[]) => hostApiFetchMock(...args),
|
||||
}));
|
||||
|
||||
vi.mock('sonner', () => ({
|
||||
toast: {
|
||||
success: (...args: unknown[]) => toastSuccessMock(...args),
|
||||
error: (...args: unknown[]) => toastErrorMock(...args),
|
||||
},
|
||||
}));
|
||||
|
||||
type TestDocumentKind = 'soul' | 'identity' | 'user' | 'agent' | 'tool' | 'heartbeat' | 'boot';
|
||||
|
||||
function makeSnapshot(agentId = 'main', overrides?: Partial<Record<TestDocumentKind, string>>) {
|
||||
const documents = [
|
||||
{
|
||||
kind: 'soul',
|
||||
fileName: 'SOUL.md',
|
||||
path: `/tmp/${agentId}/SOUL.md`,
|
||||
exists: true,
|
||||
source: 'workspace',
|
||||
content: overrides?.soul ?? '# Soul\n',
|
||||
size: 7,
|
||||
updatedAt: 1,
|
||||
templateAvailable: true,
|
||||
templatePath: '/runtime/SOUL.md',
|
||||
},
|
||||
{
|
||||
kind: 'identity',
|
||||
fileName: 'IDENTITY.md',
|
||||
path: `/tmp/${agentId}/IDENTITY.md`,
|
||||
exists: true,
|
||||
source: 'workspace',
|
||||
content: overrides?.identity ?? '# Identity\n',
|
||||
size: 11,
|
||||
updatedAt: 1,
|
||||
templateAvailable: true,
|
||||
templatePath: '/runtime/IDENTITY.md',
|
||||
},
|
||||
{
|
||||
kind: 'user',
|
||||
fileName: 'USER.md',
|
||||
path: `/tmp/${agentId}/USER.md`,
|
||||
exists: true,
|
||||
source: 'workspace',
|
||||
content: overrides?.user ?? '# User\n',
|
||||
size: 7,
|
||||
updatedAt: 1,
|
||||
templateAvailable: true,
|
||||
templatePath: '/runtime/USER.md',
|
||||
},
|
||||
{
|
||||
kind: 'agent',
|
||||
fileName: 'AGENTS.md',
|
||||
path: `/tmp/${agentId}/AGENTS.md`,
|
||||
exists: true,
|
||||
source: 'workspace',
|
||||
content: overrides?.agent ?? '# Agent\n',
|
||||
size: 8,
|
||||
updatedAt: 1,
|
||||
templateAvailable: true,
|
||||
templatePath: '/runtime/AGENTS.md',
|
||||
},
|
||||
{
|
||||
kind: 'tool',
|
||||
fileName: 'TOOLS.md',
|
||||
path: `/tmp/${agentId}/TOOLS.md`,
|
||||
exists: false,
|
||||
source: 'template',
|
||||
content: overrides?.tool ?? '# Tool\n',
|
||||
size: 0,
|
||||
updatedAt: null,
|
||||
templateAvailable: true,
|
||||
templatePath: '/runtime/TOOLS.md',
|
||||
},
|
||||
{
|
||||
kind: 'heartbeat',
|
||||
fileName: 'HEARTBEAT.md',
|
||||
path: `/tmp/${agentId}/HEARTBEAT.md`,
|
||||
exists: false,
|
||||
source: 'template',
|
||||
content: overrides?.heartbeat ?? '# Heartbeat\n',
|
||||
size: 0,
|
||||
updatedAt: null,
|
||||
templateAvailable: true,
|
||||
templatePath: '/runtime/HEARTBEAT.md',
|
||||
},
|
||||
{
|
||||
kind: 'boot',
|
||||
fileName: 'BOOT.md',
|
||||
path: `/tmp/${agentId}/BOOT.md`,
|
||||
exists: false,
|
||||
source: 'template',
|
||||
content: overrides?.boot ?? '# Boot\n',
|
||||
size: 0,
|
||||
updatedAt: null,
|
||||
templateAvailable: true,
|
||||
templatePath: '/runtime/BOOT.md',
|
||||
},
|
||||
];
|
||||
|
||||
return {
|
||||
success: true,
|
||||
selectedAgentId: agentId,
|
||||
defaultAgentId: 'main',
|
||||
agents: [
|
||||
{ id: 'main', name: 'Main', isDefault: true, workspace: '~/.openclaw/workspace' },
|
||||
{ id: 'coder', name: 'Coder', isDefault: false, workspace: '~/.openclaw/workspace-coder' },
|
||||
],
|
||||
documents,
|
||||
paths: {
|
||||
workspace: `/tmp/${agentId}`,
|
||||
templateDir: '/runtime',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe('AgentSystemDocumentsSettings', () => {
|
||||
beforeEach(async () => {
|
||||
vi.clearAllMocks();
|
||||
await i18n.changeLanguage('zh');
|
||||
hostApiFetchMock.mockImplementation((path: string, init?: { method?: string; body?: string }) => {
|
||||
if (path === '/api/agent-system-documents?agentId=coder') {
|
||||
return Promise.resolve(makeSnapshot('coder', { soul: '# Coder soul\n' }));
|
||||
}
|
||||
if (path === '/api/agent-system-documents/soul' && init?.method === 'PUT') {
|
||||
const body = JSON.parse(init.body || '{}') as { content?: string };
|
||||
return Promise.resolve(makeSnapshot('main', { soul: body.content ?? '' }));
|
||||
}
|
||||
if (path === '/api/agent-system-documents/tool/reset' && init?.method === 'POST') {
|
||||
return Promise.resolve(makeSnapshot('main', { tool: '# Tool template\n' }));
|
||||
}
|
||||
return Promise.resolve(makeSnapshot('main'));
|
||||
});
|
||||
});
|
||||
|
||||
it('loads system documents and switches selected agent', async () => {
|
||||
render(<AgentSystemDocumentsSettings />);
|
||||
|
||||
expect(await screen.findByTestId('agent-system-document-editor')).toHaveValue('# Soul\n');
|
||||
expect(screen.getByTestId('agent-system-document-tab-soul')).toHaveTextContent('SOUL.md');
|
||||
|
||||
fireEvent.change(screen.getByTestId('agent-system-document-agent-select'), {
|
||||
target: { value: 'coder' },
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(hostApiFetchMock).toHaveBeenCalledWith('/api/agent-system-documents?agentId=coder');
|
||||
});
|
||||
expect(await screen.findByTestId('agent-system-document-editor')).toHaveValue('# Coder soul\n');
|
||||
});
|
||||
|
||||
it('saves the edited selected document', async () => {
|
||||
render(<AgentSystemDocumentsSettings />);
|
||||
|
||||
const editor = await screen.findByTestId('agent-system-document-editor');
|
||||
fireEvent.change(editor, { target: { value: '# Updated soul\n' } });
|
||||
fireEvent.click(screen.getByTestId('agent-system-document-save'));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(hostApiFetchMock).toHaveBeenCalledWith(
|
||||
'/api/agent-system-documents/soul',
|
||||
expect.objectContaining({
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({ agentId: 'main', content: '# Updated soul\n' }),
|
||||
}),
|
||||
);
|
||||
});
|
||||
expect(toastSuccessMock).toHaveBeenCalledWith('SOUL.md 已保存');
|
||||
});
|
||||
|
||||
it('restores the selected tool document from template', async () => {
|
||||
render(<AgentSystemDocumentsSettings />);
|
||||
|
||||
await screen.findByTestId('agent-system-document-editor');
|
||||
fireEvent.click(screen.getByTestId('agent-system-document-tab-tool'));
|
||||
fireEvent.click(screen.getByTestId('agent-system-document-reset'));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(hostApiFetchMock).toHaveBeenCalledWith(
|
||||
'/api/agent-system-documents/tool/reset',
|
||||
expect.objectContaining({
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ agentId: 'main' }),
|
||||
}),
|
||||
);
|
||||
});
|
||||
expect(await screen.findByTestId('agent-system-document-editor')).toHaveValue('# Tool template\n');
|
||||
});
|
||||
|
||||
it('shows the OpenClaw workspace control documents', async () => {
|
||||
render(<AgentSystemDocumentsSettings />);
|
||||
|
||||
await screen.findByTestId('agent-system-document-editor');
|
||||
|
||||
expect(screen.getByTestId('agent-system-document-tab-identity')).toHaveTextContent('IDENTITY.md');
|
||||
expect(screen.getByTestId('agent-system-document-tab-user')).toHaveTextContent('USER.md');
|
||||
expect(screen.getByTestId('agent-system-document-tab-heartbeat')).toHaveTextContent('HEARTBEAT.md');
|
||||
expect(screen.getByTestId('agent-system-document-tab-boot')).toHaveTextContent('BOOT.md');
|
||||
});
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user