1
1
/* Copyright Contributors to the Open Cluster Management project */
2
2
3
- import { render , screen } from '@testing-library/react'
3
+ import { render , screen , waitFor } from '@testing-library/react'
4
4
import userEvent from '@testing-library/user-event'
5
5
import { MemoryRouter , Route , Routes } from 'react-router-dom-v5-compat'
6
6
import { RecoilRoot } from 'recoil'
7
7
import { managedClustersState , placementDecisionsState , subscriptionsState } from '../../atoms'
8
8
import {
9
+ nockAggegateRequest ,
9
10
nockIgnoreApiPaths ,
10
11
nockIgnoreRBAC ,
11
12
nockPostRequest ,
12
13
nockSearch ,
13
- nockAggegateRequest ,
14
14
} from '../../lib/nock-util'
15
15
import { defaultPlugin , PluginContext } from '../../lib/PluginContext'
16
- import { waitForText } from '../../lib/test-util'
16
+ import { getCSVDownloadLink , getCSVExportSpies , waitForText } from '../../lib/test-util'
17
17
import {
18
18
ApplicationKind ,
19
19
ApplicationSetKind ,
@@ -22,6 +22,8 @@ import {
22
22
ManagedClusterKind ,
23
23
SubscriptionKind ,
24
24
} from '../../resources'
25
+ import { getISOStringTimestamp } from '../../resources/utils'
26
+ import { AcmToastGroup , AcmToastProvider } from '../../ui-components'
25
27
import {
26
28
acmExtension ,
27
29
mockApplication0 ,
@@ -112,26 +114,28 @@ describe('Applications Page', () => {
112
114
snapshot . set ( managedClustersState , mockClusters )
113
115
} }
114
116
>
115
- < MemoryRouter >
116
- < PluginContext . Provider
117
- value = { {
118
- ...defaultPlugin ,
119
- acmExtensions : acmExtension ,
120
- } }
121
- >
122
- < Routes >
123
- < Route path = "*" element = { < Overview /> } />
124
- </ Routes >
125
- </ PluginContext . Provider >
126
- </ MemoryRouter >
117
+ < AcmToastProvider >
118
+ < AcmToastGroup />
119
+ < MemoryRouter >
120
+ < PluginContext . Provider
121
+ value = { {
122
+ ...defaultPlugin ,
123
+ acmExtensions : acmExtension ,
124
+ } }
125
+ >
126
+ < Routes >
127
+ < Route path = "*" element = { < Overview /> } />
128
+ </ Routes >
129
+ </ PluginContext . Provider >
130
+ </ MemoryRouter >
131
+ </ AcmToastProvider >
127
132
</ RecoilRoot >
128
133
)
129
134
} )
130
135
131
136
test ( 'should display info' , async ( ) => {
132
137
// wait for page to load
133
138
await waitForText ( 'feng-remote-argo8' )
134
-
135
139
expect ( screen . getByText ( SubscriptionKind ) ) . toBeTruthy ( )
136
140
expect ( screen . getByText ( mockApplication0 . metadata . namespace ! ) ) . toBeTruthy ( )
137
141
expect ( screen . getAllByText ( 'Local' ) ) . toBeTruthy ( )
@@ -233,29 +237,37 @@ describe('Applications Page', () => {
233
237
userEvent . click ( screen . getByRole ( 'button' , { name : / c l o s e o p e n s h i f t / i } ) )
234
238
} )
235
239
236
- test . skip ( 'export button should produce a file for download' , async ( ) => {
237
- nockAggegateRequest ( 'applications' , fetchAggregate . req , applicationAggregate . res )
240
+ test ( 'export button should produce a file for download' , async ( ) => {
241
+ nockAggegateRequest ( 'applications' , fetchAggregate . req , fetchAggregate . res )
238
242
239
243
await waitForText ( 'feng-remote-argo8' )
240
244
241
245
window . URL . createObjectURL = jest . fn ( )
242
246
window . URL . revokeObjectURL = jest . fn ( )
243
- const documentBody = document . body . appendChild
244
- const documentCreate = document . createElement ( 'a' ) . dispatchEvent
245
247
246
- const anchorMocked = { href : '' , click : jest . fn ( ) , download : 'table-values' , style : { display : '' } } as any
247
- const createElementSpyOn = jest . spyOn ( document , 'createElement' ) . mockReturnValueOnce ( anchorMocked )
248
- document . body . appendChild = jest . fn ( )
249
- document . createElement ( 'a' ) . dispatchEvent = jest . fn ( )
248
+ const { blobConstructorSpy, createElementSpy } = getCSVExportSpies ( )
250
249
251
- userEvent . click ( screen . getByLabelText ( 'export-search-result' ) )
250
+ userEvent . click ( screen . getByTestId ( 'export-search-result' ) )
252
251
userEvent . click ( screen . getByText ( 'Export all to CSV' ) )
253
252
254
- expect ( createElementSpyOn ) . toHaveBeenCalledWith ( 'a' )
255
- expect ( anchorMocked . download ) . toContain ( 'table-values' )
256
-
257
- document . body . appendChild = documentBody
258
- document . createElement ( 'a' ) . dispatchEvent = documentCreate
259
- await new Promise ( ( resolve ) => setTimeout ( resolve , 1500 ) )
253
+ await waitFor ( ( ) => {
254
+ const toastElement = screen . getByText ( / E x p o r t s u c c e s s f u l / i)
255
+ expect ( toastElement ) . toBeInTheDocument ( )
256
+ } )
257
+
258
+ expect ( blobConstructorSpy ) . toHaveBeenCalledWith (
259
+ [
260
+ 'Name,Type,Namespace,Clusters,Repository,Health Status,Sync Status,Time window,Created\n' +
261
+ `"application-0","Subscription","namespace-0","Local",-,-,-,-,"${ getISOStringTimestamp ( applicationAggregate . res . items [ 0 ] . metadata ?. creationTimestamp || '' ) } "\n` +
262
+ '"applicationset-0","Application set","openshift-gitops","None","git",-,-,-,-\n' +
263
+ '"applicationset-1","Application set","openshift-gitops","None","git",-,-,-,-\n' +
264
+ '"argoapplication-1","Argo CD","argoapplication-1-ns","unknown","git",-,-,-,-\n' +
265
+ '"feng-remote-argo8","Argo CD","argoapplication-1-ns","unknown","git",-,-,-,-\n' +
266
+ '"authentication-operator","OpenShift","authentication-operator-ns","None",-,-,-,-,-\n' +
267
+ '"authentication-operatorf","Flux","authentication-operator-ns","None",-,-,-,-,-' ,
268
+ ] ,
269
+ { type : 'text/csv' }
270
+ )
271
+ expect ( getCSVDownloadLink ( createElementSpy ) ?. value . download ) . toMatch ( / ^ a p p l i c a t i o n s o v e r v i e w - [ \d ] + \. c s v $ / )
260
272
} )
261
273
} )
0 commit comments