Skip to content

Commit 622dfb7

Browse files
authored
fix(aurora): pass router as prop to AuthProvider to avoid useRouter warning (#1032)
- AuthProvider now accepts router as a prop instead of calling useRouter() internally - This fixes the warning 'useRouter must be used inside a <RouterProvider>' - Updated tests to pass mock router - Added autocomplete attributes to login form inputs for better UX
1 parent 9a11c32 commit 622dfb7

5 files changed

Lines changed: 31 additions & 14 deletions

File tree

packages/aurora/src/client/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ const App = (props: AppProps) => {
9090
<AppShellProvider shadowRoot={false} theme={currentTheme}>
9191
<trpcReact.Provider client={reactClient} queryClient={queryClient}>
9292
<QueryClientProvider client={queryClient}>
93-
<AuthProvider>
93+
<AuthProvider router={router}>
9494
<NotificationManager position="top-right" />
9595
<AppInner
9696
router={router}

packages/aurora/src/client/components/navigation/MainNavigation.test.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,14 @@ beforeAll(() => {
2222
}
2323
})
2424

25+
// Mock router for AuthProvider
26+
const mockRouter = {
27+
navigate: vi.fn(),
28+
invalidate: vi.fn(),
29+
}
30+
2531
const TestingProvider = ({ children }: { children: ReactNode }) => (
26-
<AuthProvider>
32+
<AuthProvider router={mockRouter}>
2733
<I18nProvider i18n={i18n}>{children}</I18nProvider>
2834
</AuthProvider>
2935
)

packages/aurora/src/client/routes/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ export function AuthLoginPage() {
233233
id="user"
234234
type="text"
235235
placeholder={t`Enter your username`}
236+
autoComplete="username"
236237
className={textinputstyles}
237238
onChange={(e) => {
238239
setForm({ ...form, user: e.target.value })
@@ -249,6 +250,7 @@ export function AuthLoginPage() {
249250
<input
250251
id="password"
251252
type="password"
253+
autoComplete="current-password"
252254
required
253255
className={textinputstyles}
254256
onChange={(e) => {

packages/aurora/src/client/store/AuthProvider.test.tsx

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,27 @@ import { renderHook, act } from "@testing-library/react"
33
import { AuthProvider, useAuth } from "./AuthProvider"
44
import type { User } from "./AuthProvider"
55
import { ReactNode } from "react"
6-
import { useRouter } from "@tanstack/react-router"
7-
8-
// Mock router — AuthProvider uses useRouter() internally
9-
vi.mock("../router", () => ({}))
106

117
// Extract the non-null user type
128
type AuthUser = NonNullable<User>
139

14-
const wrapper = ({ children }: { children: ReactNode }) => <AuthProvider>{children}</AuthProvider>
10+
// Mock router object passed as prop
11+
const mockRouter = {
12+
navigate: vi.fn(),
13+
invalidate: vi.fn(),
14+
}
15+
16+
const wrapper = ({ children }: { children: ReactNode }) => <AuthProvider router={mockRouter}>{children}</AuthProvider>
1517

1618
describe("AuthProvider", () => {
1719
beforeEach(() => {
1820
vi.clearAllMocks()
1921
vi.useFakeTimers()
2022

23+
// Reset mock router
24+
mockRouter.navigate.mockClear()
25+
mockRouter.invalidate.mockClear()
26+
2127
// Mock window.location
2228
Object.defineProperty(window, "location", {
2329
value: {
@@ -138,7 +144,7 @@ describe("AuthProvider", () => {
138144
expect(result.current.isAuthenticated).toBe(false)
139145
expect(result.current.user).toBeNull()
140146
expect(result.current.logoutReason).toBe("manual")
141-
expect(useRouter().invalidate).toHaveBeenCalled()
147+
expect(mockRouter.invalidate).toHaveBeenCalled()
142148
})
143149

144150
it("should invalidate router on inactive logout (no modal)", async () => {
@@ -162,7 +168,7 @@ describe("AuthProvider", () => {
162168
expect(result.current.isAuthenticated).toBe(false)
163169
expect(result.current.logoutReason).toBe("inactive")
164170
expect(result.current.showInactivityModal).toBe(false)
165-
expect(useRouter().invalidate).toHaveBeenCalled()
171+
expect(mockRouter.invalidate).toHaveBeenCalled()
166172
})
167173

168174
it("should show modal on expired logout", async () => {
@@ -450,7 +456,7 @@ describe("AuthProvider", () => {
450456
})
451457

452458
expect(result.current.showInactivityModal).toBe(false)
453-
expect(useRouter().navigate).toHaveBeenCalledWith({
459+
expect(mockRouter.navigate).toHaveBeenCalledWith({
454460
to: "/",
455461
search: { redirect: "/dashboard" },
456462
})
@@ -487,7 +493,7 @@ describe("AuthProvider", () => {
487493
result.current.closeInactivityModal()
488494
})
489495

490-
expect(useRouter().navigate).toHaveBeenCalledWith({
496+
expect(mockRouter.navigate).toHaveBeenCalledWith({
491497
to: "/",
492498
search: undefined,
493499
})

packages/aurora/src/client/store/AuthProvider.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React, { useEffect, useRef, useCallback, useState } from "react"
22
import { TokenData } from "../../server/Authentication/types/models"
3-
import { useRouter } from "@tanstack/react-router"
43

54
export type User = TokenData["user"] | null
65

@@ -16,10 +15,14 @@ export interface AuthContext {
1615
redirectAfterModal?: string
1716
}
1817

18+
interface RouterNavigation {
19+
navigate: (options: { to: string; search?: Record<string, unknown> }) => void
20+
invalidate: () => void
21+
}
22+
1923
const AuthContext = React.createContext<AuthContext | null>(null)
2024

21-
export function AuthProvider({ children }: { children: React.ReactNode }) {
22-
const router = useRouter()
25+
export function AuthProvider({ children, router }: { children: React.ReactNode; router: RouterNavigation }) {
2326
const [user, setUser] = React.useState<User | null>(null)
2427
const [expiresAt, setExpiresAt] = React.useState<Date | undefined>(undefined)
2528
const [logoutReason, setLogoutReason] = React.useState<"inactive" | "expired" | "manual" | undefined>(undefined)

0 commit comments

Comments
 (0)