Skip to content

Commit

Permalink
Merge pull request #28 from sfbrigade/wip-search-form-test
Browse files Browse the repository at this point in the history
Wip search form test
  • Loading branch information
caramelqq authored Jul 24, 2021
2 parents 41e21a9 + a866a47 commit a1de2eb
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 88 deletions.
43 changes: 0 additions & 43 deletions src/components/home/Home.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {fireEvent, render, screen} from "@testing-library/react";
import Home from "./Home";
import {Route, Router} from "react-router-dom";
import {createMemoryHistory} from "history";
import {County, OrgType} from "../../types";

const history = createMemoryHistory();
jest.spyOn(history, "push");
Expand Down Expand Up @@ -31,48 +30,6 @@ describe("Home", () => {
expect(screen.getByRole("img", {name: "Storefront"})).toBeVisible();
});

describe("Search Button", () => {
it("displays an organization type dropdown that changes values on different options", () => {
const orgTypeSelect = screen.getByLabelText("I am a...");
expect(orgTypeSelect).toHaveValue("");

fireEvent.change(orgTypeSelect, {
target: {value: OrgType.SmallBusiness},
});
expect(orgTypeSelect).toHaveValue(OrgType.SmallBusiness);
});

it("has a dropdown for county that changes value when the user selects a different option", () => {
const countySelect = screen.getByLabelText("County");
expect(countySelect).toHaveValue("");

fireEvent.change(countySelect, {target: {value: County.Alameda}});
expect(countySelect).toHaveValue(County.Alameda);
});

it("searches with the filter options the user has selected", () => {
const searchButton = screen.getByText("Search");
const orgTypeSelect = screen.getByLabelText("I am a...");
const countySelect = screen.getByLabelText("County");

fireEvent.change(orgTypeSelect, {
target: {value: OrgType.SmallBusiness},
});
fireEvent.change(countySelect, {target: {value: County.Alameda}});
fireEvent.click(searchButton);

expect(history.push).toHaveBeenCalledWith({
pathname: "/results",
state: {
currentFilters: {
orgType: ["smallBusiness"],
county: ["alamedaCounty"],
},
},
});
});
});

it("renders a donate button and when pressed sends the user to the donate page", () => {
const donateButton = screen.getByText("I want to donate");
expect(donateButton).toBeVisible();
Expand Down
90 changes: 90 additions & 0 deletions src/components/home/SearchForm.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React from "react";
import {fireEvent, render, screen} from "@testing-library/react";
import {SearchForm} from "./SearchForm";
import {idleForIO} from "../../testUtils";
import {createMemoryHistory} from "history";
import {Route, Router} from "react-router-dom";

const history = createMemoryHistory();
jest.spyOn(history, "push");

describe('SearchForm selections', () => {
beforeEach(() => {
render(
<Router history={history}>
<Route component={SearchForm} />
</Router>
);
});

it('renders a SearchForm with two default Anys', () => {
const anyObject = screen.getAllByRole('option', {name: 'Any'});
expect(anyObject).toHaveLength(2);
});

it('can search with no user selections', async () => {
const searchButton = screen.getByText("Search");
fireEvent.click(searchButton);

expect(history.push).toHaveBeenLastCalledWith("/results");

const anyObject = screen.getAllByRole('option', {name: 'Any'});
expect((anyObject[0] as HTMLOptionElement).selected).toBeTruthy();
expect((anyObject[1] as HTMLOptionElement).selected).toBeTruthy();
});

it('can search by orgType', async () => {
fireEvent.change(screen.getByLabelText('I am a...'),
{ target: { value: 'smallBusiness' } });

const searchButton = screen.getByText("Search");
fireEvent.click(searchButton);

await idleForIO();

expect(history.push).toHaveBeenLastCalledWith("/results?orgType=smallBusiness");

const smallBusinessOption = screen.getAllByRole('option', {name: 'Small business'});
expect((smallBusinessOption[0] as HTMLOptionElement).selected).toBeTruthy();
const anyObject = screen.getAllByRole('option', {name: 'Any'});
expect((anyObject[0] as HTMLOptionElement).selected).toBeFalsy();
expect((anyObject[1] as HTMLOptionElement).selected).toBeTruthy();
});

it('can search by county only', async () => {
fireEvent.change(screen.getByLabelText("County"),
{ target: { value: 'alamedaCounty' } });

const searchButton = screen.getByText("Search");
fireEvent.click(searchButton);

await idleForIO();

expect(history.push).toHaveBeenLastCalledWith("/results?county=alamedaCounty");

const countyOption = screen.getAllByRole('option', {name: 'Alameda'});
expect((countyOption[0] as HTMLOptionElement).selected).toBeTruthy();
const anyObject = screen.getAllByRole('option', {name: 'Any'});
expect((anyObject[0] as HTMLOptionElement).selected).toBeTruthy();
expect((anyObject[1] as HTMLOptionElement).selected).toBeFalsy();
});

it('can search by county and org type', async () => {
fireEvent.change(screen.getByLabelText('I am a...'),
{ target: { value: 'smallBusiness' } });
fireEvent.change(screen.getByLabelText("County"),
{ target: { value: 'alamedaCounty' } });

const searchButton = screen.getByText("Search");
fireEvent.click(searchButton);

await idleForIO();

expect(history.push).toHaveBeenLastCalledWith("/results?orgType=smallBusiness&county=alamedaCounty");

const countyOption = screen.getAllByRole('option', {name: 'Alameda'});
expect((countyOption[0] as HTMLOptionElement).selected).toBeTruthy();
const smallBusinessOption = screen.getAllByRole('option', {name: 'Small business'});
expect((smallBusinessOption[0] as HTMLOptionElement).selected).toBeTruthy();
});
});
42 changes: 27 additions & 15 deletions src/components/home/SearchForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import FormControl from "@material-ui/core/FormControl";
import InputLabel from "@material-ui/core/InputLabel";
import Button from "@material-ui/core/Button";
import React, {useState} from "react";
import {getFilterNameFromGroupAndLabel} from "../results/filterHelpers";
import {getFilterNameFromGroupAndTargetName} from "../results/filterHelpers";
import {useHistory} from "react-router-dom";
import {Typography} from "@material-ui/core";
import {colors} from "../../theme";
Expand Down Expand Up @@ -56,22 +56,34 @@ const DonateButton = styled(Button)`
`;

export const SearchForm = () => {
const [orgType, setOrgType] = useState<OrgType>();
const [county, setCounty] = useState<County>();
const [orgType, setOrgType] = useState<OrgType>(OrgType.Any);
const [county, setCounty] = useState<County>(County.Any);

const history = useHistory();

const goToResults = () => {
history.push({
pathname: "/results",
state: {
currentFilters: {
orgType: [getFilterNameFromGroupAndLabel("orgType", orgType)],
county: [getFilterNameFromGroupAndLabel("county", county)],
},
},
});
let path = "/results";
if (orgType !== 'any') {
const orgTypeParam = getFilterNameFromGroupAndTargetName("orgType", orgType);
//append orgType=blah
path = `${path}?orgType=${orgTypeParam}&`;
}
//check if county is NOT any, append county
const countyParam = getFilterNameFromGroupAndTargetName("county", county);

if(countyParam && countyParam !== 'any') {
if(orgType === 'any') {
path = `${path}?`;
}
path = `${path}county=${countyParam}`;
}
//if (path[path.length -1] === ? or === &, slice it out
if(path[path.length-1] === "?" || path[path.length-1] ==="&") {
path = path.slice(0, path.length-1);
}
history.push(path);
};

const goToDonate = () => {
history.push("/donate");
};
Expand All @@ -96,9 +108,10 @@ export const SearchForm = () => {
inputProps={{
name: "org-type",
id: "org-type-select",
"data-testid": "org-type-select"
}}
>
<option aria-label="None" value="" />
<option value={OrgType.Any}>Any</option>
<option value={OrgType.SmallBusiness}>Small business</option>
<option value={OrgType.NonProfit}>Non-profit</option>
</StyledSelect>
Expand All @@ -115,13 +128,12 @@ export const SearchForm = () => {
id: "county-select",
}}
>
<option aria-label="None" value="" />
<option value={County.Any}>Any</option>
<option value={County.SanFrancisco}>San Francisco</option>
<option value={County.Alameda}>Alameda</option>
<option value={County.SanMateo}>San Mateo</option>
<option value={County.ContraCosta}>Conta Costa</option>
<option value={County.SantaClara}>Santa Clara</option>
<option value={County.Any}>Any</option>
</StyledSelect>
</FormControl>
</SearchFormFields>
Expand Down
19 changes: 6 additions & 13 deletions src/components/results/Results.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {createMemoryHistory} from "history";
import Results from "./Results";
import { Router } from "react-router-dom";
import {idleForIO} from "../../testUtils";
import { applyFilters } from "../results/filterHelpers";
import { applyFilters } from "./filterHelpers";
import {
formatAwardAmount,
formatDate,
Expand All @@ -26,8 +26,8 @@ describe("Results", () => {
]);

return (
<Router history={history}>
<Results
<Router history={history}>
<Results
isFilterOpen={isFilterOpen}
setIsFilterOpen={setIsFilterOpen}
currentFilters={currentFilters}
Expand All @@ -40,7 +40,6 @@ describe("Results", () => {
};

describe("results filtering", () => {

it("applies the filters passed in", async () => {
const results: Result[] = [
makeResult({
Expand All @@ -56,13 +55,8 @@ describe("Results", () => {
];

const history = createMemoryHistory();
const initialState = {
currentFilters: {
orgType: ["nonProfit"],
county: ["sanMateoCounty"],
},
};
history.push("/", initialState);

history.push("/?orgType=nonProfit&county=sanMateoCounty");
render(<ResultWrapper history={history} results={results}/>);

const nonProfitCheckbox = screen.getByLabelText(
Expand Down Expand Up @@ -189,9 +183,8 @@ describe("Results", () => {
describe("results list", () => {
describe("when there are no matches", () => {
it("renders a no results image and message", async () => {
const results: Result[] = [];
const history = createMemoryHistory();
render(<ResultWrapper history={history} results={results}/>);
render(<ResultWrapper history={history} results={[]}/>);
await idleForIO();

const nonProfitCheckbox = screen.getByLabelText(
Expand Down
18 changes: 14 additions & 4 deletions src/components/results/Results.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, {ChangeEvent, useEffect, useState} from "react";
import {CurrentFilters, Result, SortOptionType} from "../../types";
import {CurrentFilters, HomeSearchFormTypes, Result, SortOptionType} from "../../types";
import styled from "styled-components";
import ResultCard from "./ResultCard";
import FormControl from "@material-ui/core/FormControl";
Expand Down Expand Up @@ -100,9 +100,19 @@ const Results: React.FC<ResultsProps> = ({
const [loading, setLoading] = useState(true);
const history = useHistory<{currentFilters: CurrentFilters}>();

if(history.location.state && history.location.state.currentFilters){
setCurrentFilters(history.location.state.currentFilters);
}
useEffect(() => {
if (history.location.search) {
const params = new URLSearchParams(history.location.search);
const pathFilters: HomeSearchFormTypes = {};
if (params.get("orgType")) {
pathFilters["orgType"] = [params.get("orgType")];
}
if (params.get("county")) {
pathFilters["county"] = [params.get("county")];
}
setCurrentFilters(pathFilters);
}
}, [history.location.search, setCurrentFilters]);

const [sortOption, setSortOption] = useState<SortOptionType>(
SortOptionType.DueDateNewToOld
Expand Down
22 changes: 22 additions & 0 deletions src/components/results/filterHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,27 @@ export const filterGroups: FilterGroup[] = [
},
];

export const getFilterNameFromGroupAndTargetName = (
groupName: string,
name: string
): string | undefined => {
const foundGroup = filterGroups.find(
(group) => group.groupName === groupName
);

if (foundGroup) {
const foundFilter = foundGroup.filters.find(
(filter) => filter.name === name
);
if (foundFilter) {
return foundFilter.name;
}
}
return undefined;
};



export const getFilterNameFromGroupAndLabel = (
groupName: string,
label: string
Expand All @@ -165,6 +186,7 @@ export const getFilterNameFromGroupAndLabel = (
(filter) => filter.label === label
);
if (foundFilter) {

return foundFilter.name;
}
}
Expand Down
Loading

0 comments on commit a1de2eb

Please sign in to comment.