Files
zn-ai/tests/skill-install-shortcut.test.ts
duanshuwen df600272d6 feat: add tool status management and localization for skill installation
- Updated chat message types to include tool statuses.
- Enhanced localization files for English, Thai, and Chinese to support new tool status messages.
- Modified HomePage and SkillsPage components to handle tool statuses in chat messages.
- Implemented tool status merging and updating logic in the chat store.
- Added handling for tool status events in the gateway event processing.
- Created tests for chat message rendering with tool statuses and skill installation shortcuts.
- Improved gateway event dispatching for tool lifecycle events.
2026-04-23 20:27:54 +08:00

175 lines
5.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// @vitest-environment node
import { beforeEach, describe, expect, it, vi } from 'vitest';
const mocks = vi.hoisted(() => ({
appendMessage: vi.fn(),
setActiveRun: vi.fn(),
clearActiveRun: vi.fn(),
handleSkillsInstall: vi.fn(),
parseGitHubSkillUrl: vi.fn((url: string) => ({
owner: 'MiniMax-AI',
repo: 'skills',
ref: 'main',
skillPath: 'skills/minimax-xlsx',
defaultSlug: 'minimax-xlsx',
archiveUrl: 'https://api.github.com/repos/MiniMax-AI/skills/zipball/main',
repositoryUrl: 'https://github.com/MiniMax-AI/skills.git',
originalUrl: url,
})),
appendTranscriptLine: vi.fn(),
logger: {
error: vi.fn(),
},
}));
vi.mock('../electron/gateway/session-store', () => ({
sessionStore: {
appendMessage: mocks.appendMessage,
setActiveRun: mocks.setActiveRun,
clearActiveRun: mocks.clearActiveRun,
},
}));
vi.mock('../electron/gateway/handlers/skills', () => ({
handleSkillsInstall: mocks.handleSkillsInstall,
}));
vi.mock('@electron/service/skill-install-service', () => ({
parseGitHubSkillUrl: mocks.parseGitHubSkillUrl,
}));
vi.mock('@electron/utils/token-usage-writer', () => ({
appendTranscriptLine: mocks.appendTranscriptLine,
}));
vi.mock('@electron/service/logger', () => ({
default: mocks.logger,
}));
function flushAsyncTasks(): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, 0));
}
describe('gateway skill install shortcut', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('extracts a github-url install intent from an explicit install request', async () => {
const { extractSkillInstallIntent } = await import('../electron/gateway/skill-install-shortcut');
expect(
extractSkillInstallIntent(
'https://github.com/MiniMax-AI/skills/blob/main/skills/minimax-xlsx/SKILL.md帮我安装这个skill',
),
).toEqual({
request: {
kind: 'github-url',
url: 'https://github.com/MiniMax-AI/skills/blob/main/skills/minimax-xlsx/SKILL.md',
},
description: 'minimax-xlsx',
});
});
it('extracts a marketplace install intent when the user explicitly names a skill slug', async () => {
const { extractSkillInstallIntent } = await import('../electron/gateway/skill-install-shortcut');
expect(
extractSkillInstallIntent('帮我安装 minimax-xlsx 这个 skill'),
).toEqual({
request: {
kind: 'marketplace',
slug: 'minimax-xlsx',
},
description: 'minimax-xlsx',
});
});
it('runs a skill install shortcut and emits tool status before the final assistant message', async () => {
mocks.handleSkillsInstall.mockResolvedValue({
success: true,
slug: 'minimax-xlsx',
baseDir: '/tmp/minimax-xlsx',
source: 'github-url',
enabled: true,
});
const { maybeHandleSkillInstallMessage } = await import('../electron/gateway/skill-install-shortcut');
const broadcast = vi.fn();
const handled = maybeHandleSkillInstallMessage(
'agent:test:main',
'run-1',
{
role: 'user',
content: 'https://github.com/MiniMax-AI/skills/blob/main/skills/minimax-xlsx/SKILL.md帮我安装这个skill',
},
broadcast,
);
expect(handled).toBe(true);
expect(mocks.setActiveRun).toHaveBeenCalledWith(
'agent:test:main',
'run-1',
expect.any(AbortController),
);
await flushAsyncTasks();
expect(mocks.handleSkillsInstall).toHaveBeenCalledWith(
{
kind: 'github-url',
url: 'https://github.com/MiniMax-AI/skills/blob/main/skills/minimax-xlsx/SKILL.md',
},
broadcast,
);
expect(broadcast).toHaveBeenNthCalledWith(1, expect.objectContaining({
type: 'tool:status',
runId: 'run-1',
toolName: 'skills.install',
status: 'running',
}));
expect(broadcast).toHaveBeenNthCalledWith(2, expect.objectContaining({
type: 'tool:status',
runId: 'run-1',
toolName: 'skills.install',
status: 'completed',
}));
expect(mocks.appendMessage).toHaveBeenCalledWith(
'agent:test:main',
expect.objectContaining({
role: 'assistant',
content: '已安装并启用 skill minimax-xlsxgithub-url。位置/tmp/minimax-xlsx',
_toolStatuses: [
expect.objectContaining({
name: 'skills.install',
status: 'completed',
input: {
kind: 'github-url',
url: 'https://github.com/MiniMax-AI/skills/blob/main/skills/minimax-xlsx/SKILL.md',
},
result: expect.objectContaining({
slug: 'minimax-xlsx',
baseDir: '/tmp/minimax-xlsx',
source: 'github-url',
}),
}),
],
}),
);
expect(broadcast).toHaveBeenNthCalledWith(3, expect.objectContaining({
type: 'chat:final',
runId: 'run-1',
message: expect.objectContaining({
_toolStatuses: [
expect.objectContaining({
name: 'skills.install',
status: 'completed',
}),
],
}),
}));
});
});