Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ export default function DashboardPage() {
>
<p className="font-medium">{recipe.title}</p>
<p className="text-sm text-muted-foreground">
{recipe.calories ? `${Math.round(recipe.calories)} cal` : "N/A"} ·{" "}
{recipe.calories ? `${Math.round(recipe.calories)} cal` : "N/A"} ·{" "}
{recipe.readyInMinutes || "N/A"} min
</p>
</Link>
Expand All @@ -205,4 +205,3 @@ export default function DashboardPage() {
</div>
);
}

9 changes: 5 additions & 4 deletions apps/frontend/src/lib/api/auth.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ interface AuthResponse {
status: string;
data: {
user: User;
session: {
access_token: string;
refresh_token: string;
expires_at: number;
tokens: {
accessToken: string;
refreshToken: string;
expiresIn: number;
expiresAt: number;
};
};
error: null;
Expand Down
129 changes: 129 additions & 0 deletions apps/frontend/src/lib/hooks/use-auth.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import React, { type ReactNode } from "react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { renderHook, waitFor } from "@testing-library/react";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { useAuth } from "./use-auth";

const {
clearAuthMock,
loginMock,
pushMock,
setAuthMock,
signupMock,
toastSuccessMock,
} = vi.hoisted(() => ({
clearAuthMock: vi.fn(),
loginMock: vi.fn(),
pushMock: vi.fn(),
setAuthMock: vi.fn(),
signupMock: vi.fn(),
toastSuccessMock: vi.fn(),
}));

vi.mock("../api/auth.api", () => ({
authApi: {
login: loginMock,
signup: signupMock,
logout: vi.fn(),
getCurrentUser: vi.fn(),
},
}));

vi.mock("../store/auth-store", () => ({
useAuthStore: () => ({
user: null,
setAuth: setAuthMock,
clearAuth: clearAuthMock,
}),
}));

vi.mock("next/navigation", () => ({
useRouter: () => ({
push: pushMock,
}),
}));

vi.mock("sonner", () => ({
toast: {
success: toastSuccessMock,
},
}));

function createWrapper() {
const queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false },
mutations: { retry: false },
},
});

return function Wrapper({ children }: { children: ReactNode }) {
return (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);
};
}

describe("useAuth", () => {
beforeEach(() => {
vi.clearAllMocks();
});

it("stores backend tokens and navigates after login", async () => {
const user = { id: "user-1", email: "test@example.com" };
loginMock.mockResolvedValue({
user,
tokens: {
accessToken: "access-token",
refreshToken: "refresh-token",
expiresIn: 3600,
expiresAt: 123456,
},
});

const { result } = renderHook(() => useAuth(), { wrapper: createWrapper() });

result.current.login({ email: "test@example.com", password: "password123" });

await waitFor(() =>
expect(setAuthMock).toHaveBeenCalledWith(
user,
"access-token",
"refresh-token"
)
);
expect(pushMock).toHaveBeenCalledWith("/dashboard");
expect(toastSuccessMock).toHaveBeenCalledWith("Welcome back!");
});

it("stores backend tokens and navigates after signup", async () => {
const user = { id: "user-2", email: "new@example.com" };
signupMock.mockResolvedValue({
user,
tokens: {
accessToken: "new-access-token",
refreshToken: "new-refresh-token",
expiresIn: 3600,
expiresAt: 123456,
},
});

const { result } = renderHook(() => useAuth(), { wrapper: createWrapper() });

result.current.signup({
email: "new@example.com",
password: "password123",
displayName: "New User",
});

await waitFor(() =>
expect(setAuthMock).toHaveBeenCalledWith(
user,
"new-access-token",
"new-refresh-token"
)
);
expect(pushMock).toHaveBeenCalledWith("/dashboard");
expect(toastSuccessMock).toHaveBeenCalledWith("Account created successfully!");
});
});
4 changes: 2 additions & 2 deletions apps/frontend/src/lib/hooks/use-auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function useAuth() {
const loginMutation = useMutation({
mutationFn: authApi.login,
onSuccess: (data) => {
setAuth(data.user, data.session.access_token, data.session.refresh_token);
setAuth(data.user, data.tokens.accessToken, data.tokens.refreshToken);
toast.success("Welcome back!");
router.push("/dashboard");
},
Expand All @@ -21,7 +21,7 @@ export function useAuth() {
const signupMutation = useMutation({
mutationFn: authApi.signup,
onSuccess: (data) => {
setAuth(data.user, data.session.access_token, data.session.refresh_token);
setAuth(data.user, data.tokens.accessToken, data.tokens.refreshToken);
toast.success("Account created successfully!");
router.push("/dashboard");
},
Expand Down
Loading