diff --git a/pages/search/index.tsx b/pages/search/index.tsx index 5bfacb998..0d796d375 100644 --- a/pages/search/index.tsx +++ b/pages/search/index.tsx @@ -61,7 +61,9 @@ export default function Search({ results }) { {totalResults ? ( <> - {`Displaying 1-50 of ${totalResults.toLocaleString()} results for keyword "${ + {`Displaying ${ + totalResults > 50 ? "1-50" : totalResults.toLocaleString() + } of ${totalResults.toLocaleString()} results for keyword "${ searchParams.q }"`} diff --git a/src/components/SearchForm/SearchForm.test.tsx b/src/components/SearchForm/SearchForm.test.tsx new file mode 100644 index 000000000..d8c194506 --- /dev/null +++ b/src/components/SearchForm/SearchForm.test.tsx @@ -0,0 +1,51 @@ +import React from "react" +import { render, screen, fireEvent, act } from "@testing-library/react" +import mockRouter from "next-router-mock" + +import SearchForm from "./SearchForm" +import userEvent from "@testing-library/user-event" + +jest.mock("next/router", () => jest.requireActual("next-router-mock")) + +describe("SearchForm", () => { + const submit = () => + fireEvent( + screen.getByRole("button", { name: "Search" }), + new MouseEvent("click") + ) + beforeEach(() => { + mockRouter.query.q = "" + }) + afterEach(async () => { + const input = screen.getByRole("textbox") + await userEvent.clear(input) + }) + it("submits a keyword query by default", async () => { + render() + const input = screen.getByRole("textbox") + await act(async () => { + await userEvent.type(input, "spaghetti") + submit() + expect(mockRouter.asPath).toBe("/search?q=spaghetti") + }) + }) + it("submits a journal_title query", async () => { + render() + const input = screen.getByRole("textbox") + const searchScopeSelect = screen.getByRole("combobox") + await act(async () => { + await userEvent.type(input, "spaghetti") + await userEvent.selectOptions(searchScopeSelect, "journal_title") + submit() + expect(mockRouter.asPath).toBe( + "/search?q=spaghetti&search_scope=journal_title" + ) + }) + }) + it("gets keyword from url", () => { + mockRouter.query.q = "spaghetti" + render() + const input = screen.getByDisplayValue("spaghetti") + expect(input).toBeTruthy() + }) +}) diff --git a/src/components/SearchForm/SearchForm.tsx b/src/components/SearchForm/SearchForm.tsx index a85c448c9..585e5e5e1 100644 --- a/src/components/SearchForm/SearchForm.tsx +++ b/src/components/SearchForm/SearchForm.tsx @@ -1,11 +1,11 @@ import { SearchBar } from "@nypl/design-system-react-components" import { useRouter } from "next/router" -import type { SyntheticEvent } from "react" +import type { SyntheticEvent, Dispatch, SetStateAction } from "react" +import { useState } from "react" import styles from "../../../styles/components/Search.module.scss" import RCLink from "../RCLink/RCLink" import { getQueryString } from "../../utils/searchUtils" -import type { SearchFormEvent } from "../../types/searchTypes" import { BASE_URL, PATHS } from "../../config/constants" /** @@ -14,19 +14,30 @@ import { BASE_URL, PATHS } from "../../config/constants" */ const SearchForm = () => { const router = useRouter() + const [searchTerm, setSearchTerm] = useState( + (router?.query?.q as string) || "" + ) + const [searchScope, setSearchScope] = useState("all") const handleSubmit = async (e: SyntheticEvent) => { e.preventDefault() - const target = e.target as typeof e.target & SearchFormEvent const searchParams = { - q: target.q.value, - field: target.search_scope.value, + q: searchTerm, + field: searchScope, } const queryString = getQueryString(searchParams) await router.push(`${PATHS.SEARCH}${queryString}`) } + const handleChange = ( + e: SyntheticEvent, + setValue: Dispatch> + ) => { + const target = e.target as HTMLInputElement + setValue(target.value) + } + return (
@@ -38,6 +49,8 @@ const SearchForm = () => { onSubmit={handleSubmit} labelText="Search Bar Label" selectProps={{ + value: searchScope, + onChange: (e) => handleChange(e, setSearchScope), labelText: "Select a category", name: "search_scope", optionsData: [ @@ -50,6 +63,8 @@ const SearchForm = () => { ], }} textInputProps={{ + onChange: (e) => handleChange(e, setSearchTerm), + value: searchTerm, labelText: "Search by keyword, title, journal title, or author/contributor", name: "q",