完善客户端模块与工作区能力
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import {
|
||||
AgentProfileApiError,
|
||||
deleteAgentAvatar,
|
||||
getAgentProfile,
|
||||
getAgentProfileApiErrorMessage,
|
||||
putAgentProfile,
|
||||
uploadAgentAvatar,
|
||||
} from '@/lib/agent-profile';
|
||||
|
||||
const hostApiFetchMock = vi.hoisted(() => vi.fn());
|
||||
@@ -57,6 +60,78 @@ describe('Agent Profile API client', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('sends a completed local session snapshot alongside the profile', async () => {
|
||||
hostApiFetchMock.mockResolvedValue({ success: true, profile });
|
||||
const sessionData = {
|
||||
project_id: 'prj_1',
|
||||
session_id: 'ses_1',
|
||||
updated_at: '2026-08-13T10:00:00.000Z',
|
||||
messages: [{
|
||||
id: 'msg_1',
|
||||
role: 'user' as const,
|
||||
created_at: '2026-08-13T09:59:00.000Z',
|
||||
text: '请帮我解释这个问题。',
|
||||
}],
|
||||
};
|
||||
|
||||
await expect(putAgentProfile('access-token', {
|
||||
display_name: '小泥',
|
||||
age: 18,
|
||||
gender: 'female',
|
||||
share_age_with_agents: true,
|
||||
share_gender_with_agents: true,
|
||||
analysis_enabled: true,
|
||||
version: 2,
|
||||
session_data: sessionData,
|
||||
})).resolves.toEqual(profile);
|
||||
|
||||
expect(hostApiFetchMock).toHaveBeenCalledWith('/api/works/user/agent-profile', {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({
|
||||
display_name: '小泥',
|
||||
age: 18,
|
||||
gender: 'female',
|
||||
share_age_with_agents: true,
|
||||
share_gender_with_agents: true,
|
||||
analysis_enabled: true,
|
||||
version: 2,
|
||||
session_data: sessionData,
|
||||
}),
|
||||
headers: { 'X-NianCode-Access-Token': 'access-token' },
|
||||
});
|
||||
});
|
||||
|
||||
it('uploads a prepared avatar through the authenticated Host API proxy', async () => {
|
||||
hostApiFetchMock.mockResolvedValue({ success: true, avatar_url: 'https://cdn.example/avatar.webp' });
|
||||
|
||||
await expect(uploadAgentAvatar('access-token', {
|
||||
fileName: 'avatar.webp',
|
||||
mimeType: 'image/webp',
|
||||
dataBase64: 'QUJD',
|
||||
})).resolves.toBe('https://cdn.example/avatar.webp');
|
||||
|
||||
expect(hostApiFetchMock).toHaveBeenCalledWith('/api/works/user/avatar', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
fileName: 'avatar.webp',
|
||||
mimeType: 'image/webp',
|
||||
dataBase64: 'QUJD',
|
||||
}),
|
||||
headers: { 'X-NianCode-Access-Token': 'access-token' },
|
||||
});
|
||||
});
|
||||
|
||||
it('deletes the current avatar through the authenticated Host API proxy', async () => {
|
||||
hostApiFetchMock.mockResolvedValue({ success: true, avatar_url: null });
|
||||
|
||||
await expect(deleteAgentAvatar('access-token')).resolves.toBeNull();
|
||||
|
||||
expect(hostApiFetchMock).toHaveBeenCalledWith('/api/works/user/avatar', {
|
||||
method: 'DELETE',
|
||||
headers: { 'X-NianCode-Access-Token': 'access-token' },
|
||||
});
|
||||
});
|
||||
|
||||
it('retains upstream conflict detail for the store to handle', async () => {
|
||||
hostApiFetchMock.mockResolvedValue({
|
||||
success: false,
|
||||
@@ -69,6 +144,42 @@ describe('Agent Profile API client', () => {
|
||||
name: 'AgentProfileApiError',
|
||||
status: 409,
|
||||
detail: { code: 'agent_profile_version_conflict', current_version: 4 },
|
||||
code: 'agent_profile_version_conflict',
|
||||
});
|
||||
});
|
||||
|
||||
it('retains avatar validation error codes from the Host API proxy', async () => {
|
||||
hostApiFetchMock.mockResolvedValue({
|
||||
success: false,
|
||||
status: 415,
|
||||
code: 'avatar_unsupported_type',
|
||||
error: 'Unsupported avatar image type',
|
||||
});
|
||||
|
||||
await expect(deleteAgentAvatar('access-token')).rejects.toMatchObject<Partial<AgentProfileApiError>>({
|
||||
status: 415,
|
||||
code: 'avatar_unsupported_type',
|
||||
});
|
||||
});
|
||||
|
||||
it('keeps a structured service error visible instead of replacing it with generic 503 text', async () => {
|
||||
hostApiFetchMock.mockResolvedValue({
|
||||
success: false,
|
||||
status: 503,
|
||||
error: 'Agent Profile database migration is pending',
|
||||
detail: {
|
||||
code: 'agent_profile_storage_unavailable',
|
||||
message: 'Agent Profile database migration is pending',
|
||||
},
|
||||
code: 'agent_profile_storage_unavailable',
|
||||
});
|
||||
|
||||
const error = await getAgentProfile('access-token').catch((value) => value as AgentProfileApiError);
|
||||
expect(error).toMatchObject({
|
||||
status: 503,
|
||||
code: 'agent_profile_storage_unavailable',
|
||||
message: 'Agent Profile database migration is pending',
|
||||
});
|
||||
expect(getAgentProfileApiErrorMessage(error)).toBe('Agent Profile database migration is pending');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user