@trackunit/react-core-contexts-test 1.7.80 → 1.7.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HookRenderer.cjs.js +9 -7
- package/HookRenderer.esm.js +6 -4
- package/index.cjs.js +38 -1375
- package/index.cjs2.js +14585 -0
- package/index.esm.js +17 -1358
- package/index.esm2.js +14544 -0
- package/package.json +5 -7
- package/src/TrackunitProvidersMockBuilder.d.ts +1 -1
- package/src/mocks/mockAnalyticsContext.d.ts +1 -1
- package/src/mocks/mockAssetSortingContext.d.ts +1 -1
- package/src/mocks/mockConfirmationDialogContext.d.ts +1 -1
- package/src/mocks/mockCurrentUserContext.d.ts +1 -1
- package/src/mocks/mockCurrentUserPreferenceContext.d.ts +1 -1
- package/src/mocks/mockEnvironmentContext.d.ts +1 -1
- package/src/mocks/mockErrorHandlerContext.d.ts +1 -1
- package/src/mocks/mockFilterBarContext.d.ts +1 -1
- package/src/mocks/mockModalDialogContext.d.ts +1 -1
- package/src/mocks/mockNavigationContext.d.ts +1 -1
- package/src/mocks/mockOemBrandingContext.d.ts +1 -1
- package/src/mocks/mockTimeRangeContext.d.ts +1 -1
- package/src/mocks/mockToastContext.d.ts +1 -1
- package/src/mocks/mockUserSubscriptionContext.d.ts +1 -1
- package/src/mocks/mockWidgetConfigContext.d.ts +1 -1
package/index.esm.js
CHANGED
|
@@ -1,1358 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
*/
|
|
19
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
|
-
const doNothing = () => {
|
|
21
|
-
/* Do nothing */
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const mockAnalyticsContext = {
|
|
25
|
-
logEvent: doNothing,
|
|
26
|
-
logError: doNothing,
|
|
27
|
-
logPageView: doNothing,
|
|
28
|
-
setUserProperty: doNothing,
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const mockAssetSortingContext = {
|
|
32
|
-
setSortBy: doNothing,
|
|
33
|
-
sortingState: {
|
|
34
|
-
sortBy: AssetSortByProperty.Criticality,
|
|
35
|
-
order: SortOrder.Desc,
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Mocks the current user context
|
|
41
|
-
*
|
|
42
|
-
* @returns {CurrentUserContextInterface} - Returns the mocked current user context
|
|
43
|
-
*/
|
|
44
|
-
const mockCurrentUserContext = {
|
|
45
|
-
clientSideUserId: "751ea227-f199-4d00-925f-a608312c5e45",
|
|
46
|
-
userName: "",
|
|
47
|
-
userRole: "",
|
|
48
|
-
customerId: 12345,
|
|
49
|
-
userId: 154312,
|
|
50
|
-
tasUserId: "751ea227-f199-4d00-925f-a608312c5e45",
|
|
51
|
-
email: "",
|
|
52
|
-
name: "",
|
|
53
|
-
accountId: "",
|
|
54
|
-
assumedUser: null,
|
|
55
|
-
jobTitle: "",
|
|
56
|
-
isAuthenticated: true,
|
|
57
|
-
isVerified: true,
|
|
58
|
-
isTrackunitUser: false,
|
|
59
|
-
isAssuming: false,
|
|
60
|
-
isAccountOwner: true,
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const mockEnvironmentContext = {
|
|
64
|
-
auth: {
|
|
65
|
-
url: "",
|
|
66
|
-
clientId: "",
|
|
67
|
-
issuer: "",
|
|
68
|
-
},
|
|
69
|
-
managerClassicUrl: "https://sso.trackunit.com",
|
|
70
|
-
googleMapsApiKey: "",
|
|
71
|
-
amplitudeApiKey: "",
|
|
72
|
-
amplitudeApiEndpoint: "",
|
|
73
|
-
graphqlPublicUrl: "",
|
|
74
|
-
graphqlInternalUrl: "",
|
|
75
|
-
graphqlReportUrl: "",
|
|
76
|
-
buildVersion: "",
|
|
77
|
-
commitNumber: 0,
|
|
78
|
-
irisAppSdkServerUrl: "",
|
|
79
|
-
publicUrl: "",
|
|
80
|
-
isFeatureBranch: false,
|
|
81
|
-
environment: "dev",
|
|
82
|
-
sentryDsn: "",
|
|
83
|
-
sessionId: "",
|
|
84
|
-
tracingHeaders: {
|
|
85
|
-
"X-TrackunitAppVersion": "",
|
|
86
|
-
"session-id": "",
|
|
87
|
-
"commit-number": 0,
|
|
88
|
-
},
|
|
89
|
-
trackunitRestApiUrl: "",
|
|
90
|
-
hubspotRequestAppAccessFormId: "",
|
|
91
|
-
uptimeId: "",
|
|
92
|
-
reportAccessCallback: "",
|
|
93
|
-
reportAccessClientId: "",
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* This is a mock for the FilterBarContext.
|
|
98
|
-
*
|
|
99
|
-
* @returns { FilterBarContext }- mock for the FilterBarContext
|
|
100
|
-
*/
|
|
101
|
-
const mockFilterBarContext = {
|
|
102
|
-
assetsFilterBarValues: {},
|
|
103
|
-
customersFilterBarValues: {},
|
|
104
|
-
sitesFilterBarValues: {},
|
|
105
|
-
isLoading: false,
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
const mockOemBrandingContext = {
|
|
109
|
-
getAllBrandingDetails: doNothing,
|
|
110
|
-
getOemBranding: async () => null,
|
|
111
|
-
getOemImage: doNothing,
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
const mockToastContext = {
|
|
115
|
-
addToast: doNothing,
|
|
116
|
-
removeToast: doNothing,
|
|
117
|
-
setIsManifestError: doNothing,
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* This is a mock for the UserSubscriptionContext.
|
|
122
|
-
*
|
|
123
|
-
* @returns { IUserSubscriptionContext }- mock for the UserSubscriptionContext
|
|
124
|
-
*/
|
|
125
|
-
const mockUserSubscriptionContext = {
|
|
126
|
-
numberOfDaysWithAccessToHistoricalData: 30,
|
|
127
|
-
numberOfDaysWithAccessToHistoricalInsights: 30,
|
|
128
|
-
features: [],
|
|
129
|
-
loading: false,
|
|
130
|
-
packageType: "EXPAND_FLEET_OWNER",
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
const defaultOptions = {
|
|
134
|
-
mutate: {
|
|
135
|
-
errorPolicy: "all",
|
|
136
|
-
},
|
|
137
|
-
query: {
|
|
138
|
-
errorPolicy: "all",
|
|
139
|
-
},
|
|
140
|
-
};
|
|
141
|
-
/**
|
|
142
|
-
* This is a wrapper around the MockedProvider that logs errors to the console.
|
|
143
|
-
*/
|
|
144
|
-
function ApolloMockedProviderWithError(props) {
|
|
145
|
-
const isDebugging = !!process.env.VSCODE_INSPECTOR_OPTIONS || !!process.env.DEBUG;
|
|
146
|
-
loadDevMessages();
|
|
147
|
-
loadErrorMessages();
|
|
148
|
-
const { mocks, ...otherProps } = props;
|
|
149
|
-
const mockLink = new MockLink(mocks, false, { showWarnings: isDebugging });
|
|
150
|
-
const errorLoggingLink = onError(({ graphQLErrors, networkError }) => {
|
|
151
|
-
if (graphQLErrors) {
|
|
152
|
-
graphQLErrors.map(({ message, locations, path }) => {
|
|
153
|
-
if (isDebugging) {
|
|
154
|
-
// eslint-disable-next-line no-console
|
|
155
|
-
console.log(`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`);
|
|
156
|
-
}
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
if (networkError && isDebugging) {
|
|
160
|
-
// eslint-disable-next-line no-console
|
|
161
|
-
console.log(`[Network error]: ${networkError}`);
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
const link = ApolloLink.from([errorLoggingLink, mockLink]);
|
|
165
|
-
return (jsx(MockedProvider, { ...otherProps, defaultOptions: { ...defaultOptions, watchQuery: { fetchPolicy: "no-cache" } }, link: link }));
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const mockConfirmationDialogContext = {
|
|
169
|
-
confirm: doNothing,
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Mocks the current user context
|
|
174
|
-
*
|
|
175
|
-
* @returns {IUserPreferencesContext} - Returns the mocked current user context
|
|
176
|
-
*/
|
|
177
|
-
const mockCurrentUserPreferenceContext = {
|
|
178
|
-
language: "en",
|
|
179
|
-
setLanguage: doNothing,
|
|
180
|
-
timeZonePreference: "LOCAL_TIME_ZONE",
|
|
181
|
-
setTimeZonePreference: doNothing,
|
|
182
|
-
systemOfMeasurement: "SI",
|
|
183
|
-
setSystemOfMeasurement: doNothing,
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
const mockExportDataContextState = {
|
|
187
|
-
exportData: () => Promise.resolve(),
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Mocks the ErrorHandlingContextValue
|
|
192
|
-
*
|
|
193
|
-
* @returns {ErrorHandlingContextValue} - Returns the mocked current user context
|
|
194
|
-
*/
|
|
195
|
-
const mockErrorHandlerContext = {
|
|
196
|
-
captureException: doNothing$1,
|
|
197
|
-
addBreadcrumb: doNothing$1,
|
|
198
|
-
setTag: doNothing$1,
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
const mockModalDialogContext = {
|
|
202
|
-
openModal: doNothing,
|
|
203
|
-
closeModal: doNothing,
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
const mockNavigationContext = {
|
|
207
|
-
hasAccessTo: (options) => {
|
|
208
|
-
return Promise.resolve(true);
|
|
209
|
-
},
|
|
210
|
-
gotoAssetHome: (assetId, options) => {
|
|
211
|
-
return Promise.resolve(true);
|
|
212
|
-
},
|
|
213
|
-
gotoSiteHome: (siteId, options) => {
|
|
214
|
-
return Promise.resolve(true);
|
|
215
|
-
},
|
|
216
|
-
gotoGroupHome: (groupId, options) => {
|
|
217
|
-
return Promise.resolve(true);
|
|
218
|
-
},
|
|
219
|
-
gotoAppLibrary: (irisAppId) => {
|
|
220
|
-
return Promise.resolve(true);
|
|
221
|
-
},
|
|
222
|
-
gotoFleetApp: (options) => {
|
|
223
|
-
return Promise.resolve(true);
|
|
224
|
-
},
|
|
225
|
-
gotoCustomerHome: (customerId) => {
|
|
226
|
-
return Promise.resolve(true);
|
|
227
|
-
},
|
|
228
|
-
gotoAdmin: (url) => {
|
|
229
|
-
return Promise.resolve(true);
|
|
230
|
-
},
|
|
231
|
-
gotoAlerts: (url) => {
|
|
232
|
-
return Promise.resolve(true);
|
|
233
|
-
},
|
|
234
|
-
gotoMarketplace: () => {
|
|
235
|
-
return Promise.resolve(true);
|
|
236
|
-
},
|
|
237
|
-
reloadManager: () => {
|
|
238
|
-
return Promise.resolve(true);
|
|
239
|
-
},
|
|
240
|
-
getAssetHomeUrl: (assetId, options) => {
|
|
241
|
-
return Promise.resolve(`/assets/${assetId}/status`);
|
|
242
|
-
},
|
|
243
|
-
getSiteHomeUrl: (siteId, options) => {
|
|
244
|
-
return Promise.resolve(`/sites/${siteId}/overview`);
|
|
245
|
-
},
|
|
246
|
-
getGroupHomeUrl: (groupId, options) => {
|
|
247
|
-
return Promise.resolve(`/groups/${groupId}/home`);
|
|
248
|
-
},
|
|
249
|
-
getCustomerHomeUrl: (customerId, options) => {
|
|
250
|
-
return Promise.resolve(customerId ? `/customers/${customerId}/info` : `/customers`);
|
|
251
|
-
},
|
|
252
|
-
getAppLibraryUrl: irisAppId => {
|
|
253
|
-
return Promise.resolve(`/administration/app-library`);
|
|
254
|
-
},
|
|
255
|
-
getFleetAppUrl: options => {
|
|
256
|
-
return Promise.resolve(`/fleet`);
|
|
257
|
-
},
|
|
258
|
-
getAdminUrl: url => {
|
|
259
|
-
return Promise.resolve(url ? `/administration${url}` : `/administration`);
|
|
260
|
-
},
|
|
261
|
-
getAlertsUrl: url => {
|
|
262
|
-
return Promise.resolve(url ? `/event-setup${url}` : `/event-setup`);
|
|
263
|
-
},
|
|
264
|
-
getMarketplaceUrl: options => {
|
|
265
|
-
return Promise.resolve(`/marketplace`);
|
|
266
|
-
},
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
const mockTimeRangeContext = {
|
|
270
|
-
timeRange: {
|
|
271
|
-
startMsInEpoch: 1,
|
|
272
|
-
endMsInEpoch: 2,
|
|
273
|
-
},
|
|
274
|
-
temporalPeriod: {
|
|
275
|
-
direction: "last",
|
|
276
|
-
count: 3,
|
|
277
|
-
unit: "days",
|
|
278
|
-
},
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
const mockWidgetConfigContext = {
|
|
282
|
-
pollInterval: 1000,
|
|
283
|
-
getTitle: async () => "Test Title",
|
|
284
|
-
setTitle: async () => { },
|
|
285
|
-
getData: async () => ({}),
|
|
286
|
-
getDataVersion: async () => 1,
|
|
287
|
-
setData: async () => { },
|
|
288
|
-
setLoadingState: async () => { },
|
|
289
|
-
openEditMode: async () => { },
|
|
290
|
-
closeEditMode: async () => { },
|
|
291
|
-
};
|
|
292
|
-
|
|
293
|
-
const RerenderContext = createContext({ rerenderCounter: 0, setRerenderCounter: (value) => { } });
|
|
294
|
-
/**
|
|
295
|
-
* This provider is used to force re-renders in the test environment, since tanstack router does not support re-render.
|
|
296
|
-
*/
|
|
297
|
-
const RerenderProvider = ({ children, counter }) => {
|
|
298
|
-
const [rerenderCounter, setRerenderCounter] = useState(0);
|
|
299
|
-
useEffect(() => {
|
|
300
|
-
if (counter && rerenderCounter !== counter && rerenderCounter !== 0) {
|
|
301
|
-
setRerenderCounter(counter);
|
|
302
|
-
}
|
|
303
|
-
}, [rerenderCounter, counter]);
|
|
304
|
-
return (jsx(RerenderContext.Provider, { value: { rerenderCounter, setRerenderCounter }, children: children }));
|
|
305
|
-
};
|
|
306
|
-
/**
|
|
307
|
-
* This hook is used to get the rerender counter.
|
|
308
|
-
*/
|
|
309
|
-
const useRerenderCounter = () => {
|
|
310
|
-
return useContext(RerenderContext);
|
|
311
|
-
};
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* This component is used to force re-renders in the test environment, since tanstack router does not support re-render.
|
|
315
|
-
*/
|
|
316
|
-
const RerenderComponent = ({ children }) => {
|
|
317
|
-
const { rerenderCounter } = useRerenderCounter();
|
|
318
|
-
return (jsx("div", { "data-rerender-counter": `rerender-${rerenderCounter}`, children: Children.map(children, child => isValidElement(child)
|
|
319
|
-
? createElement(child.type, {
|
|
320
|
-
...child.props,
|
|
321
|
-
key: child.key,
|
|
322
|
-
"data-rerender-counter": rerenderCounter,
|
|
323
|
-
})
|
|
324
|
-
: child) }));
|
|
325
|
-
};
|
|
326
|
-
|
|
327
|
-
const buildFlatRouteMap = (routes) => {
|
|
328
|
-
const routeMap = {};
|
|
329
|
-
routes.forEach(route => {
|
|
330
|
-
routeMap[route.id] = route;
|
|
331
|
-
if (Array.isArray(route.children)) {
|
|
332
|
-
Object.assign(routeMap, buildFlatRouteMap(route.children));
|
|
333
|
-
}
|
|
334
|
-
});
|
|
335
|
-
return routeMap;
|
|
336
|
-
};
|
|
337
|
-
/**
|
|
338
|
-
* This component is used to wrap the children of the RouterContainer to add a test root container
|
|
339
|
-
*/
|
|
340
|
-
const RootRouteDebugger = () => {
|
|
341
|
-
// const matches = useMatches();
|
|
342
|
-
// console.log(
|
|
343
|
-
// "matches",
|
|
344
|
-
// matches.map(match => match.routeId)
|
|
345
|
-
// );
|
|
346
|
-
return jsx(Outlet, {});
|
|
347
|
-
};
|
|
348
|
-
/**
|
|
349
|
-
* This component is used to wrap the children of the RouterContainer to add a test root container.
|
|
350
|
-
*
|
|
351
|
-
* @param addTestRootContainer boolean to add test root container
|
|
352
|
-
* @param children children to be wrapped
|
|
353
|
-
* @returns {ReactNode} children component wrapped in a test root container
|
|
354
|
-
*/
|
|
355
|
-
const TestRenderChildren = ({ addTestRootContainer, children }) => {
|
|
356
|
-
return addTestRootContainer ? (jsx("div", { className: "inline-block h-[1000px] w-[1024px] scale-[.99]", "data-testid": "testRoot", style: {
|
|
357
|
-
"--tw-scale-x": "0.99",
|
|
358
|
-
"--tw-scale-y": "0.99",
|
|
359
|
-
}, children: children })) : (jsx("div", { children: children }));
|
|
360
|
-
};
|
|
361
|
-
/**
|
|
362
|
-
* This component is used to wrap the children of the RouterContainer to add a test root container.
|
|
363
|
-
*
|
|
364
|
-
* @param addTestRootContainer boolean to add test root container
|
|
365
|
-
* @param selectedRouterProps selected router props
|
|
366
|
-
* @param rootRoute root route
|
|
367
|
-
* @param children children to be wrapped
|
|
368
|
-
* @returns {ReactElement} children component wrapped in a test root container
|
|
369
|
-
*/
|
|
370
|
-
const RouterContainer = ({ addTestRootContainer, selectedRouterProps, rootRoute, children, }) => {
|
|
371
|
-
const client = useApolloClient();
|
|
372
|
-
// The current version of createMemoryHistory seem to have issues when NOT ending on / so adding a # will not effect what url is rendered but it seems to work
|
|
373
|
-
const memoryHistory = useRef(createMemoryHistory({
|
|
374
|
-
initialEntries: selectedRouterProps?.initialEntries?.reverse().map(entry => entry.path + "#") ?? ["/#"],
|
|
375
|
-
initialIndex: 0,
|
|
376
|
-
}));
|
|
377
|
-
const addTestRootContainerRef = useRef(addTestRootContainer);
|
|
378
|
-
useEffect(() => {
|
|
379
|
-
addTestRootContainerRef.current = addTestRootContainer;
|
|
380
|
-
}, [addTestRootContainer]);
|
|
381
|
-
const getChildren = useCallback(() => children, [children]);
|
|
382
|
-
const childrenRef = useRef(() => getChildren());
|
|
383
|
-
useEffect(() => {
|
|
384
|
-
childrenRef.current = () => getChildren();
|
|
385
|
-
}, [getChildren]);
|
|
386
|
-
const initialEntriesRef = useRef(selectedRouterProps?.initialEntries);
|
|
387
|
-
useEffect(() => {
|
|
388
|
-
initialEntriesRef.current = selectedRouterProps?.initialEntries;
|
|
389
|
-
}, [selectedRouterProps?.initialEntries]);
|
|
390
|
-
const router = useMemo(() => {
|
|
391
|
-
let localRootRoute = rootRoute;
|
|
392
|
-
if (!localRootRoute) {
|
|
393
|
-
const route = createRootRoute({ component: RootRouteDebugger });
|
|
394
|
-
const childRoute = createRoute({
|
|
395
|
-
path: "/",
|
|
396
|
-
getParentRoute: () => route,
|
|
397
|
-
component: () => {
|
|
398
|
-
return (jsx(TestRenderChildren, { addTestRootContainer: addTestRootContainerRef.current, children: childrenRef.current() }));
|
|
399
|
-
},
|
|
400
|
-
});
|
|
401
|
-
route.addChildren([childRoute]);
|
|
402
|
-
localRootRoute = route;
|
|
403
|
-
}
|
|
404
|
-
else {
|
|
405
|
-
const pathsToRoute = buildFlatRouteMap([localRootRoute]);
|
|
406
|
-
objectValues(pathsToRoute).forEach(route => {
|
|
407
|
-
route.options.component = RootRouteDebugger;
|
|
408
|
-
route.lazyFn = undefined;
|
|
409
|
-
});
|
|
410
|
-
if (pathsToRoute.__root__) {
|
|
411
|
-
pathsToRoute.__root__.options.component = RootRouteDebugger;
|
|
412
|
-
pathsToRoute.__root__.options.beforeLoad = () => { };
|
|
413
|
-
pathsToRoute.__root__.lazyFn = undefined;
|
|
414
|
-
}
|
|
415
|
-
if (pathsToRoute["/"]) {
|
|
416
|
-
// This ensures / is not redirecting to default home route
|
|
417
|
-
pathsToRoute["/"].options.beforeLoad = () => { };
|
|
418
|
-
}
|
|
419
|
-
if ((initialEntriesRef.current?.length || 0) > 0) {
|
|
420
|
-
initialEntriesRef.current?.forEach(entry => {
|
|
421
|
-
const route = pathsToRoute[entry.route];
|
|
422
|
-
if (route) {
|
|
423
|
-
if (entry.beforeLoad) {
|
|
424
|
-
route.options.beforeLoad = entry.beforeLoad;
|
|
425
|
-
}
|
|
426
|
-
if (entry.component) {
|
|
427
|
-
route.options.component = entry.component;
|
|
428
|
-
}
|
|
429
|
-
else {
|
|
430
|
-
route.update({
|
|
431
|
-
component: () => {
|
|
432
|
-
return (jsx(TestRenderChildren, { addTestRootContainer: addTestRootContainerRef.current, children: childrenRef.current() }));
|
|
433
|
-
},
|
|
434
|
-
});
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
});
|
|
438
|
-
}
|
|
439
|
-
else {
|
|
440
|
-
const slashRoute = pathsToRoute["/"];
|
|
441
|
-
if (slashRoute) {
|
|
442
|
-
slashRoute.options.component = () => (jsx(TestRenderChildren, { addTestRootContainer: addTestRootContainerRef.current, children: childrenRef.current() }));
|
|
443
|
-
}
|
|
444
|
-
else {
|
|
445
|
-
const childRoute = createRoute({
|
|
446
|
-
path: "/",
|
|
447
|
-
getParentRoute: () => localRootRoute,
|
|
448
|
-
component: () => {
|
|
449
|
-
return (jsx(TestRenderChildren, { addTestRootContainer: addTestRootContainerRef.current, children: childrenRef.current() }));
|
|
450
|
-
},
|
|
451
|
-
});
|
|
452
|
-
localRootRoute.addChildren([childRoute]);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
return createRouter({
|
|
457
|
-
routeTree: localRootRoute,
|
|
458
|
-
history: memoryHistory.current,
|
|
459
|
-
defaultPendingMs: 0,
|
|
460
|
-
defaultPendingMinMs: 0, // Add this to control minimum pending time
|
|
461
|
-
context: {
|
|
462
|
-
hasAccessTo: async () => {
|
|
463
|
-
return true;
|
|
464
|
-
},
|
|
465
|
-
showMarketplace: true,
|
|
466
|
-
showHelpCenter: true,
|
|
467
|
-
showAppLibrary: true,
|
|
468
|
-
client: null,
|
|
469
|
-
defaultUserRoute: "/",
|
|
470
|
-
isAuthenticated: true,
|
|
471
|
-
},
|
|
472
|
-
});
|
|
473
|
-
}, [rootRoute]);
|
|
474
|
-
const context = useMemo(() => ({
|
|
475
|
-
hasAccessTo: async () => true,
|
|
476
|
-
isAuthenticated: true,
|
|
477
|
-
client,
|
|
478
|
-
defaultUserRoute: "/",
|
|
479
|
-
...(selectedRouterProps?.context || {}),
|
|
480
|
-
}), [client, selectedRouterProps?.context]);
|
|
481
|
-
const ErrorComponent = ({ error }) => {
|
|
482
|
-
return jsxs(Fragment, { children: ["UNCAUGHT ERROR IN TEST: ", error instanceof Error ? error.message : error] });
|
|
483
|
-
};
|
|
484
|
-
return jsx(RouterProvider, { context: context, defaultErrorComponent: ErrorComponent, router: router });
|
|
485
|
-
};
|
|
486
|
-
|
|
487
|
-
/**
|
|
488
|
-
* Flushes all promises in the queue.
|
|
489
|
-
* This is useful when testing async code.
|
|
490
|
-
*
|
|
491
|
-
* @param waitTimeInMS - The amount of time to wait before resolving the promise.
|
|
492
|
-
* @returns {Promise<void>} - Returns a promise that resolves after the wait time.
|
|
493
|
-
*/
|
|
494
|
-
const flushPromises = (waitTimeInMS = 0) => {
|
|
495
|
-
return new Promise(resolve => {
|
|
496
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
497
|
-
if (global.ORG_setTimeout) {
|
|
498
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
499
|
-
return global.ORG_setTimeout(() => global.ORG_setTimeout(resolve, waitTimeInMS), 1);
|
|
500
|
-
}
|
|
501
|
-
else {
|
|
502
|
-
setTimeout(() => setTimeout(resolve, waitTimeInMS), 1);
|
|
503
|
-
}
|
|
504
|
-
});
|
|
505
|
-
};
|
|
506
|
-
/**
|
|
507
|
-
* Flushes all promises in the queue.
|
|
508
|
-
* This is useful when testing async code.
|
|
509
|
-
*
|
|
510
|
-
* @param waitTimeInMS - The amount of time to wait before resolving the promise.
|
|
511
|
-
* @returns {Promise<void>} - Returns a promise that resolves after the wait time.
|
|
512
|
-
*/
|
|
513
|
-
const flushPromisesInAct = (waitTimeInMS = 0) => {
|
|
514
|
-
return act(() => {
|
|
515
|
-
return new Promise(resolve => {
|
|
516
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
517
|
-
if (global.ORG_setTimeout) {
|
|
518
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
519
|
-
return global.ORG_setTimeout(() => global.ORG_setTimeout(resolve, waitTimeInMS), 1);
|
|
520
|
-
}
|
|
521
|
-
else {
|
|
522
|
-
setTimeout(() => setTimeout(resolve, waitTimeInMS), 1);
|
|
523
|
-
}
|
|
524
|
-
});
|
|
525
|
-
});
|
|
526
|
-
};
|
|
527
|
-
|
|
528
|
-
/**
|
|
529
|
-
* This builder allows you to enable trackunit providers using the builder pattern, and then call 1 of either:
|
|
530
|
-
* For React Components:
|
|
531
|
-
* - render
|
|
532
|
-
* For React Hooks:
|
|
533
|
-
* - renderHook
|
|
534
|
-
* For Storybook:
|
|
535
|
-
* - storybook
|
|
536
|
-
*/
|
|
537
|
-
class TrackunitProvidersMockBuilder {
|
|
538
|
-
constructor() {
|
|
539
|
-
this.selectedEnvironmentContext = mockEnvironmentContext;
|
|
540
|
-
this.selectedModalDialogContext = mockModalDialogContext;
|
|
541
|
-
this.selectedTimeRangeContext = mockTimeRangeContext;
|
|
542
|
-
this.selectedWidgetConfigContext = mockWidgetConfigContext;
|
|
543
|
-
this.selectedNavigationContext = mockNavigationContext;
|
|
544
|
-
this.selectedTokenContext = { token: "fakeToken" };
|
|
545
|
-
this.selectedApolloMocks = [];
|
|
546
|
-
this.selectedRouterProps = null;
|
|
547
|
-
this.selectedToastContext = mockToastContext;
|
|
548
|
-
this.selectedErrorHandler = mockErrorHandlerContext;
|
|
549
|
-
this.selectedConfirmationDialogContext = mockConfirmationDialogContext;
|
|
550
|
-
this.selectedAssetSortingContext = mockAssetSortingContext;
|
|
551
|
-
this.selectedCurrentUserContext = mockCurrentUserContext;
|
|
552
|
-
this.selectedCurrentUserPreferenceContext = mockCurrentUserPreferenceContext;
|
|
553
|
-
this.selectedAnalyticsContext = mockAnalyticsContext;
|
|
554
|
-
this.selectedOemBrandingContext = mockOemBrandingContext;
|
|
555
|
-
this.selectedUserSubscriptionContext = mockUserSubscriptionContext;
|
|
556
|
-
this.selectedFilterBarValues = mockFilterBarContext;
|
|
557
|
-
this.selectedExportDataContext = mockExportDataContextState;
|
|
558
|
-
}
|
|
559
|
-
/**
|
|
560
|
-
* Use this Analytics Context.
|
|
561
|
-
* Defaults to mockAnalyticsContext.
|
|
562
|
-
*
|
|
563
|
-
* This context is used by the useAnalytics hook from lib "@trackunit/react-core-hooks"
|
|
564
|
-
*
|
|
565
|
-
* @see mockAnalyticsContext
|
|
566
|
-
* @example
|
|
567
|
-
* ...
|
|
568
|
-
* it("should allow render", async () => {
|
|
569
|
-
* await trackunitProviders().analytics(yourPartialAnalyticsMock).render(<YourTestComponent data-testid="yourTestId" />);
|
|
570
|
-
* expect(screen.getByTestId("yourTestId")).toBeInTheDocument();
|
|
571
|
-
* });
|
|
572
|
-
* ...
|
|
573
|
-
* @example
|
|
574
|
-
* ...
|
|
575
|
-
* it("should allow renderHook", async () => {
|
|
576
|
-
* const { result } = await trackunitProviders().analytics(yourPartialAnalyticsMock).renderHook(() => useYourTestHook());
|
|
577
|
-
* expect(result.current).toEqual(anything());
|
|
578
|
-
* });
|
|
579
|
-
* ...
|
|
580
|
-
* @param analyticsContext - The analytics context to use.
|
|
581
|
-
* @returns { TrackunitProvidersMockBuilder } - The builder.
|
|
582
|
-
*/
|
|
583
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
584
|
-
analytics(analyticsContext) {
|
|
585
|
-
this.selectedAnalyticsContext = { ...mockAnalyticsContext, ...analyticsContext };
|
|
586
|
-
return this;
|
|
587
|
-
}
|
|
588
|
-
/**
|
|
589
|
-
* Use this Environment Context.
|
|
590
|
-
* Defaults to mockEnvironmentContext.
|
|
591
|
-
*
|
|
592
|
-
* This context is used by the useEnvironment hook from lib "@trackunit/react-core-hooks"
|
|
593
|
-
*
|
|
594
|
-
* @see mockEnvironmentContext
|
|
595
|
-
* @example
|
|
596
|
-
* ...
|
|
597
|
-
* it("should allow render", async () => {
|
|
598
|
-
* await trackunitProviders().environment(yourPartialEnvironmentsMock).render(<YourTestComponent data-testid="yourTestId" />);
|
|
599
|
-
* expect(screen.getByTestId("yourTestId")).toBeInTheDocument();
|
|
600
|
-
* });
|
|
601
|
-
* ...
|
|
602
|
-
* @example
|
|
603
|
-
* ...
|
|
604
|
-
* it("should allow renderHook", async () => {
|
|
605
|
-
* const { result } = await trackunitProviders().environment(yourPartialEnvironmentMock).renderHook(() => useYourTestHook());
|
|
606
|
-
* expect(result.current).toEqual(anything());
|
|
607
|
-
* });
|
|
608
|
-
* ...
|
|
609
|
-
* @param environmentContext - The environment context to use.
|
|
610
|
-
* @returns { TrackunitProvidersMockBuilder } - The builder.
|
|
611
|
-
*/
|
|
612
|
-
environment(environmentContext) {
|
|
613
|
-
this.selectedEnvironmentContext = { ...mockEnvironmentContext, ...environmentContext };
|
|
614
|
-
return this;
|
|
615
|
-
}
|
|
616
|
-
/**
|
|
617
|
-
* Use this Time Range Context, used for myhome.
|
|
618
|
-
* Defaults to mockTimeRangeContext.
|
|
619
|
-
*
|
|
620
|
-
* @see mockTimeRangeContext
|
|
621
|
-
*/
|
|
622
|
-
timeRange(timeRangeContext) {
|
|
623
|
-
this.selectedTimeRangeContext = { ...mockTimeRangeContext, ...timeRangeContext };
|
|
624
|
-
return this;
|
|
625
|
-
}
|
|
626
|
-
/**
|
|
627
|
-
* Use this Widget Config Context.
|
|
628
|
-
* Defaults to mockWidgetConfigContext.
|
|
629
|
-
*
|
|
630
|
-
* @see mockWidgetConfigContext
|
|
631
|
-
*/
|
|
632
|
-
widgetConfig(widgetConfigContext) {
|
|
633
|
-
this.selectedWidgetConfigContext = { ...mockWidgetConfigContext, ...widgetConfigContext };
|
|
634
|
-
return this;
|
|
635
|
-
}
|
|
636
|
-
/**
|
|
637
|
-
* Use this Navigation Context.
|
|
638
|
-
* Defaults to mockNavigationContext.
|
|
639
|
-
*
|
|
640
|
-
* @see mockNavigationContext
|
|
641
|
-
* @example
|
|
642
|
-
* ...
|
|
643
|
-
* it("should allow render", async () => {
|
|
644
|
-
* await trackunitProviders().navigation(yourPartialNavigationMock).render(<YourTestComponent data-testid="yourTestId" />);
|
|
645
|
-
* expect(screen.getByTestId("yourTestId")).toBeInTheDocument();
|
|
646
|
-
* });
|
|
647
|
-
*/
|
|
648
|
-
navigation(navigationContext) {
|
|
649
|
-
this.selectedNavigationContext = { ...mockNavigationContext, ...navigationContext };
|
|
650
|
-
return this;
|
|
651
|
-
}
|
|
652
|
-
/**
|
|
653
|
-
* Use this to pass in a differerent current user.
|
|
654
|
-
* Defaults to mockCurrentUserContext.
|
|
655
|
-
*
|
|
656
|
-
* This context is used by the useCurrentUser hook from lib "@trackunit/react-core-hooks"
|
|
657
|
-
*
|
|
658
|
-
* @see mockCurrentUserContext
|
|
659
|
-
* @example
|
|
660
|
-
* ...
|
|
661
|
-
* it("should allow render", async () => {
|
|
662
|
-
* await trackunitProviders().currentUser(yourPartialCurrentUserMock).render(<YourTestComponent data-testid="yourTestId" />);
|
|
663
|
-
* expect(screen.getByTestId("yourTestId")).toBeInTheDocument();
|
|
664
|
-
* });
|
|
665
|
-
* ...
|
|
666
|
-
* @example
|
|
667
|
-
* ...
|
|
668
|
-
* it("should allow renderHook", async () => {
|
|
669
|
-
* const { result } = await trackunitProviders().currentUser(yourPartialCurrentUserMock).renderHook(() => useYourTestHook());
|
|
670
|
-
* expect(result.current).toEqual(anything());
|
|
671
|
-
* });
|
|
672
|
-
* ...
|
|
673
|
-
* @returns { TrackunitProvidersMockBuilder } - The builder.
|
|
674
|
-
*/
|
|
675
|
-
currentUser(currentUserContext) {
|
|
676
|
-
this.selectedCurrentUserContext = { ...mockCurrentUserContext, ...currentUserContext };
|
|
677
|
-
return this;
|
|
678
|
-
}
|
|
679
|
-
/**
|
|
680
|
-
* Use this to pass in a differerent current user preference.
|
|
681
|
-
* Defaults to mockCurrentUserPreferenceContext.
|
|
682
|
-
*
|
|
683
|
-
* This context is used by the useCurrentUserPreference hook from lib "@trackunit/react-core-hooks"
|
|
684
|
-
*
|
|
685
|
-
* @see mockCurrentUserPreferenceContext
|
|
686
|
-
* @example
|
|
687
|
-
* ...
|
|
688
|
-
* it("should allow render", async () => {
|
|
689
|
-
* await trackunitProviders().currentUserPreference(yourPartialCurrentUserPreferenceMock).render(<YourTestComponent data-testid="yourTestId" />);
|
|
690
|
-
* expect(screen.getByTestId("yourTestId")).toBeInTheDocument();
|
|
691
|
-
* });
|
|
692
|
-
* ...
|
|
693
|
-
* @example
|
|
694
|
-
* ...
|
|
695
|
-
* it("should allow renderHook", async () => {
|
|
696
|
-
* const { result } = await trackunitProviders().currentUserPreference(yourPartialCurrentUserPreferenceMock).renderHook(() => useYourTestHook());
|
|
697
|
-
* expect(result.current).toEqual(anything());
|
|
698
|
-
* });
|
|
699
|
-
* ...
|
|
700
|
-
* @returns { TrackunitProvidersMockBuilder } - The builder.
|
|
701
|
-
*/
|
|
702
|
-
currentUserPreference(currentUserPreferenceContext) {
|
|
703
|
-
this.selectedCurrentUserPreferenceContext = {
|
|
704
|
-
...mockCurrentUserPreferenceContext,
|
|
705
|
-
...currentUserPreferenceContext,
|
|
706
|
-
};
|
|
707
|
-
return this;
|
|
708
|
-
}
|
|
709
|
-
/**
|
|
710
|
-
* Use this to pass in a differerent filter bar values when working with pages with filterbar.
|
|
711
|
-
* Defaults to { filterBarValues: {} }.
|
|
712
|
-
*
|
|
713
|
-
* @param filterBarValues - The filter bar values to use.
|
|
714
|
-
* @example
|
|
715
|
-
* ...
|
|
716
|
-
* it("should allow render", async () => {
|
|
717
|
-
* await trackunitProviders().filterBarValues(yourFilterBarValuesMock).render(<YourTestComponent data-testid="yourTestId" />);
|
|
718
|
-
* expect(screen.getByTestId("yourTestId")).toBeInTheDocument();
|
|
719
|
-
* });
|
|
720
|
-
* ...
|
|
721
|
-
* @example
|
|
722
|
-
* ...
|
|
723
|
-
* it("should allow renderHook", async () => {
|
|
724
|
-
* const { result } = await trackunitProviders().filterBarValues(yourFilterBarValuesMock).renderHook(() => useYourTestHook());
|
|
725
|
-
* expect(result.current).toEqual(anything());
|
|
726
|
-
* });
|
|
727
|
-
* ...
|
|
728
|
-
* @returns { TrackunitProvidersMockBuilder } - The builder.
|
|
729
|
-
*/
|
|
730
|
-
filterBarValues(filterBarValues) {
|
|
731
|
-
this.selectedFilterBarValues = { ...this.selectedFilterBarValues, ...filterBarValues };
|
|
732
|
-
return this;
|
|
733
|
-
}
|
|
734
|
-
/**
|
|
735
|
-
* Use this to pass in a differerent current user subscription.
|
|
736
|
-
* Defaults to mockUserSubscriptionContext.
|
|
737
|
-
*
|
|
738
|
-
* This context is used by the useUserSubscription hook from lib "@trackunit/react-core-hooks"
|
|
739
|
-
*
|
|
740
|
-
* @see mockUserSubscriptionContext
|
|
741
|
-
* @example
|
|
742
|
-
* ...
|
|
743
|
-
* it("should allow render", async () => {
|
|
744
|
-
* await trackunitProviders().userSubscription(yourPartialUserSubscriptionMock).render(<YourTestComponent data-testid="yourTestId" />);
|
|
745
|
-
* expect(screen.getByTestId("yourTestId")).toBeInTheDocument();
|
|
746
|
-
* });
|
|
747
|
-
* ...
|
|
748
|
-
* @example
|
|
749
|
-
* ...
|
|
750
|
-
* it("should allow renderHook", async () => {
|
|
751
|
-
* const { result } = await trackunitProviders().userSubscription(yourPartialUserSubscriptionMock).renderHook(() => useYourTestHook());
|
|
752
|
-
* expect(result.current).toEqual(anything());
|
|
753
|
-
* });
|
|
754
|
-
* ...
|
|
755
|
-
* @returns { TrackunitProvidersMockBuilder } - The builder.
|
|
756
|
-
*/
|
|
757
|
-
userSubscription(userSubscription) {
|
|
758
|
-
//TODO DON'T SUPPORT THE WEIRD WAY OF PASSING FEATURES
|
|
759
|
-
const featuresConverted = userSubscription.features?.map(f => {
|
|
760
|
-
if (typeof f === "string") {
|
|
761
|
-
return { id: f, name: f };
|
|
762
|
-
}
|
|
763
|
-
return f;
|
|
764
|
-
}) || [];
|
|
765
|
-
this.selectedUserSubscriptionContext = {
|
|
766
|
-
...mockUserSubscriptionContext,
|
|
767
|
-
...omit(userSubscription, ["features"]),
|
|
768
|
-
features: [...(mockUserSubscriptionContext.features || []), ...featuresConverted],
|
|
769
|
-
};
|
|
770
|
-
return this;
|
|
771
|
-
}
|
|
772
|
-
/**
|
|
773
|
-
* Set global asset sorting context.
|
|
774
|
-
* Defaults to mockAssetSortingContext.
|
|
775
|
-
*
|
|
776
|
-
* This context is used by the useAssetSorting hook from lib "@trackunit/react-core-hooks"
|
|
777
|
-
*
|
|
778
|
-
* @see mockAssetSortingContext
|
|
779
|
-
* @example
|
|
780
|
-
* ...
|
|
781
|
-
* it("should allow render", async () => {
|
|
782
|
-
* await trackunitProviders().assetSorting(yourPartialAssetSortingMock).render(<YourTestComponent data-testid="yourTestId" />);
|
|
783
|
-
* expect(screen.getByTestId("yourTestId")).toBeInTheDocument();
|
|
784
|
-
* });
|
|
785
|
-
* ...
|
|
786
|
-
* @example
|
|
787
|
-
* ...
|
|
788
|
-
* it("should allow renderHook", async () => {
|
|
789
|
-
* const { result } = await trackunitProviders().assetSorting(yourPartialAssetSortingMock).renderHook(() => useYourTestHook());
|
|
790
|
-
* expect(result.current).toEqual(anything());
|
|
791
|
-
* });
|
|
792
|
-
* ...
|
|
793
|
-
* @param assetSortingContext - Override the default context.
|
|
794
|
-
* @returns { TrackunitProvidersMockBuilder } - The builder.
|
|
795
|
-
*/
|
|
796
|
-
assetSorting(assetSortingContext) {
|
|
797
|
-
this.selectedAssetSortingContext = { ...mockAssetSortingContext, ...assetSortingContext };
|
|
798
|
-
return this;
|
|
799
|
-
}
|
|
800
|
-
/**
|
|
801
|
-
* Use this to pass in a differerent export data context.
|
|
802
|
-
* Defaults to mockExportDataContextState.
|
|
803
|
-
*
|
|
804
|
-
* This context is used by the useExportDataContext hook from lib "@trackunit/react-core-hooks"
|
|
805
|
-
*
|
|
806
|
-
* @see mockExportDataContextState
|
|
807
|
-
* @example
|
|
808
|
-
* ...
|
|
809
|
-
* it("should allow render", async () => {
|
|
810
|
-
* await trackunitProviders().exportData(yourPartialExportDataMock).render(<YourTestComponent data-testid="yourTestId" />);
|
|
811
|
-
* expect(screen.getByTestId("yourTestId")).toBeInTheDocument();
|
|
812
|
-
* });
|
|
813
|
-
* ...
|
|
814
|
-
*/
|
|
815
|
-
exportData(exportDataContext) {
|
|
816
|
-
this.selectedExportDataContext = { ...mockExportDataContextState, ...exportDataContext };
|
|
817
|
-
return this;
|
|
818
|
-
}
|
|
819
|
-
/**
|
|
820
|
-
* Set OEM Branding context.
|
|
821
|
-
* Defaults to mockOemBrandingContext.
|
|
822
|
-
*
|
|
823
|
-
* This context is used by the useAssetSorting hook from lib "@trackunit/react-core-hooks"
|
|
824
|
-
*
|
|
825
|
-
* @see mockOemBrandingContext
|
|
826
|
-
* @example
|
|
827
|
-
* ...
|
|
828
|
-
* it("should allow render", async () => {
|
|
829
|
-
* await trackunitProviders().oemBrandingContext(yourPartialOemBrandingMock).render(<YourTestComponent data-testid="yourTestId" />);
|
|
830
|
-
* expect(screen.getByTestId("yourTestId")).toBeInTheDocument();
|
|
831
|
-
* });
|
|
832
|
-
* ...
|
|
833
|
-
* @example
|
|
834
|
-
* ...
|
|
835
|
-
* it("should allow renderHook", async () => {
|
|
836
|
-
* const { result } = await trackunitProviders().oemBrandingContext(yourPartialOemBrandingMock).renderHook(() => useYourTestHook());
|
|
837
|
-
* expect(result.current).toEqual(anything());
|
|
838
|
-
* });
|
|
839
|
-
* ...
|
|
840
|
-
* @param oemBrandingContext - Override the default context.
|
|
841
|
-
*/
|
|
842
|
-
oemBrandingContext(oemBrandingContext) {
|
|
843
|
-
this.selectedOemBrandingContext = { ...mockOemBrandingContext, ...oemBrandingContext };
|
|
844
|
-
return this;
|
|
845
|
-
}
|
|
846
|
-
/**
|
|
847
|
-
* Use this ToastContext with the given mocks.
|
|
848
|
-
* Defaults to mockToastContext.
|
|
849
|
-
*
|
|
850
|
-
* This context is used by the useToast hook from lib "@trackunit/react-core-hooks"
|
|
851
|
-
*
|
|
852
|
-
* @see mockToastContext
|
|
853
|
-
* @example
|
|
854
|
-
* ...
|
|
855
|
-
* it("should allow render", async () => {
|
|
856
|
-
* await trackunitProviders().toast(yourPartialToastMock).render(<YourTestComponent data-testid="yourTestId" />);
|
|
857
|
-
* expect(screen.getByTestId("yourTestId")).toBeInTheDocument();
|
|
858
|
-
* });
|
|
859
|
-
* ...
|
|
860
|
-
* @example
|
|
861
|
-
* ...
|
|
862
|
-
* it("should allow renderHook", async () => {
|
|
863
|
-
* const { result } = await trackunitProviders().toast(yourPartialToastMock).renderHook(() => useYourTestHook());
|
|
864
|
-
* expect(result.current).toEqual(anything());
|
|
865
|
-
* });
|
|
866
|
-
* ...
|
|
867
|
-
* @param toastContext - Override the default toast context.
|
|
868
|
-
*/
|
|
869
|
-
toast(toastContext) {
|
|
870
|
-
this.selectedToastContext = { ...mockToastContext, ...toastContext };
|
|
871
|
-
return this;
|
|
872
|
-
}
|
|
873
|
-
/**
|
|
874
|
-
* confirmationDialog
|
|
875
|
-
*/
|
|
876
|
-
confirmationDialog(confirmationDialog) {
|
|
877
|
-
this.selectedConfirmationDialogContext = { ...mockConfirmationDialogContext, ...confirmationDialog };
|
|
878
|
-
return this;
|
|
879
|
-
}
|
|
880
|
-
/**
|
|
881
|
-
* modalDialog
|
|
882
|
-
*/
|
|
883
|
-
modalDialog(modalDialog) {
|
|
884
|
-
this.selectedModalDialogContext = { ...mockModalDialogContext, ...modalDialog };
|
|
885
|
-
return this;
|
|
886
|
-
}
|
|
887
|
-
/**
|
|
888
|
-
* errorHandler
|
|
889
|
-
*/
|
|
890
|
-
errorHandler(errorHandler) {
|
|
891
|
-
this.selectedErrorHandler = { ...mockErrorHandlerContext, ...errorHandler };
|
|
892
|
-
return this;
|
|
893
|
-
}
|
|
894
|
-
/**
|
|
895
|
-
* Use this token.
|
|
896
|
-
*
|
|
897
|
-
* This context is used by the useToken hook from lib "@trackunit/react-core-hooks"
|
|
898
|
-
*
|
|
899
|
-
* @example
|
|
900
|
-
* ...
|
|
901
|
-
* it("should allow render", async () => {
|
|
902
|
-
* await trackunitProviders().token(yourMockedToken).render(<YourTestComponent data-testid="yourTestId" />);
|
|
903
|
-
* expect(screen.getByTestId("yourTestId")).toBeInTheDocument();
|
|
904
|
-
* });
|
|
905
|
-
* ...
|
|
906
|
-
* @example
|
|
907
|
-
* ...
|
|
908
|
-
* it("should allow renderHook", async () => {
|
|
909
|
-
* const { result } = await trackunitProviders().token(yourMockedToken).renderHook(() => useYourTestHook());
|
|
910
|
-
* expect(result.current).toEqual(anything());
|
|
911
|
-
* });
|
|
912
|
-
* ...
|
|
913
|
-
* @param token - The token to use.
|
|
914
|
-
* @returns { TrackunitProvidersMockBuilder } - The builder.
|
|
915
|
-
*/
|
|
916
|
-
token(token) {
|
|
917
|
-
this.selectedTokenContext = { token };
|
|
918
|
-
return this;
|
|
919
|
-
}
|
|
920
|
-
/**
|
|
921
|
-
* Use this Router Props with the given mocks.
|
|
922
|
-
*
|
|
923
|
-
* This is used to provide a MemoryRouter from lib "@tanstack/react-router"
|
|
924
|
-
*
|
|
925
|
-
* @example
|
|
926
|
-
* ...
|
|
927
|
-
* it("should allow render", async () => {
|
|
928
|
-
* await trackunitProviders().routerProps(yourRouterPropsMock).render(<YourTestComponent data-testid="yourTestId" />);
|
|
929
|
-
* expect(screen.getByTestId("yourTestId")).toBeInTheDocument();
|
|
930
|
-
* });
|
|
931
|
-
* ...
|
|
932
|
-
* @example
|
|
933
|
-
* ...
|
|
934
|
-
* it("should allow renderHook", async () => {
|
|
935
|
-
* const { result } = await trackunitProviders().routerProps(yourRouterPropsMock).renderHook(() => useYourTestHook());
|
|
936
|
-
* expect(result.current).toEqual(anything());
|
|
937
|
-
* });
|
|
938
|
-
* ...
|
|
939
|
-
* @param routerProps - The router props to use.
|
|
940
|
-
* @returns { TrackunitProvidersMockBuilder } - The builder.
|
|
941
|
-
*/
|
|
942
|
-
routerProps(routerProps) {
|
|
943
|
-
this.selectedRouterProps = routerProps;
|
|
944
|
-
return this.rootRoute(routerProps.routeTree ? routerProps.routeTree : this.selectedRootRoute);
|
|
945
|
-
}
|
|
946
|
-
/**
|
|
947
|
-
* Use this Manager Apollo Context Provider with the given mocks.
|
|
948
|
-
*
|
|
949
|
-
* This context is used by the useQuery and useLazyQuery hook from lib "@apollo/client"
|
|
950
|
-
*
|
|
951
|
-
* @see https://www.apollographql.com/docs/react/development-testing/testing
|
|
952
|
-
* @example
|
|
953
|
-
* ...
|
|
954
|
-
* it("should allow render", async () => {
|
|
955
|
-
* await trackunitProviders().apollo([yourApolloMocks]).render(<YourTestComponent data-testid="yourTestId" />);
|
|
956
|
-
* expect(screen.getByTestId("yourTestId")).toBeInTheDocument();
|
|
957
|
-
* });
|
|
958
|
-
* ...
|
|
959
|
-
* @example
|
|
960
|
-
* ...
|
|
961
|
-
* it("should allow renderHook", async () => {
|
|
962
|
-
* const { result } = await trackunitProviders().apollo([yourApolloMocks]).renderHook(() => useYourTestHook());
|
|
963
|
-
* expect(result.current).toEqual(anything());
|
|
964
|
-
* });
|
|
965
|
-
* ...
|
|
966
|
-
* @param apolloMocks - The mocks to use for the ApolloProvider.
|
|
967
|
-
*/
|
|
968
|
-
apollo(apolloMocks) {
|
|
969
|
-
this.selectedApolloMocks = apolloMocks || [];
|
|
970
|
-
return this;
|
|
971
|
-
}
|
|
972
|
-
/**
|
|
973
|
-
* Validate the mocks that has been supplied to make sure they make sense.
|
|
974
|
-
* Note: This function is overridden in builders extending this one.
|
|
975
|
-
*
|
|
976
|
-
* @returns {boolean} true or throws error if any invalid mocks
|
|
977
|
-
*/
|
|
978
|
-
validateSuppliedMocks() {
|
|
979
|
-
return true;
|
|
980
|
-
}
|
|
981
|
-
rootRoute(rootRoute) {
|
|
982
|
-
this.selectedRootRoute = rootRoute;
|
|
983
|
-
return this;
|
|
984
|
-
}
|
|
985
|
-
/**
|
|
986
|
-
* Make sure this represent the same structure as the main index.tsx does.
|
|
987
|
-
*
|
|
988
|
-
* @param testChildren - the child element being tested.
|
|
989
|
-
*/
|
|
990
|
-
getMockedCompositionRoot(testChildren) {
|
|
991
|
-
return (jsx(ErrorHandlingContextProvider, { value: this.selectedErrorHandler, children: jsx(CurrentUserProvider, { value: this.selectedCurrentUserContext, children: jsx(AnalyticsContext.Provider, { value: this.selectedAnalyticsContext, children: jsx(UserSubscriptionProvider, { value: this.selectedUserSubscriptionContext, children: jsx(OemBrandingContextProvider, { value: this.selectedOemBrandingContext, children: jsx(TokenProvider, { value: this.selectedTokenContext, children: jsx(ToastProvider, { value: this.selectedToastContext, children: jsx(ConfirmationDialogProvider, { value: this.selectedConfirmationDialogContext, children: jsx(FilterBarProvider, { value: this.selectedFilterBarValues, children: jsx(ExportDataContext.Provider, { value: this.selectedExportDataContext, children: jsx(AssetSortingProvider, { value: this.selectedAssetSortingContext, children: jsx(ApolloMockedProviderWithError, { addTypename: false, mocks: this.selectedApolloMocks, children: jsx(NavigationContextProvider, { value: this.selectedNavigationContext, children: jsx(CurrentUserPreferenceProvider, { value: this.selectedCurrentUserPreferenceContext, children: jsx(EnvironmentContextProvider, { value: this.selectedEnvironmentContext, children: jsx(ModalDialogContextProvider, { value: this.selectedModalDialogContext, children: jsx(TimeRangeProvider, { value: this.selectedTimeRangeContext, children: jsx(WidgetConfigProvider, { value: this.selectedWidgetConfigContext, children: testChildren }) }) }) }) }) }) }) }) }) }) }) }) }) }) }) }) }) }));
|
|
992
|
-
}
|
|
993
|
-
getMockedCompositionRootWithRouter(testChildren) {
|
|
994
|
-
const childrenWithRouter = (jsx(RouterContainer, { addTestRootContainer: true, rootRoute: this.selectedRootRoute, selectedRouterProps: this.selectedRouterProps, children: testChildren }));
|
|
995
|
-
return this.getMockedCompositionRoot(childrenWithRouter);
|
|
996
|
-
}
|
|
997
|
-
/**
|
|
998
|
-
* This will return the mocked composition root.
|
|
999
|
-
*/
|
|
1000
|
-
async renderHook(callback, parentElement) {
|
|
1001
|
-
this.validateSuppliedMocks();
|
|
1002
|
-
// This ensures correct act loading when using hooks and not loaded if this build is used for storybook
|
|
1003
|
-
const hookRenderer = await import('./HookRenderer.esm.js');
|
|
1004
|
-
let rerenderCounter = 0;
|
|
1005
|
-
const renderedHook = await hookRenderer.reactHooksRenderHook(callback, children => this.getMockedCompositionRoot(jsx(RerenderProvider, { counter: rerenderCounter, children: jsx(RouterContainer, { addTestRootContainer: true, rootRoute: this.selectedRootRoute, selectedRouterProps: this.selectedRouterProps, children: jsx(RerenderComponent, { children: parentElement ? parentElement(children) : children }) }) })));
|
|
1006
|
-
return {
|
|
1007
|
-
...renderedHook,
|
|
1008
|
-
rerender: async (props) => {
|
|
1009
|
-
rerenderCounter += 1;
|
|
1010
|
-
renderedHook.rerender(props);
|
|
1011
|
-
},
|
|
1012
|
-
};
|
|
1013
|
-
}
|
|
1014
|
-
/**
|
|
1015
|
-
* This will use react-testing-library.render the child in the correct mocked hierarchy of context providers.
|
|
1016
|
-
*
|
|
1017
|
-
* @see https://testing-library.com/docs/react-testing-library/api#render
|
|
1018
|
-
* @param child - the child element being tested.
|
|
1019
|
-
*/
|
|
1020
|
-
async render(child) {
|
|
1021
|
-
this.validateSuppliedMocks();
|
|
1022
|
-
let mountedcomponent;
|
|
1023
|
-
await act(async () => {
|
|
1024
|
-
mountedcomponent = render(child, {
|
|
1025
|
-
wrapper: ({ children }) => this.getMockedCompositionRootWithRouter(children),
|
|
1026
|
-
});
|
|
1027
|
-
await flushPromises();
|
|
1028
|
-
});
|
|
1029
|
-
await act(async () => {
|
|
1030
|
-
await flushPromises();
|
|
1031
|
-
});
|
|
1032
|
-
await act(async () => {
|
|
1033
|
-
await flushPromises();
|
|
1034
|
-
});
|
|
1035
|
-
return mountedcomponent;
|
|
1036
|
-
}
|
|
1037
|
-
/**
|
|
1038
|
-
* Test that a hook can handle rerenders with the same props and returns a stable result.
|
|
1039
|
-
* This is useful for testing that hooks properly memoize their results.
|
|
1040
|
-
* Returns true if the hook result is referentially stable after rerender.
|
|
1041
|
-
* Uses Object.is() for comparison to match Jest's toBe() behavior exactly.
|
|
1042
|
-
*
|
|
1043
|
-
* **Requirements:**
|
|
1044
|
-
* - The hook must return a non-null, non-undefined value
|
|
1045
|
-
* - If the hook returns null or undefined, the test will throw an error
|
|
1046
|
-
* - This ensures the test is actually verifying stability of a meaningful result
|
|
1047
|
-
*
|
|
1048
|
-
* @example
|
|
1049
|
-
* ```ts
|
|
1050
|
-
* expect(await trackunitProviders().verifyHookStability(() =>
|
|
1051
|
-
* useAssetMetadataChartData({
|
|
1052
|
-
* filters: {},
|
|
1053
|
-
* selectedChartOption: "metadataCompleteness",
|
|
1054
|
-
* })
|
|
1055
|
-
* )).toBe(true);
|
|
1056
|
-
* ```
|
|
1057
|
-
* @param callback - The hook to test
|
|
1058
|
-
* @param parentElement - Optional parent element wrapper
|
|
1059
|
-
* @throws Error if the hook result is undefined or null (to ensure meaningful stability testing)
|
|
1060
|
-
* @returns {boolean} true if the result is referentially stable after rerender (using Object.is()), false otherwise
|
|
1061
|
-
*/
|
|
1062
|
-
async verifyHookStability(callback, parentElement) {
|
|
1063
|
-
const { result, rerender } = await this.renderHook(callback, parentElement);
|
|
1064
|
-
// Wait for effects to settle after initial render
|
|
1065
|
-
await flushPromisesInAct();
|
|
1066
|
-
const initial = result.current;
|
|
1067
|
-
await rerender();
|
|
1068
|
-
// Wait for effects to settle after rerender
|
|
1069
|
-
await flushPromisesInAct();
|
|
1070
|
-
const updated = result.current;
|
|
1071
|
-
if (updated === undefined || updated === null) {
|
|
1072
|
-
throw new Error("Updated result is undefined or null, so the test is not testing anything");
|
|
1073
|
-
}
|
|
1074
|
-
return Object.is(updated, initial);
|
|
1075
|
-
}
|
|
1076
|
-
/**
|
|
1077
|
-
* This will return the children in the correct mocked hierarchy of context providers.
|
|
1078
|
-
*/
|
|
1079
|
-
storybook(child) {
|
|
1080
|
-
return this.getMockedCompositionRoot(child);
|
|
1081
|
-
}
|
|
1082
|
-
}
|
|
1083
|
-
/**
|
|
1084
|
-
* This is the default mock builder for the TrackunitProviders.
|
|
1085
|
-
*/
|
|
1086
|
-
const trackunitProviders = () => new TrackunitProvidersMockBuilder();
|
|
1087
|
-
|
|
1088
|
-
/**
|
|
1089
|
-
* Differentiate between the first and subsequent renders.
|
|
1090
|
-
*
|
|
1091
|
-
* @returns {boolean} Returns true if it is the first render, false otherwise.
|
|
1092
|
-
*/
|
|
1093
|
-
const useIsFirstRender = () => {
|
|
1094
|
-
const [isFirstRender, setIsFirstRender] = useState(true);
|
|
1095
|
-
useEffect(() => {
|
|
1096
|
-
setIsFirstRender(false);
|
|
1097
|
-
}, []);
|
|
1098
|
-
return isFirstRender;
|
|
1099
|
-
};
|
|
1100
|
-
|
|
1101
|
-
/**
|
|
1102
|
-
* Logs props that have changed.
|
|
1103
|
-
* Use this for debugging which props force a component to re-render.
|
|
1104
|
-
* This is a hook version of the class component lifecycle method `componentDidUpdate`.
|
|
1105
|
-
* ALWAYS wrap in your own object.
|
|
1106
|
-
*
|
|
1107
|
-
* @param id optional id to use for logging or it will guess the id from the stack trace
|
|
1108
|
-
* @param propsToWatch all the props to watch for changes
|
|
1109
|
-
* @param dontLogReRender if true, will not log the re-render message nice if you have a lot of re-renders
|
|
1110
|
-
* @example
|
|
1111
|
-
* const propsToWatch = { foo: props.foo, bar: props.bar };
|
|
1112
|
-
* useDebugger(propsToWatch);
|
|
1113
|
-
*/
|
|
1114
|
-
const useDebugger = (propsToWatch, id, dontLogReRender) => {
|
|
1115
|
-
const prevPropsRef = useRef(propsToWatch);
|
|
1116
|
-
const uniqueId = useMemo(() => {
|
|
1117
|
-
let stackId = id || (propsToWatch && propsToWatch.id);
|
|
1118
|
-
const stack = new Error().stack;
|
|
1119
|
-
if (!stackId && stack) {
|
|
1120
|
-
const stackLines = stack.split("\n");
|
|
1121
|
-
for (let i = 0; i < stackLines.length; i++) {
|
|
1122
|
-
const stackLine = stackLines[i];
|
|
1123
|
-
if (stackLine?.includes("useDebugger")) {
|
|
1124
|
-
stackId = stackLines[i + 1]?.trim().split(" ")[1];
|
|
1125
|
-
break;
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
|
-
return stackId || "unknown-id";
|
|
1130
|
-
}, [id, propsToWatch]);
|
|
1131
|
-
const isFirstRender = useIsFirstRender();
|
|
1132
|
-
if (isFirstRender) {
|
|
1133
|
-
// eslint-disable-next-line no-console
|
|
1134
|
-
console.log("First-render", uniqueId, window.location.pathname);
|
|
1135
|
-
}
|
|
1136
|
-
else if (dontLogReRender !== true) {
|
|
1137
|
-
// eslint-disable-next-line no-console
|
|
1138
|
-
console.log("Re-render", uniqueId, window.location.pathname);
|
|
1139
|
-
}
|
|
1140
|
-
useEffect(() => {
|
|
1141
|
-
const changedProps = Object.entries(propsToWatch || {}).reduce((result, [key, value]) => {
|
|
1142
|
-
if (prevPropsRef.current && prevPropsRef.current[key] !== value) {
|
|
1143
|
-
result[key + ""] = [prevPropsRef.current[key], value];
|
|
1144
|
-
}
|
|
1145
|
-
return result;
|
|
1146
|
-
}, {});
|
|
1147
|
-
if (objectKeys(changedProps).length > 0) {
|
|
1148
|
-
objectKeys(changedProps).forEach(changedProp => {
|
|
1149
|
-
// eslint-disable-next-line no-console
|
|
1150
|
-
console.log(`${uniqueId} changed property: ${changedProp}`);
|
|
1151
|
-
// JSON stringify is used to avoid console.table from logging the object reference
|
|
1152
|
-
const result = JSON.parse(safeStringify(changedProps[changedProp]));
|
|
1153
|
-
const result0 = result[0];
|
|
1154
|
-
const result1 = result[1];
|
|
1155
|
-
result0 &&
|
|
1156
|
-
typeof result0 === "object" &&
|
|
1157
|
-
objectKeys(result0).forEach(prop => {
|
|
1158
|
-
result0[prop] = typeof result0[prop] === "object" ? JSON.stringify(result0[prop]) : result0[prop];
|
|
1159
|
-
});
|
|
1160
|
-
result1 &&
|
|
1161
|
-
typeof result1 === "object" &&
|
|
1162
|
-
objectKeys(result1).forEach(prop => {
|
|
1163
|
-
result1[prop] = typeof result1[prop] === "object" ? JSON.stringify(result1[prop]) : result1[prop];
|
|
1164
|
-
});
|
|
1165
|
-
// eslint-disable-next-line no-console
|
|
1166
|
-
console.table([result0, result1]);
|
|
1167
|
-
});
|
|
1168
|
-
// eslint-disable-next-line no-console
|
|
1169
|
-
console.dir(changedProps);
|
|
1170
|
-
}
|
|
1171
|
-
prevPropsRef.current = propsToWatch;
|
|
1172
|
-
}, [propsToWatch, uniqueId]);
|
|
1173
|
-
};
|
|
1174
|
-
/**
|
|
1175
|
-
* Debugger component for debugging state changes and re-renders.
|
|
1176
|
-
*
|
|
1177
|
-
* This component will log when it is mounted, re-renders or unmounted.
|
|
1178
|
-
* It will also log when any of its props change.
|
|
1179
|
-
*
|
|
1180
|
-
* @param id optional id to use for logging
|
|
1181
|
-
* @param stop if true, will stop execution and open debugger
|
|
1182
|
-
* @param logPropsChanges optional object with props to watch for changes
|
|
1183
|
-
* @param children the children to render
|
|
1184
|
-
*/
|
|
1185
|
-
const Debugger = ({ id, logPropsChanges, stop, children, }) => {
|
|
1186
|
-
const uniqueId = id ||
|
|
1187
|
-
// @ts-ignore
|
|
1188
|
-
React["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]?.ReactCurrentOwner?.current?._debugOwner?.type?.name ||
|
|
1189
|
-
new Error().stack?.split("\n")[2]?.trim() ||
|
|
1190
|
-
"unknown-id";
|
|
1191
|
-
useDebugger(logPropsChanges || {}, id);
|
|
1192
|
-
const uniqueIdRef = useRef(uniqueId);
|
|
1193
|
-
useEffect(() => {
|
|
1194
|
-
const currentUniqueId = uniqueIdRef.current;
|
|
1195
|
-
// eslint-disable-next-line no-console
|
|
1196
|
-
console.log(`${currentUniqueId} Debugger is mounting`);
|
|
1197
|
-
return () => {
|
|
1198
|
-
// eslint-disable-next-line no-console
|
|
1199
|
-
console.log(`${currentUniqueId} Debugger is unmounting`);
|
|
1200
|
-
};
|
|
1201
|
-
}, []);
|
|
1202
|
-
if (stop === true) {
|
|
1203
|
-
// eslint-disable-next-line no-debugger
|
|
1204
|
-
debugger;
|
|
1205
|
-
}
|
|
1206
|
-
return jsx("div", { className: "Debugger", children: children });
|
|
1207
|
-
};
|
|
1208
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1209
|
-
const safeStringify = (obj) => {
|
|
1210
|
-
const seen = new WeakSet();
|
|
1211
|
-
return JSON.stringify(obj, function (key, value) {
|
|
1212
|
-
if (typeof value === "object" && value !== null) {
|
|
1213
|
-
if (seen.has(value)) {
|
|
1214
|
-
return undefined; // Omit circular reference
|
|
1215
|
-
}
|
|
1216
|
-
seen.add(value);
|
|
1217
|
-
}
|
|
1218
|
-
return value;
|
|
1219
|
-
});
|
|
1220
|
-
};
|
|
1221
|
-
|
|
1222
|
-
/**
|
|
1223
|
-
*
|
|
1224
|
-
* @param document Document that represents the specific GQL query / mutation schema.
|
|
1225
|
-
* @param variables Variables that should be passed to the query / mutation.
|
|
1226
|
-
* Note that an *exact* match between the mock and operation is necessary.
|
|
1227
|
-
* @param data Data object to be returned.
|
|
1228
|
-
* Note that *all* properties should be given a value, use `null` in place of `undefined`,
|
|
1229
|
-
* otherwise nothing will be returned.
|
|
1230
|
-
* @param error ApolloError object to be returned.
|
|
1231
|
-
* @returns {MockedResponse} with data attached, this response can be passed to the mocked ApolloProvider.
|
|
1232
|
-
* @see [Testing React components using MockedProvider and associated APIs](https://www.apollographql.com/docs/react/development-testing/testing/)
|
|
1233
|
-
* @example
|
|
1234
|
-
* it("should show the brand fetched from graphql", async () => {
|
|
1235
|
-
* const mock = queryFor(GetDemoAssetDocument, {
|
|
1236
|
-
* assetId: "assetId",
|
|
1237
|
-
* });
|
|
1238
|
-
*
|
|
1239
|
-
* AssetRuntime.getAssetInfo = jest.fn().mockResolvedValue({ assetId: "assetId" });
|
|
1240
|
-
* await trackunitProviders()
|
|
1241
|
-
* .apollo([mock])
|
|
1242
|
-
* .render(<App />);
|
|
1243
|
-
*
|
|
1244
|
-
* # mock.data is the combined result of what is passed in from queryFor and what is generated by generateMockData
|
|
1245
|
-
* expect(screen.getByText(`Brand: ${mock.data.asset?.brand}`)).toBeInTheDocument();
|
|
1246
|
-
* });
|
|
1247
|
-
*/
|
|
1248
|
-
const queryFor = (document, variables, data, error, maxUsageCount = 1) => {
|
|
1249
|
-
return {
|
|
1250
|
-
request: {
|
|
1251
|
-
query: document,
|
|
1252
|
-
variables,
|
|
1253
|
-
},
|
|
1254
|
-
data,
|
|
1255
|
-
maxUsageCount,
|
|
1256
|
-
newData: () => {
|
|
1257
|
-
if (process.env.VSCODE_INSPECTOR_OPTIONS || process.env.DEBUG) {
|
|
1258
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1259
|
-
const name = document.definitions[0].name.value;
|
|
1260
|
-
// eslint-disable-next-line no-console
|
|
1261
|
-
console.log("Found Response for: " +
|
|
1262
|
-
name +
|
|
1263
|
-
" for variables: " +
|
|
1264
|
-
JSON.stringify(variables, null, 2) +
|
|
1265
|
-
" Returning: " +
|
|
1266
|
-
"{ data: " +
|
|
1267
|
-
JSON.stringify(data, null, 2) +
|
|
1268
|
-
", error: " +
|
|
1269
|
-
JSON.stringify(error, null, 2) +
|
|
1270
|
-
"}");
|
|
1271
|
-
}
|
|
1272
|
-
return {
|
|
1273
|
-
data,
|
|
1274
|
-
errors: error ? [new GraphQLError(error.message)] : undefined,
|
|
1275
|
-
};
|
|
1276
|
-
},
|
|
1277
|
-
};
|
|
1278
|
-
};
|
|
1279
|
-
/**
|
|
1280
|
-
*
|
|
1281
|
-
* @param document Document that represents the specific GQL query / mutation schema.
|
|
1282
|
-
* @param variables Variables that should be passed to the query / mutation.
|
|
1283
|
-
* Note that an *exact* match between the mock and operation is necessary.
|
|
1284
|
-
* @param data Data object to be returned.
|
|
1285
|
-
* Note that *all* properties should be given a value, use `null` in place of `undefined`,
|
|
1286
|
-
* otherwise nothing will be returned.
|
|
1287
|
-
* @param error ApolloError object to be returned.
|
|
1288
|
-
* @returns {MockedResponse} that can be passed to the mocked ApolloProvider.
|
|
1289
|
-
* @see [Testing React components using MockedProvider and associated APIs](https://www.apollographql.com/docs/react/development-testing/testing/)
|
|
1290
|
-
*/
|
|
1291
|
-
const queryForHook = (hookFn, document, variables, data, error) => {
|
|
1292
|
-
return {
|
|
1293
|
-
request: {
|
|
1294
|
-
query: document,
|
|
1295
|
-
variables,
|
|
1296
|
-
},
|
|
1297
|
-
newData: () => {
|
|
1298
|
-
if (process.env.VSCODE_INSPECTOR_OPTIONS || process.env.DEBUG) {
|
|
1299
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1300
|
-
const name = document.definitions[0].name.value;
|
|
1301
|
-
// eslint-disable-next-line no-console
|
|
1302
|
-
console.log("Found Response for: " +
|
|
1303
|
-
name +
|
|
1304
|
-
" for variables: " +
|
|
1305
|
-
JSON.stringify(variables, null, 2) +
|
|
1306
|
-
" Returning: " +
|
|
1307
|
-
"{ data: " +
|
|
1308
|
-
JSON.stringify(data, null, 2) +
|
|
1309
|
-
", error: " +
|
|
1310
|
-
JSON.stringify(error, null, 2) +
|
|
1311
|
-
"}");
|
|
1312
|
-
}
|
|
1313
|
-
return {
|
|
1314
|
-
data,
|
|
1315
|
-
errors: error ? [new GraphQLError(error.message)] : undefined,
|
|
1316
|
-
};
|
|
1317
|
-
},
|
|
1318
|
-
};
|
|
1319
|
-
};
|
|
1320
|
-
|
|
1321
|
-
/**
|
|
1322
|
-
* This helps validate the IrisApp is exposed correctly it must expose:
|
|
1323
|
-
* - bootstrap
|
|
1324
|
-
* - mount
|
|
1325
|
-
* - unmount
|
|
1326
|
-
* According to the single spa spec.
|
|
1327
|
-
*
|
|
1328
|
-
* Your test could look like this
|
|
1329
|
-
*
|
|
1330
|
-
* @example
|
|
1331
|
-
* import * as IrisApp from "./index";
|
|
1332
|
-
describe("App", () => {
|
|
1333
|
-
it("Should validate", async () => {
|
|
1334
|
-
const result = await validateIrisApp(IrisApp);
|
|
1335
|
-
expect(result).toBeNull();
|
|
1336
|
-
});
|
|
1337
|
-
});
|
|
1338
|
-
* @param irisApp Import the index ts(x) file as above and pass it in.
|
|
1339
|
-
* @returns {null|string} if everything is good - otherwise a string telling you what is wrong.
|
|
1340
|
-
*/
|
|
1341
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1342
|
-
const validateIrisApp = async (irisApp) => {
|
|
1343
|
-
if (!irisApp.bootstrap || typeof irisApp.bootstrap !== "function") {
|
|
1344
|
-
return "Missing a bootstrap function";
|
|
1345
|
-
}
|
|
1346
|
-
if (!irisApp.mount || typeof irisApp.mount !== "function") {
|
|
1347
|
-
return "Missing a mount function";
|
|
1348
|
-
}
|
|
1349
|
-
if (!irisApp.unmount || typeof irisApp.unmount !== "function") {
|
|
1350
|
-
return "Missing an unmount function";
|
|
1351
|
-
}
|
|
1352
|
-
if (irisApp.update && typeof irisApp.update !== "function") {
|
|
1353
|
-
return "Update must be a function";
|
|
1354
|
-
}
|
|
1355
|
-
return null;
|
|
1356
|
-
};
|
|
1357
|
-
|
|
1358
|
-
export { Debugger, TrackunitProvidersMockBuilder, doNothing, flushPromises, flushPromisesInAct, mockAnalyticsContext, mockAssetSortingContext, mockCurrentUserContext, mockEnvironmentContext, mockFilterBarContext, mockOemBrandingContext, mockToastContext, mockUserSubscriptionContext, queryFor, queryForHook, trackunitProviders, useDebugger, validateIrisApp };
|
|
1
|
+
export { D as Debugger, T as TrackunitProvidersMockBuilder, k as doNothing, f as flushPromises, b as flushPromisesInAct, m as mockAnalyticsContext, c as mockAssetSortingContext, d as mockCurrentUserContext, e as mockEnvironmentContext, g as mockFilterBarContext, h as mockOemBrandingContext, i as mockToastContext, j as mockUserSubscriptionContext, q as queryFor, l as queryForHook, t as trackunitProviders, u as useDebugger, v as validateIrisApp } from './index.esm2.js';
|
|
2
|
+
import '@trackunit/iris-app-runtime-core-api';
|
|
3
|
+
import 'react/jsx-runtime';
|
|
4
|
+
import 'react';
|
|
5
|
+
import 'react-dom/test-utils';
|
|
6
|
+
import 'react-dom';
|
|
7
|
+
import 'react-dom/client';
|
|
8
|
+
import '@trackunit/react-core-hooks';
|
|
9
|
+
import 'es-toolkit';
|
|
10
|
+
import '@apollo/client';
|
|
11
|
+
import '@apollo/client/dev';
|
|
12
|
+
import '@apollo/client/link/error';
|
|
13
|
+
import '@apollo/client/testing';
|
|
14
|
+
import '@trackunit/shared-utils';
|
|
15
|
+
import '@apollo/client/react';
|
|
16
|
+
import '@tanstack/react-router';
|
|
17
|
+
import 'graphql';
|