Style/Revamp #4

Merged
me merged 12 commits from feature/home_revamp into main 2026-05-08 03:16:16 +00:00
2 changed files with 115 additions and 115 deletions
Showing only changes of commit 8cca16a0f9 - Show all commits
+100 -100
View File
@@ -3,125 +3,125 @@ import { MemoryRouter, Route, Routes } from "react-router-dom";
import { beforeEach, describe, expect, it } from "vitest"; import { beforeEach, describe, expect, it } from "vitest";
import { mockUser } from "../../test/fixtures/user.fixture"; import { mockUser } from "../../test/fixtures/user.fixture";
import { useAuthStore } from "../store/useAuthStore"; import { useAuthStore } from "../store/useAuthStore";
import { ProtectedRoute, PublicRoute } from "./RouteGuards"; import { ProtectedRoute, AutoRedirectRoute } from "./RouteGuards";
function renderGuard(ui: React.ReactNode, mountPath: "/protected" | "/public") { function renderGuard(ui: React.ReactNode, mountPath: "/protected" | "/public") {
return render( return render(
<MemoryRouter initialEntries={[mountPath]}> <MemoryRouter initialEntries={[mountPath]}>
<Routes> <Routes>
<Route path="/login" element={<div>Login Page</div>} /> <Route path="/login" element={<div>Login Page</div>} />
<Route path="/drawer" element={<div>Drawer Page</div>} /> <Route path="/drawer" element={<div>Drawer Page</div>} />
<Route path="/protected" element={ui} /> <Route path="/protected" element={ui} />
<Route path="/public" element={ui} /> <Route path="/public" element={ui} />
</Routes> </Routes>
</MemoryRouter>, </MemoryRouter>,
); );
} }
beforeEach(() => { beforeEach(() => {
useAuthStore.setState({ useAuthStore.setState({
accessToken: null, accessToken: null,
user: null, user: null,
isInitializing: true, isInitializing: true,
}); });
}); });
describe("ProtectedRoute", () => { describe("ProtectedRoute", () => {
it("should show SplashScreen while auth is initializing", () => { it("should show SplashScreen while auth is initializing", () => {
useAuthStore.setState({ useAuthStore.setState({
isInitializing: true, isInitializing: true,
accessToken: null, accessToken: null,
user: null, user: null,
});
renderGuard(
<ProtectedRoute>
<div>Secret</div>
</ProtectedRoute>,
"/protected",
);
expect(screen.getByText(/Unsealing/i)).toBeInTheDocument();
expect(screen.queryByText("Secret")).not.toBeInTheDocument();
}); });
renderGuard(
<ProtectedRoute>
<div>Secret</div>
</ProtectedRoute>,
"/protected",
);
expect(screen.getByText(/Unsealing/i)).toBeInTheDocument(); it("should redirect unauthenticated users to /login", () => {
expect(screen.queryByText("Secret")).not.toBeInTheDocument(); useAuthStore.setState({
}); isInitializing: false,
accessToken: null,
it("should redirect unauthenticated users to /login", () => { user: null,
useAuthStore.setState({ });
isInitializing: false, renderGuard(
accessToken: null, <ProtectedRoute>
user: null, <div>Secret</div>
</ProtectedRoute>,
"/protected",
);
expect(screen.getByText("Login Page")).toBeInTheDocument();
expect(screen.queryByText("Secret")).not.toBeInTheDocument();
}); });
renderGuard(
<ProtectedRoute>
<div>Secret</div>
</ProtectedRoute>,
"/protected",
);
expect(screen.getByText("Login Page")).toBeInTheDocument();
expect(screen.queryByText("Secret")).not.toBeInTheDocument();
});
it("should render page for authenticated users", () => { it("should render page for authenticated users", () => {
useAuthStore.setState({ useAuthStore.setState({
isInitializing: false, isInitializing: false,
accessToken: "token", accessToken: "token",
user: mockUser, user: mockUser,
});
renderGuard(
<ProtectedRoute>
<div>Secret</div>
</ProtectedRoute>,
"/protected",
);
expect(screen.getByText("Secret")).toBeInTheDocument();
}); });
renderGuard(
<ProtectedRoute>
<div>Secret</div>
</ProtectedRoute>,
"/protected",
);
expect(screen.getByText("Secret")).toBeInTheDocument();
});
}); });
describe("PublicRoute", () => { describe("PublicRoute", () => {
it("should show SplashScreen while auth is initializing", () => { it("should show SplashScreen while auth is initializing", () => {
useAuthStore.setState({ useAuthStore.setState({
isInitializing: true, isInitializing: true,
accessToken: null, accessToken: null,
user: null, user: null,
});
renderGuard(
<AutoRedirectRoute>
<div>Login Page</div>
</AutoRedirectRoute>,
"/public",
);
expect(screen.getByText(/Unsealing/i)).toBeInTheDocument();
expect(screen.queryByText("Login Page")).not.toBeInTheDocument();
}); });
renderGuard(
<PublicRoute>
<div>Login Page</div>
</PublicRoute>,
"/public",
);
expect(screen.getByText(/Unsealing/i)).toBeInTheDocument();
expect(screen.queryByText("Login Page")).not.toBeInTheDocument();
});
it("should redirect authenticated users to /drawer", () => { it("should redirect authenticated users to /drawer", () => {
useAuthStore.setState({ useAuthStore.setState({
isInitializing: false, isInitializing: false,
accessToken: "token", accessToken: "token",
user: mockUser, user: mockUser,
});
renderGuard(
<AutoRedirectRoute>
<div>Login Form</div>
</AutoRedirectRoute>,
"/public",
);
expect(screen.getByText("Drawer Page")).toBeInTheDocument();
expect(screen.queryByText("Login Form")).not.toBeInTheDocument();
}); });
renderGuard(
<PublicRoute>
<div>Login Form</div>
</PublicRoute>,
"/public",
);
expect(screen.getByText("Drawer Page")).toBeInTheDocument();
expect(screen.queryByText("Login Form")).not.toBeInTheDocument();
});
it("should render page for unauthenticated users", () => { it("should render page for unauthenticated users", () => {
useAuthStore.setState({ useAuthStore.setState({
isInitializing: false, isInitializing: false,
accessToken: null, accessToken: null,
user: null, user: null,
});
renderGuard(
<AutoRedirectRoute>
<div>Login Form</div>
</AutoRedirectRoute>,
"/public",
);
expect(screen.getByText("Login Form")).toBeInTheDocument();
}); });
renderGuard(
<PublicRoute>
<div>Login Form</div>
</PublicRoute>,
"/public",
);
expect(screen.getByText("Login Form")).toBeInTheDocument();
});
}); });
+15 -15
View File
@@ -9,30 +9,30 @@ import SplashScreen from "./SplashScreen";
* state so the Login component can link them back after sign-in * state so the Login component can link them back after sign-in
*/ */
export function ProtectedRoute({ children }: { children: React.ReactNode }) { export function ProtectedRoute({ children }: { children: React.ReactNode }) {
const { isAuthenticated, isInitializing } = useAuth(); const { isAuthenticated, isInitializing } = useAuth();
const location = useLocation(); const location = useLocation();
if (isInitializing) return <SplashScreen />; if (isInitializing) return <SplashScreen />;
if (!isAuthenticated) { if (!isAuthenticated) {
return <Navigate to={ROUTES.LOGIN} state={{ from: location }} replace />; return <Navigate to={ROUTES.LOGIN} state={{ from: location }} replace />;
} }
return <>{children}</>; return <>{children}</>;
} }
/** /**
* Public - auth route guard. * Auto-redirect - auth route guard.
* If authenticated, redirect all the auth related flows to the drawer * If authenticated, redirect all the auth related flows to the drawer
*/ */
export function PublicRoute({ children }: { children: React.ReactNode }) { export function AutoRedirectRoute({ children }: { children: React.ReactNode }) {
const { isAuthenticated, isInitializing } = useAuth(); const { isAuthenticated, isInitializing } = useAuth();
if (isInitializing) return <SplashScreen />; if (isInitializing) return <SplashScreen />;
if (isAuthenticated) { if (isAuthenticated) {
return <Navigate to={ROUTES.DRAWER} replace />; return <Navigate to={ROUTES.DRAWER} replace />;
} }
return <>{children}</>; return <>{children}</>;
} }