Frontend/test/explore/1 (#544)

* refactor(<ExplorePage/>): add useExplore

* feat(api): add useBrainApi

* test(useBrainApi): add unit tests
This commit is contained in:
Mamadou DICKO 2023-07-06 19:01:23 +02:00 committed by GitHub
parent 0ce9c8ffcd
commit 4261ddae51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 122 additions and 49 deletions

View File

@ -0,0 +1,56 @@
import { UUID } from "crypto";
import { useEffect, useState } from "react";
import { useBrainApi } from "@/lib/api/brain/useBrainApi";
import { getBrainFromLocalStorage } from "@/lib/context/BrainProvider/helpers/brainLocalStorage";
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
import { useSupabase } from "@/lib/context/SupabaseProvider";
import { useAxios } from "@/lib/hooks";
import { Document } from "@/lib/types/Document";
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export const useExplore = () => {
const [documents, setDocuments] = useState<Document[]>([]);
const [isPending, setIsPending] = useState(true);
const { session } = useSupabase();
const { axiosInstance } = useAxios();
const { setActiveBrain, setDefaultBrain, currentBrainId } = useBrainContext();
const { getBrainDocuments } = useBrainApi();
const fetchAndSetActiveBrain = async () => {
const storedBrain = getBrainFromLocalStorage();
if (storedBrain) {
setActiveBrain({ ...storedBrain });
return storedBrain;
} else {
const defaultBrain = await setDefaultBrain();
return defaultBrain;
}
};
useEffect(() => {
const fetchDocuments = async (brainId: UUID | null) => {
setIsPending(true);
await fetchAndSetActiveBrain();
try {
if (brainId === null) {
throw new Error("Brain id not found");
}
const brainDocuments = await getBrainDocuments(brainId);
setDocuments(brainDocuments);
} catch (error) {
console.error("Error fetching documents", error);
setDocuments([]);
}
setIsPending(false);
};
void fetchDocuments(currentBrainId);
}, [session?.access_token, axiosInstance, currentBrainId]);
return {
isPending,
documents,
setDocuments,
};
};

View File

@ -3,68 +3,21 @@
import { AnimatePresence, motion } from "framer-motion";
import Link from "next/link";
import { redirect } from "next/navigation";
import { useEffect, useState } from "react";
import Button from "@/lib/components/ui/Button";
import Spinner from "@/lib/components/ui/Spinner";
import { useSupabase } from "@/lib/context/SupabaseProvider";
import { useAxios } from "@/lib/hooks";
import { Document } from "@/lib/types/Document";
import { getBrainFromLocalStorage } from "@/lib/context/BrainProvider/helpers/brainLocalStorage";
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
import { UUID } from "crypto";
import DocumentItem from "./DocumentItem";
import { useExplore } from "./hooks/useExplore";
const ExplorePage = (): JSX.Element => {
const [documents, setDocuments] = useState<Document[]>([]);
const [isPending, setIsPending] = useState(true);
const { session } = useSupabase();
const { axiosInstance } = useAxios();
const { setActiveBrain, setDefaultBrain, currentBrain, currentBrainId } =
useBrainContext();
const fetchAndSetActiveBrain = async () => {
const storedBrain = getBrainFromLocalStorage();
if (storedBrain) {
setActiveBrain({ ...storedBrain });
return storedBrain;
} else {
const defaultBrain = await setDefaultBrain();
return defaultBrain;
}
};
const { documents, setDocuments, isPending } = useExplore();
if (session === null) {
redirect("/login");
}
useEffect(() => {
const fetchDocuments = async (brainId: UUID | null) => {
setIsPending(true);
await fetchAndSetActiveBrain();
try {
if (brainId === undefined || brainId === null) {
throw new Error("Brain id not found");
}
console.log(
`Fetching documents from ${process.env.NEXT_PUBLIC_BACKEND_URL}/explore/?brain_id=${brainId}`
);
const response = await axiosInstance.get<{ documents: Document[] }>(
`/explore/?brain_id=${brainId}`
);
setDocuments(response.data.documents);
} catch (error) {
console.error("Error fetching documents", error);
setDocuments([]);
}
setIsPending(false);
};
fetchDocuments(currentBrainId);
}, [session.access_token, axiosInstance, currentBrainId]);
return (
<main>
<section className="w-full outline-none pt-10 flex flex-col gap-5 items-center justify-center p-6">

View File

@ -0,0 +1,37 @@
import { renderHook } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vitest";
import { useBrainApi } from "../useBrainApi";
const axiosGetMock = vi.fn(() => ({
data: {
documents: [],
},
}));
vi.mock("@/lib/hooks", () => ({
useAxios: vi.fn(() => ({
axiosInstance: {
get: axiosGetMock,
},
})),
}));
describe("useBrainApi", () => {
afterEach(() => {
vi.resetAllMocks();
});
it("should call getBrainDocuments with the correct parameters", async () => {
const {
result: {
current: { getBrainDocuments },
},
} = renderHook(() => useBrainApi());
const brainId = "123";
await getBrainDocuments(brainId);
expect(axiosGetMock).toHaveBeenCalledTimes(1);
expect(axiosGetMock).toHaveBeenCalledWith(`/explore/?brain_id=${brainId}`);
});
});

View File

@ -0,0 +1,14 @@
import { AxiosInstance } from "axios";
import { Document } from "@/lib/types/Document";
export const getBrainDocuments = async (
brainId: string,
axiosInstance: AxiosInstance
): Promise<Document[]> => {
const response = await axiosInstance.get<{ documents: Document[] }>(
`/explore/?brain_id=${brainId}`
);
return response.data.documents;
};

View File

@ -0,0 +1,13 @@
import { useAxios } from "@/lib/hooks";
import { getBrainDocuments } from "./brain";
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export const useBrainApi = () => {
const { axiosInstance } = useAxios();
return {
getBrainDocuments: async (brainId: string) =>
getBrainDocuments(brainId, axiosInstance),
};
};