refactor: enforce frontend view model boundaries
This commit is contained in:
@@ -8,9 +8,10 @@ import { RouteErrorBoundary } from "./RouteErrorBoundary";
|
||||
|
||||
const session = { isAuthenticated: false };
|
||||
vi.mock("@/features/auth", () => ({
|
||||
useAuth: () => ((/* eslint-disable unicorn/no-null -- Fixture preserves the production contract’s explicit null values. */
|
||||
{ user: session.isAuthenticated ? {} : null }
|
||||
/* eslint-enable unicorn/no-null */)),
|
||||
/* eslint-disable unicorn/no-null -- Fixture preserves the production contract’s explicit null values. */
|
||||
useAuth: () =>
|
||||
({ user: session.isAuthenticated ? {} : null }),
|
||||
/* eslint-enable unicorn/no-null */
|
||||
}));
|
||||
|
||||
const ThrowingRoute: FC = () => {
|
||||
@@ -39,6 +40,7 @@ const RouteHarness: FC = () => {
|
||||
<button onClick={() => navigate("/healthy")} type="button">
|
||||
go healthy
|
||||
</button>
|
||||
|
||||
<RouteErrorBoundary>
|
||||
<HealthyRoute />
|
||||
</RouteErrorBoundary>
|
||||
@@ -62,10 +64,13 @@ describe("RouteErrorBoundary", () => {
|
||||
async (path) => {
|
||||
session.isAuthenticated = path === "/accounts";
|
||||
let isFailing = true;
|
||||
|
||||
const RecoverableRoute: FC = () => {
|
||||
if (isFailing) throw new Error("temporary failure");
|
||||
|
||||
return <div>recovered route</div>;
|
||||
};
|
||||
|
||||
render(
|
||||
<MantineProvider>
|
||||
<MemoryRouter initialEntries={[path]}>
|
||||
@@ -116,10 +121,12 @@ describe("RouteErrorBoundary", () => {
|
||||
expect(reload).toHaveAttribute("href", "/login");
|
||||
// Cancel browser navigation in JSDOM only after proving React Router did not intercept it.
|
||||
let isIntercepted = true;
|
||||
|
||||
const preventNavigation = (event: MouseEvent) => {
|
||||
isIntercepted = event.defaultPrevented;
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
document.addEventListener("click", preventNavigation, { once: true });
|
||||
fireEvent.click(reload);
|
||||
expect(isIntercepted).toBe(false);
|
||||
|
||||
@@ -33,7 +33,13 @@ class Boundary extends Component<BoundaryProps, State> {
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.state.hasError ? <RouteErrorFallback authenticated={this.props.authenticated} /> : this.props.children;
|
||||
return this.state.hasError
|
||||
? (
|
||||
<RouteErrorFallback authenticated={this.props.authenticated} />
|
||||
)
|
||||
: (
|
||||
this.props.children
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,10 +52,13 @@ const RouteErrorFallback: FC<RouteErrorFallbackProps> = (props) => {
|
||||
return (
|
||||
<Stack>
|
||||
<Title order={1}>{t("routeError.title")}</Title>
|
||||
|
||||
<Text>{t("routeError.text")}</Text>
|
||||
|
||||
<Button component={Link} to={to}>
|
||||
{t("routeError.action")}
|
||||
</Button>
|
||||
|
||||
<Button component="a" href={to} variant="default">
|
||||
{t("routeError.reload")}
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user