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
46import { AssistantStore } from './index' ;
57
68const 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+
718describe ( '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