1
1
import { cleanup , screen , act , fireEvent } from '@testing-library/react' ;
2
2
import { superRender } from '@actiontech/shared/lib/testUtil/superRender' ;
3
3
import AvailabilityZoneWrapper from '..' ;
4
- import { useLocation , Outlet , useNavigate } from 'react-router-dom' ;
4
+ import { useLocation , Outlet , useNavigate , useParams } from 'react-router-dom' ;
5
5
import { mockUseRecentlySelectedZone } from '../../../../testUtils/mockHooks/mockUseRecentlySelectedZone' ;
6
6
import { mockUseRecentlySelectedZoneData } from '../../../../testUtils/mockHooks/data' ;
7
+ import { mockUseRecentlyOpenedProjects } from '../../../Nav/SideMenu/testUtils/mockUseRecentlyOpenedProjects' ;
8
+ import { baseMockApi } from '@actiontech/shared/lib/testUtil' ;
7
9
8
10
jest . mock ( 'react-router-dom' , ( ) => ( {
9
11
...jest . requireActual ( 'react-router-dom' ) ,
10
12
useLocation : jest . fn ( ) ,
11
13
Outlet : jest . fn ( ) ,
12
- useNavigate : jest . fn ( )
14
+ useNavigate : jest . fn ( ) ,
15
+ useParams : jest . fn ( )
13
16
} ) ) ;
14
17
15
18
describe ( 'base/AvailabilityZone/AvailabilityZoneWrapper' , ( ) => {
16
19
const navigateSpy = jest . fn ( ) ;
17
20
21
+ const getRecentlyProjectIdByUserInfoSpy = jest . fn ( ) ;
22
+
23
+ let getCurrentUserSpy : jest . SpyInstance ;
24
+ const useParamsSpy : jest . Mock = useParams as jest . Mock ;
25
+
18
26
const mockAvailabilityZoneOptions = [
19
27
{ value : 'zone-123' , label : 'Test Zone' } ,
20
28
{ value : 'zone-456' , label : 'Another Zone' }
21
29
] ;
22
30
23
31
beforeEach ( ( ) => {
24
32
jest . useFakeTimers ( ) ;
33
+ getCurrentUserSpy = baseMockApi . global . getCurrentUser ( ) ;
25
34
26
35
( Outlet as jest . Mock ) . mockImplementation ( ( ) => < div > Outlet Content</ div > ) ;
27
36
@@ -31,6 +40,11 @@ describe('base/AvailabilityZone/AvailabilityZoneWrapper', () => {
31
40
pathname : '/test-path' ,
32
41
search : '?test=true'
33
42
} ) ) ;
43
+ useParamsSpy . mockReturnValue ( { projectID : undefined } ) ;
44
+ mockUseRecentlyOpenedProjects ( {
45
+ getRecentlyProjectIdByUserInfo : getRecentlyProjectIdByUserInfoSpy
46
+ } ) ;
47
+
34
48
mockUseRecentlySelectedZone ( ) ;
35
49
} ) ;
36
50
@@ -101,12 +115,11 @@ describe('base/AvailabilityZone/AvailabilityZoneWrapper', () => {
101
115
102
116
fireEvent . click ( screen . getByText ( '确 认' ) ) ;
103
117
118
+ await act ( async ( ) => jest . advanceTimersByTime ( 3000 ) ) ;
104
119
expect ( updateRecentlySelectedZoneSpy ) . toHaveBeenCalledWith ( {
105
120
uid : 'zone-123' ,
106
121
name : 'Test Zone'
107
122
} ) ;
108
-
109
- expect ( navigateSpy ) . toHaveBeenCalledWith ( '/test-path?test=true' ) ;
110
123
} ) ;
111
124
112
125
it ( 'should show modal when memorized zone not in available options' , ( ) => {
@@ -134,4 +147,123 @@ describe('base/AvailabilityZone/AvailabilityZoneWrapper', () => {
134
147
expect ( screen . getByText ( 'Outlet Content' ) ) . toBeInTheDocument ( ) ;
135
148
expect ( screen . queryByText ( '选择可用区' ) ) . not . toBeInTheDocument ( ) ;
136
149
} ) ;
150
+
151
+ describe ( 'Project path replacement logic' , ( ) => {
152
+ const updateRecentlySelectedZoneSpy = jest . fn ( ) ;
153
+
154
+ beforeEach ( ( ) => {
155
+ mockUseRecentlySelectedZone ( {
156
+ ...mockUseRecentlySelectedZoneData ,
157
+ updateRecentlySelectedZone : updateRecentlySelectedZoneSpy ,
158
+ availabilityZoneOptions : mockAvailabilityZoneOptions
159
+ } ) ;
160
+ } ) ;
161
+
162
+ it ( 'should navigate to project path when memorized project exists and no default project in URL' , async ( ) => {
163
+ getRecentlyProjectIdByUserInfoSpy . mockReturnValue ( 'project-123' ) ;
164
+
165
+ ( useLocation as jest . Mock ) . mockImplementation ( ( ) => ( {
166
+ pathname : '/sqle/project//dashboard' ,
167
+ search : '?test=true'
168
+ } ) ) ;
169
+
170
+ superRender ( < AvailabilityZoneWrapper /> ) ;
171
+
172
+ const selectElement = screen . getByRole ( 'combobox' ) ;
173
+ fireEvent . mouseDown ( selectElement ) ;
174
+
175
+ await act ( async ( ) => jest . advanceTimersByTime ( 0 ) ) ;
176
+
177
+ fireEvent . click ( screen . getByText ( 'Test Zone' ) ) ;
178
+ fireEvent . click ( screen . getByText ( '确 认' ) ) ;
179
+
180
+ await act ( async ( ) => jest . advanceTimersByTime ( 3000 ) ) ;
181
+
182
+ expect ( navigateSpy ) . toHaveBeenCalledWith (
183
+ '/sqle/project/project-123/dashboard?test=true' ,
184
+ { replace : true }
185
+ ) ;
186
+ } ) ;
187
+
188
+ it ( 'should navigate to project path when memorized project exists and default project in URL' , async ( ) => {
189
+ getRecentlyProjectIdByUserInfoSpy . mockReturnValue ( 'project-123' ) ;
190
+ useParamsSpy . mockReturnValue ( { projectID : '700300' } ) ;
191
+
192
+ ( useLocation as jest . Mock ) . mockImplementation ( ( ) => ( {
193
+ pathname : '/sqle/project/700300/dashboard' ,
194
+ search : '?test=true'
195
+ } ) ) ;
196
+
197
+ superRender ( < AvailabilityZoneWrapper /> ) ;
198
+
199
+ const selectElement = screen . getByRole ( 'combobox' ) ;
200
+ fireEvent . mouseDown ( selectElement ) ;
201
+
202
+ await act ( async ( ) => jest . advanceTimersByTime ( 0 ) ) ;
203
+
204
+ fireEvent . click ( screen . getByText ( 'Test Zone' ) ) ;
205
+ fireEvent . click ( screen . getByText ( '确 认' ) ) ;
206
+
207
+ await act ( async ( ) => jest . advanceTimersByTime ( 3000 ) ) ;
208
+
209
+ expect ( navigateSpy ) . toHaveBeenCalledWith (
210
+ '/sqle/project/project-123/dashboard?test=true' ,
211
+ { replace : true }
212
+ ) ;
213
+ } ) ;
214
+
215
+ it ( 'should replace project id when project id in url but project id not in bind projects' , async ( ) => {
216
+ getRecentlyProjectIdByUserInfoSpy . mockReturnValue ( undefined ) ;
217
+ useParamsSpy . mockReturnValue ( { projectID : '123456' } ) ;
218
+
219
+ ( useLocation as jest . Mock ) . mockImplementation ( ( ) => ( {
220
+ pathname : '/sqle/project/123456/dashboard' ,
221
+ search : '?test=true'
222
+ } ) ) ;
223
+
224
+ superRender ( < AvailabilityZoneWrapper /> ) ;
225
+
226
+ const selectElement = screen . getByRole ( 'combobox' ) ;
227
+ fireEvent . mouseDown ( selectElement ) ;
228
+
229
+ await act ( async ( ) => jest . advanceTimersByTime ( 0 ) ) ;
230
+
231
+ fireEvent . click ( screen . getByText ( 'Test Zone' ) ) ;
232
+ fireEvent . click ( screen . getByText ( '确 认' ) ) ;
233
+
234
+ await act ( async ( ) => jest . advanceTimersByTime ( 3000 ) ) ;
235
+ expect ( getCurrentUserSpy ) . toHaveBeenCalledTimes ( 1 ) ;
236
+
237
+ expect ( navigateSpy ) . toHaveBeenCalledWith (
238
+ '/sqle/project//dashboard?test=true' ,
239
+ { replace : true }
240
+ ) ;
241
+ } ) ;
242
+
243
+ it ( 'should handle path without sqle prefix correctly' , async ( ) => {
244
+ getRecentlyProjectIdByUserInfoSpy . mockReturnValue ( 'project-123' ) ;
245
+
246
+ ( useLocation as jest . Mock ) . mockImplementation ( ( ) => ( {
247
+ pathname : '/project//dashboard' ,
248
+ search : '?test=true'
249
+ } ) ) ;
250
+
251
+ superRender ( < AvailabilityZoneWrapper /> ) ;
252
+
253
+ const selectElement = screen . getByRole ( 'combobox' ) ;
254
+ fireEvent . mouseDown ( selectElement ) ;
255
+
256
+ await act ( async ( ) => jest . advanceTimersByTime ( 0 ) ) ;
257
+
258
+ fireEvent . click ( screen . getByText ( 'Test Zone' ) ) ;
259
+ fireEvent . click ( screen . getByText ( '确 认' ) ) ;
260
+
261
+ await act ( async ( ) => jest . advanceTimersByTime ( 3000 ) ) ;
262
+
263
+ expect ( navigateSpy ) . toHaveBeenCalledWith (
264
+ '/project/project-123/dashboard?test=true' ,
265
+ { replace : true }
266
+ ) ;
267
+ } ) ;
268
+ } ) ;
137
269
} ) ;
0 commit comments