Skip to content

Commit

Permalink
Fixed tests
Browse files Browse the repository at this point in the history
  • Loading branch information
patricklafrance committed Nov 7, 2023
1 parent eaa5b48 commit f4a2dbd
Show file tree
Hide file tree
Showing 16 changed files with 554 additions and 90 deletions.
4 changes: 3 additions & 1 deletion docs/reference/routing/useIsRouteMatchProtected.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ const isProtected = useIsRouteMatchProtected(locationArg)
### Parameters

- `locationArg`: The location to match the route paths against.
- `options`: An optional object literal of options:
- `throwWhenThereIsNoMatch`: Whether or not to throw an `Error` if no route match `locationArg`.

### Returns

A `boolean` value indicating whether or not the matching route is `protected`. If no route match the given location, an `Error` is thrown.
A `boolean` value indicating whether or not the matching route is `protected`. If `throwWhenThereIsNoMatch` is enabled and no route match the given location, an `Error` is thrown.

## Usage

Expand Down
14 changes: 12 additions & 2 deletions packages/core/src/federation/registerLocalModules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ export interface LocalModuleRegistrationError {

export class LocalModuleRegistry {
#registrationStatus: ModuleRegistrationStatus = "none";

readonly #deferredRegistrations: DeferredRegistration[] = [];
#deferredRegistrations: DeferredRegistration[] = [];

async registerModules<TRuntime extends AbstractRuntime = AbstractRuntime, TContext = unknown, TData = unknown>(registerFunctions: ModuleRegisterFunction<TRuntime, TContext, TData>[], runtime: TRuntime, { context }: RegisterLocalModulesOptions<TContext> = {}) {
const errors: LocalModuleRegistrationError[] = [];
Expand Down Expand Up @@ -109,6 +108,12 @@ export class LocalModuleRegistry {
get registrationStatus() {
return this.#registrationStatus;
}

// Strictly for Jest tests, this is NOT ideal.
__reset() {
this.#registrationStatus = "none";
this.#deferredRegistrations = [];
}
}

const localModuleRegistry = new LocalModuleRegistry();
Expand All @@ -124,3 +129,8 @@ export function completeLocalModuleRegistrations<TRuntime extends AbstractRuntim
export function getLocalModuleRegistrationStatus() {
return localModuleRegistry.registrationStatus;
}

// Strictly for Jest tests, this is NOT ideal.
export function __resetLocalModuleRegistrations() {
localModuleRegistry.__reset();
}
1 change: 1 addition & 0 deletions packages/firefly/jest-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "@testing-library/jest-dom";
3 changes: 2 additions & 1 deletion packages/firefly/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ const config: Config = {
...pathsToModuleNameMapper(compilerOptions.paths, {
prefix: "<rootDir>"
})
}
},
setupFilesAfterEnv: ["<rootDir>/jest-setup.js"]
};

export default config;
1 change: 1 addition & 0 deletions packages/firefly/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"@swc/helpers": "0.5.3",
"@swc/jest": "0.2.29",
"@testing-library/react": "14.0.0",
"@testing-library/jest-dom": "6.1.4",
"@types/jest": "29.5.6",
"@types/react": "18.2.33",
"@types/react-dom": "18.2.14",
Expand Down
43 changes: 16 additions & 27 deletions packages/firefly/src/AppRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import { cloneElement, useCallback, useEffect, useMemo, useState, type ReactElem
import { ErrorBoundary, useErrorBoundary } from "react-error-boundary";
import { Outlet, RouterProvider, createBrowserRouter, useLocation, type RouterProviderProps } from "react-router-dom";

export type OnLoadPublicDataFunction = (signal: AbortSignal) => Promise<unknown>;
export type OnLoadPublicDataFunction = () => Promise<unknown>;

export type OnLoadProtectedDataFunction = (signal: AbortSignal) => Promise<unknown>;
export type OnLoadProtectedDataFunction = () => Promise<unknown>;

export type OnCompleteRegistrationFunction = () => Promise<unknown>;
export type OnCompleteRegistrationsFunction = () => Promise<unknown>;

interface BootstrappingRouteProps {
fallbackElement: ReactElement;
onLoadPublicData?: OnLoadPublicDataFunction;
onLoadProtectedData?: OnLoadProtectedDataFunction;
onCompleteRegistration?: OnCompleteRegistrationFunction;
onCompleteRegistrations?: OnCompleteRegistrationsFunction;
waitForMsw: boolean;
areModulesRegistered: boolean;
areModulesReady: boolean;
Expand All @@ -28,7 +28,7 @@ export function BootstrappingRoute(props: BootstrappingRouteProps) {
fallbackElement,
onLoadPublicData,
onLoadProtectedData,
onCompleteRegistration,
onCompleteRegistrations,
waitForMsw,
areModulesRegistered,
areModulesReady
Expand Down Expand Up @@ -66,9 +66,7 @@ export function BootstrappingRoute(props: BootstrappingRouteProps) {
if (!isPublicDataLoaded) {
logger.debug("[shell] Loading public data.");

const abordController = new AbortController();

onLoadPublicData(abordController.signal)
onLoadPublicData()
.then(() => {
setIsPublicDataLoaded(true);

Expand All @@ -77,16 +75,13 @@ export function BootstrappingRoute(props: BootstrappingRouteProps) {
.catch(error => {
showBoundary(error);
});

return () => {
abordController.abort();
};
}
}
}
}, [logger, areModulesRegistered, areModulesReady, isMswStarted, isPublicDataLoaded, onLoadPublicData]);

const isActiveRouteProtected = useIsRouteMatchProtected(location);
// Only throw when there's no match if the modules has been registered, otherwise it's expected that there are no registered routes.
const isActiveRouteProtected = useIsRouteMatchProtected(location, { throwWhenThereIsNoMatch: areModulesReady });

useEffect(() => {
// Don't go further if no handler has been provided to load protected data.
Expand All @@ -96,9 +91,7 @@ export function BootstrappingRoute(props: BootstrappingRouteProps) {
if (!isProtectedDataLoaded) {
logger.debug(`[shell] Loading protected data as "${location.pathname}" is a protected route.`);

const abordController = new AbortController();

onLoadProtectedData(abordController.signal)
onLoadProtectedData()
.then(() => {
setIsProtectedDataLoaded(true);

Expand All @@ -107,10 +100,6 @@ export function BootstrappingRoute(props: BootstrappingRouteProps) {
.catch(error => {
showBoundary(error);
});

return () => {
abordController.abort();
};
}
} else {
logger.debug(`[shell] Not loading protected data as "${location.pathname}" is a public route.`);
Expand All @@ -121,14 +110,14 @@ export function BootstrappingRoute(props: BootstrappingRouteProps) {

useEffect(() => {
// Don't go further if no handler has been provided to complete the registration.
if (onCompleteRegistration) {
if (onCompleteRegistrations) {
if (areModulesRegistered && isMswStarted && isPublicDataLoaded) {
if (!areModulesReady) {
onCompleteRegistration();
onCompleteRegistrations();
}
}
}
}, [areModulesRegistered, areModulesReady, isMswStarted, isPublicDataLoaded, onCompleteRegistration]);
}, [areModulesRegistered, areModulesReady, isMswStarted, isPublicDataLoaded, onCompleteRegistrations]);

if (!areModulesReady || !isMswStarted || !isPublicDataLoaded || (isActiveRouteProtected && !isProtectedDataLoaded)) {
return fallbackElement;
Expand All @@ -144,7 +133,7 @@ export interface AppRouterProps {
errorElement: ReactElement;
onLoadPublicData?: OnLoadPublicDataFunction;
onLoadProtectedData?: OnLoadProtectedDataFunction;
onCompleteRegistration?: OnCompleteRegistrationFunction;
onCompleteRegistrations?: OnCompleteRegistrationsFunction;
waitForMsw: boolean;
routerProvidersProps?: RouterProviderProps;
}
Expand All @@ -155,7 +144,7 @@ export function AppRouter(props: AppRouterProps) {
errorElement,
onLoadPublicData,
onLoadProtectedData,
onCompleteRegistration,
onCompleteRegistrations,
waitForMsw,
routerProvidersProps = {}
} = props;
Expand Down Expand Up @@ -183,7 +172,7 @@ export function AppRouter(props: AppRouterProps) {
fallbackElement={fallbackElement}
onLoadPublicData={onLoadPublicData}
onLoadProtectedData={onLoadProtectedData}
onCompleteRegistration={onCompleteRegistration}
onCompleteRegistrations={onCompleteRegistrations}
waitForMsw={waitForMsw}
areModulesRegistered={areModulesRegistered}
areModulesReady={areModulesReady}
Expand All @@ -193,7 +182,7 @@ export function AppRouter(props: AppRouterProps) {
children: routes
}
]);
}, [areModulesRegistered, areModulesReady, routes, onLoadPublicData, onLoadProtectedData, onCompleteRegistration, waitForMsw]);
}, [areModulesRegistered, areModulesReady, routes, onLoadPublicData, onLoadProtectedData, onCompleteRegistrations, waitForMsw]);

return (
<RouterProvider {...routerProvidersProps} router={router} />
Expand Down
Loading

0 comments on commit f4a2dbd

Please sign in to comment.