@@ -92,6 +92,10 @@ describe('placesEndpoints', () => {
9292 } )
9393
9494 describe ( 'and an ENS realm with an explicit position is provided' , ( ) => {
95+ // The /places scene record carries a contaminated user_count (the Genesis
96+ // City parcel's occupancy); /worlds carries the World's real count. The
97+ // scene fetch is always the first call, so it's queued in the parent
98+ // beforeEach; each child queues only its distinct /worlds response next.
9599 beforeEach ( ( ) => {
96100 mockGetEnv . mockImplementation ( key => ( key === 'PLACES_API_URL' ? 'https://places.test/api' : undefined ) )
97101 fetchSpy . mockResolvedValueOnce ( {
@@ -109,25 +113,118 @@ describe('placesEndpoints', () => {
109113 description : '' ,
110114 positions : [ '10,20' , '11,20' ] ,
111115 world : true ,
112- world_name : 'cool.dcl.eth'
116+ world_name : 'cool.dcl.eth' ,
117+ user_count : 99
113118 }
114119 ]
115120 } )
116121 } as unknown as Response )
117122 } )
118123
119- it ( 'should query the World scene by name AND position so the API returns only the matching scene' , async ( ) => {
120- const store = createTestStore ( )
121- await store . dispatch ( placesEndpoints . endpoints . getJumpPlaces . initiate ( { realm : 'Cool.DCL.eth' , position : [ 10 , 20 ] } ) )
124+ describe ( 'and the /worlds lookup resolves the World record' , ( ) => {
125+ beforeEach ( ( ) => {
126+ fetchSpy . mockResolvedValueOnce ( {
127+ ok : true ,
128+ json : ( ) =>
129+ Promise . resolve ( { ok : true , data : [ { id : 'cool.dcl.eth' , world : true , world_name : 'cool.dcl.eth' , user_count : 2 } ] } )
130+ } as unknown as Response )
131+ } )
132+
133+ it ( 'should query the World scene by name AND position so the API returns only the matching scene' , async ( ) => {
134+ const store = createTestStore ( )
135+ await store . dispatch ( placesEndpoints . endpoints . getJumpPlaces . initiate ( { realm : 'Cool.DCL.eth' , position : [ 10 , 20 ] } ) )
122136
123- expect ( fetchSpy ) . toHaveBeenCalledWith ( 'https://places.test/api/places?names=cool.dcl.eth&positions=10,20' )
137+ expect ( fetchSpy ) . toHaveBeenCalledWith ( 'https://places.test/api/places?names=cool.dcl.eth&positions=10,20' )
138+ } )
139+
140+ it ( 'should return the scene the server resolved for that position' , async ( ) => {
141+ const store = createTestStore ( )
142+ const result = await store . dispatch (
143+ placesEndpoints . endpoints . getJumpPlaces . initiate ( { realm : 'cool.dcl.eth' , position : [ 10 , 20 ] } )
144+ )
145+
146+ expect ( result . data ?. [ 0 ] ) . toEqual ( expect . objectContaining ( { id : 'arena' } ) )
147+ } )
148+
149+ it ( 'should also query /worlds with the lowercased name to read the reliable occupancy' , async ( ) => {
150+ const store = createTestStore ( )
151+ await store . dispatch ( placesEndpoints . endpoints . getJumpPlaces . initiate ( { realm : 'Cool.DCL.eth' , position : [ 10 , 20 ] } ) )
152+
153+ expect ( fetchSpy ) . toHaveBeenCalledWith ( 'https://places.test/api/worlds?names=cool.dcl.eth' )
154+ } )
155+
156+ it ( 'should overlay the /worlds user_count so the card shows the World occupancy, not the Genesis City parcel count' , async ( ) => {
157+ const store = createTestStore ( )
158+ const result = await store . dispatch (
159+ placesEndpoints . endpoints . getJumpPlaces . initiate ( { realm : 'cool.dcl.eth' , position : [ 10 , 20 ] } )
160+ )
161+
162+ expect ( result . data ?. [ 0 ] . user_count ) . toBe ( 2 )
163+ } )
124164 } )
125165
126- it ( 'should return the scene the server resolved for that position' , async ( ) => {
127- const store = createTestStore ( )
128- const result = await store . dispatch ( placesEndpoints . endpoints . getJumpPlaces . initiate ( { realm : 'cool.dcl.eth' , position : [ 10 , 20 ] } ) )
166+ describe ( 'and the /worlds lookup reports zero users (the user is alone)' , ( ) => {
167+ beforeEach ( ( ) => {
168+ fetchSpy . mockResolvedValueOnce ( {
169+ ok : true ,
170+ json : ( ) =>
171+ Promise . resolve ( { ok : true , data : [ { id : 'cool.dcl.eth' , world : true , world_name : 'cool.dcl.eth' , user_count : 0 } ] } )
172+ } as unknown as Response )
173+ } )
129174
130- expect ( result . data ?. [ 0 ] ) . toEqual ( expect . objectContaining ( { id : 'arena' } ) )
175+ it ( 'should overlay the zero count instead of leaving the contaminated value' , async ( ) => {
176+ const store = createTestStore ( )
177+ const result = await store . dispatch (
178+ placesEndpoints . endpoints . getJumpPlaces . initiate ( { realm : 'cool.dcl.eth' , position : [ 10 , 20 ] } )
179+ )
180+
181+ expect ( result . data ?. [ 0 ] . user_count ) . toBe ( 0 )
182+ } )
183+ } )
184+
185+ describe ( 'and the /worlds lookup fails' , ( ) => {
186+ beforeEach ( ( ) => {
187+ fetchSpy . mockRejectedValueOnce ( new Error ( 'worlds down' ) )
188+ } )
189+
190+ it ( 'should keep the scene record and not crash the query' , async ( ) => {
191+ const store = createTestStore ( )
192+ const result = await store . dispatch (
193+ placesEndpoints . endpoints . getJumpPlaces . initiate ( { realm : 'cool.dcl.eth' , position : [ 10 , 20 ] } )
194+ )
195+
196+ expect ( result . data ?. [ 0 ] ) . toEqual ( expect . objectContaining ( { id : 'arena' , user_count : 99 } ) )
197+ } )
198+ } )
199+
200+ describe ( 'and the /worlds lookup returns a non-OK response' , ( ) => {
201+ beforeEach ( ( ) => {
202+ fetchSpy . mockResolvedValueOnce ( { ok : false , status : 503 } as unknown as Response )
203+ } )
204+
205+ it ( 'should fall back to the scene record value rather than overriding with undefined' , async ( ) => {
206+ const store = createTestStore ( )
207+ const result = await store . dispatch (
208+ placesEndpoints . endpoints . getJumpPlaces . initiate ( { realm : 'cool.dcl.eth' , position : [ 10 , 20 ] } )
209+ )
210+
211+ expect ( result . data ?. [ 0 ] . user_count ) . toBe ( 99 )
212+ } )
213+ } )
214+
215+ describe ( 'and the /worlds lookup returns no record' , ( ) => {
216+ beforeEach ( ( ) => {
217+ fetchSpy . mockResolvedValueOnce ( { ok : true , json : ( ) => Promise . resolve ( { ok : true , data : [ ] } ) } as unknown as Response )
218+ } )
219+
220+ it ( 'should keep the scene record value' , async ( ) => {
221+ const store = createTestStore ( )
222+ const result = await store . dispatch (
223+ placesEndpoints . endpoints . getJumpPlaces . initiate ( { realm : 'cool.dcl.eth' , position : [ 10 , 20 ] } )
224+ )
225+
226+ expect ( result . data ?. [ 0 ] . user_count ) . toBe ( 99 )
227+ } )
131228 } )
132229 } )
133230
0 commit comments