diff --git a/frontend/src/components/TopMenu.test.tsx b/frontend/src/components/TopMenu.test.tsx new file mode 100644 index 0000000..785afc6 --- /dev/null +++ b/frontend/src/components/TopMenu.test.tsx @@ -0,0 +1,136 @@ +// __tests__/TopMenu.test.tsx +import { render, screen, fireEvent, waitFor } from "@testing-library/react"; +import "@testing-library/jest-dom"; +import React from "react"; +import TopMenu from "./TopMenu"; // Adjust the import path as necessary +import { BrowserRouter } from "react-router-dom"; +import { vi } from "vitest"; + +// Mock fetch +global.fetch = vi.fn(() => + Promise.resolve({ + ok: true, + json: () => Promise.resolve({ results: [] }), + }), +); + +describe("TopMenu Component", () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + test("renders search input and settings button", () => { + render( + + + , + ); + + const inputElement = screen.getByPlaceholderText(/search.../i); + const settingsButton = screen.getByRole("button"); + const searchIcon = screen.getByTestId("search-icon"); + const settingsIcon = screen.getByTestId("settings-icon"); + + expect(inputElement).toBeInTheDocument(); + expect(settingsButton).toBeInTheDocument(); + expect(searchIcon).toBeInTheDocument(); + expect(settingsIcon).toBeInTheDocument(); + }); + + test("updates search term on input change", () => { + render( + + + , + ); + + const inputElement = screen.getByPlaceholderText(/search.../i); + + fireEvent.change(inputElement, { target: { value: "test" } }); + + expect(inputElement).toHaveValue("test"); + }); + + test("calls API on Enter key press", async () => { + render( + + + , + ); + + const inputElement = screen.getByPlaceholderText(/search.../i); + + fireEvent.change(inputElement, { target: { value: "test" } }); + fireEvent.keyDown(inputElement, { key: "Enter", code: "Enter" }); + + await waitFor(() => expect(global.fetch).toHaveBeenCalledTimes(1)); + expect(global.fetch).toHaveBeenCalledWith( + "https://api.example.com/search", + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ query: "test" }), + }, + ); + }); + + test("handles API call failure gracefully", async () => { + (global.fetch as jest.Mock).mockImplementationOnce(() => + Promise.resolve({ + ok: false, + }), + ); + + render( + + + , + ); + + const inputElement = screen.getByPlaceholderText(/search.../i); + + fireEvent.change(inputElement, { target: { value: "test" } }); + fireEvent.keyDown(inputElement, { key: "Enter", code: "Enter" }); + + const consoleErrorSpy = vi + .spyOn(console, "error") + .mockImplementation(() => {}); + + await waitFor(() => expect(global.fetch).toHaveBeenCalledTimes(1)); + + await waitFor(() => + expect(consoleErrorSpy).toHaveBeenCalledWith("API call failed"), + ); + + consoleErrorSpy.mockRestore(); + }); + + test("handles network error gracefully", async () => { + (global.fetch as jest.Mock).mockImplementationOnce(() => + Promise.reject(new Error("Network error")), + ); + + render( + + + , + ); + + const inputElement = screen.getByPlaceholderText(/search.../i); + + fireEvent.change(inputElement, { target: { value: "test" } }); + fireEvent.keyDown(inputElement, { key: "Enter", code: "Enter" }); + + const consoleErrorSpy = vi + .spyOn(console, "error") + .mockImplementation(() => {}); + + await waitFor(() => + expect(consoleErrorSpy).toHaveBeenCalledWith("Error:", expect.any(Error)), + ); + + consoleErrorSpy.mockRestore(); + }); +}); diff --git a/frontend/src/components/TopMenu.tsx b/frontend/src/components/TopMenu.tsx index 285f639..d5ca690 100644 --- a/frontend/src/components/TopMenu.tsx +++ b/frontend/src/components/TopMenu.tsx @@ -1,14 +1,43 @@ -import React from "react"; +import React, { useState } from "react"; import { IoIosSearch, IoIosSettings } from "react-icons/io"; import { Link } from "react-router-dom"; function TopMenu() { + const [searchTerm, setSearchTerm] = useState(""); + + const handleKeyDown = async (event) => { + if (event.key === "Enter") { + // Call the REST API + try { + const response = await fetch("https://api.example.com/search", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ query: searchTerm }), + }); + + if (response.ok) { + const data = await response.json(); + console.log(data); // Handle the response data + } else { + console.error("API call failed"); + } + } catch (error) { + console.error("Error:", error); + } + } + }; + return (
@@ -18,9 +47,15 @@ function TopMenu() { type="text" className="w-full pl-10 pr-4 py-2 border border-gray-500 rounded-lg focus:outline focus:border-gray-700 text-white placeholder-gray-500" placeholder="Search..." + value={searchTerm} + onChange={(e) => setSearchTerm(e.target.value)} + onKeyDown={handleKeyDown} /> - +