Skip to content

Commit 75b639b

Browse files
✅ test: Refactor AssistantStore tests to improve structure and clarity, including EdgeConfig mocking and fetch error handling. (lobehub#7704)
Co-authored-by: gru-agent[bot] <185149714+gru-agent[bot]@users.noreply.github.com>
1 parent 14d8f51 commit 75b639b

File tree

1 file changed

+141
-8
lines changed

1 file changed

+141
-8
lines changed

src/server/modules/AssistantStore/index.test.ts

Lines changed: 141 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,28 @@
11
// @vitest-environment node
2-
import { describe, expect, it } from 'vitest';
2+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3+
4+
import { EdgeConfig } from '@/server/modules/EdgeConfig';
35

46
import { AssistantStore } from './index';
57

68
const baseURL = 'https://registry.npmmirror.com/@lobehub/agents-index/v1/files/public';
9+
10+
vi.mock('@/server/modules/EdgeConfig', () => {
11+
const EdgeConfigMock = vi.fn();
12+
// @ts-expect-error: static mock for isEnabled
13+
EdgeConfigMock.isEnabled = vi.fn();
14+
EdgeConfigMock.prototype.getAgentRestrictions = vi.fn();
15+
return { EdgeConfig: EdgeConfigMock };
16+
});
17+
718
describe('AssistantStore', () => {
19+
beforeEach(() => {
20+
vi.restoreAllMocks();
21+
vi.clearAllMocks();
22+
// @ts-expect-error
23+
global.fetch = undefined;
24+
});
25+
826
it('should return the default index URL when no language is provided', () => {
927
const agentMarket = new AssistantStore();
1028
const url = agentMarket['getAgentIndexUrl']();
@@ -20,17 +38,13 @@ describe('AssistantStore', () => {
2038
it('should return the zh-CN URL for zh locale', () => {
2139
const agentMarket = new AssistantStore();
2240
const url = agentMarket['getAgentIndexUrl']('zh' as any);
23-
expect(url).toBe(
24-
'https://registry.npmmirror.com/@lobehub/agents-index/v1/files/public/index.zh-CN.json',
25-
);
41+
expect(url).toBe(`${baseURL}/index.zh-CN.json`);
2642
});
2743

2844
it('should return the default URL for en locale', () => {
2945
const agentMarket = new AssistantStore();
3046
const url = agentMarket['getAgentIndexUrl']('en' as any);
31-
expect(url).toBe(
32-
'https://registry.npmmirror.com/@lobehub/agents-index/v1/files/public/index.en-US.json',
33-
);
47+
expect(url).toBe(`${baseURL}/index.en-US.json`);
3448
});
3549

3650
it('should return the base URL if the provided language is not supported', () => {
@@ -45,7 +59,7 @@ describe('AssistantStore', () => {
4559
expect(url).toBe(`${baseURL}/agent-123.en-US.json`);
4660
});
4761

48-
it('should return the agent URL for a supported language', () => {
62+
it('should return the agent URL for a supported language', () => {
4963
const agentMarket = new AssistantStore();
5064
const url = agentMarket.getAgentUrl('agent-123', 'zh-CN');
5165
expect(url).toBe(`${baseURL}/agent-123.zh-CN.json`);
@@ -56,4 +70,123 @@ describe('AssistantStore', () => {
5670
const url = agentMarket.getAgentUrl('agent-123', 'fr' as any);
5771
expect(url).toBe(`${baseURL}/agent-123.json`);
5872
});
73+
74+
it('should return empty agents array with schema version when fetch fails', async () => {
75+
global.fetch = vi.fn().mockRejectedValue(new Error('fetch failed'));
76+
const store = new AssistantStore();
77+
const result = await store.getAgentIndex();
78+
expect(result).toEqual({ agents: [], schemaVersion: 1 });
79+
});
80+
81+
it('should handle fetch error and return empty agents with schema version when error.ok is false', async () => {
82+
global.fetch = vi.fn().mockResolvedValue({
83+
ok: false,
84+
text: () => Promise.resolve('Error'),
85+
});
86+
const store = new AssistantStore();
87+
const result = await store.getAgentIndex();
88+
expect(result).toEqual({ agents: [], schemaVersion: 1 });
89+
});
90+
91+
it('should filter agents by whitelist when EdgeConfig is enabled', async () => {
92+
const mockAgents = {
93+
agents: [
94+
{ identifier: 'agent1', meta: {}, author: '', createAt: '', createdAt: '', homepage: '' },
95+
{ identifier: 'agent2', meta: {}, author: '', createAt: '', createdAt: '', homepage: '' },
96+
],
97+
schemaVersion: 1,
98+
};
99+
100+
global.fetch = vi.fn().mockResolvedValue({
101+
ok: true,
102+
status: 200,
103+
json: () => Promise.resolve({ ...mockAgents }),
104+
});
105+
106+
// @ts-expect-error
107+
EdgeConfig.isEnabled.mockReturnValue(true);
108+
109+
const store = new AssistantStore();
110+
(EdgeConfig as any).prototype.getAgentRestrictions.mockResolvedValue({
111+
whitelist: ['agent1'],
112+
blacklist: undefined,
113+
});
114+
115+
const result = await store.getAgentIndex();
116+
117+
expect(result.agents).toHaveLength(1);
118+
expect(result.agents[0].identifier).toBe('agent1');
119+
});
120+
121+
it('should filter agents by blacklist when EdgeConfig is enabled and no whitelist', async () => {
122+
const mockAgents = {
123+
agents: [
124+
{ identifier: 'agent1', meta: {}, author: '', createAt: '', createdAt: '', homepage: '' },
125+
{ identifier: 'agent2', meta: {}, author: '', createAt: '', createdAt: '', homepage: '' },
126+
],
127+
schemaVersion: 1,
128+
};
129+
130+
global.fetch = vi.fn().mockResolvedValue({
131+
ok: true,
132+
status: 200,
133+
json: () => Promise.resolve({ ...mockAgents }),
134+
});
135+
136+
// @ts-expect-error
137+
EdgeConfig.isEnabled.mockReturnValue(true);
138+
139+
const store = new AssistantStore();
140+
(EdgeConfig as any).prototype.getAgentRestrictions.mockResolvedValue({
141+
whitelist: undefined,
142+
blacklist: ['agent2'],
143+
});
144+
145+
const result = await store.getAgentIndex();
146+
147+
expect(result.agents).toHaveLength(1);
148+
expect(result.agents[0].identifier).toBe('agent1');
149+
});
150+
151+
it('should fallback to default language if fetch returns 404', async () => {
152+
const mockAgents = {
153+
agents: [
154+
{ identifier: 'agent1', meta: {}, author: '', createAt: '', createdAt: '', homepage: '' },
155+
],
156+
schemaVersion: 1,
157+
};
158+
159+
const fetchMock = vi
160+
.fn()
161+
.mockResolvedValueOnce({
162+
status: 404,
163+
ok: false,
164+
text: () => Promise.resolve('Not found'),
165+
})
166+
.mockResolvedValueOnce({
167+
status: 200,
168+
ok: true,
169+
json: () => Promise.resolve({ ...mockAgents }),
170+
});
171+
172+
global.fetch = fetchMock as any;
173+
174+
// @ts-expect-error
175+
EdgeConfig.isEnabled.mockReturnValue(false);
176+
177+
const store = new AssistantStore();
178+
const result = await store.getAgentIndex('zh-CN');
179+
expect(result).toEqual(mockAgents);
180+
expect(fetchMock).toHaveBeenCalledTimes(2);
181+
});
182+
183+
it('should throw error for unexpected error in getAgentIndex', async () => {
184+
global.fetch = vi.fn().mockRejectedValue(new Error('something else'));
185+
const store = new AssistantStore();
186+
187+
// eslint-disable-next-line @typescript-eslint/no-empty-function
188+
vi.spyOn(console, 'error').mockImplementation(() => {});
189+
190+
await expect(store.getAgentIndex()).rejects.toThrow('something else');
191+
});
59192
});

0 commit comments

Comments
 (0)