Skip to content

Commit

Permalink
Fix unit tests (#3389)
Browse files Browse the repository at this point in the history
- Fix all broken unit tests
  • Loading branch information
TomNUSDS authored Dec 10, 2021
1 parent 6eaffdc commit 42bd1ae
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 119 deletions.
4 changes: 3 additions & 1 deletion frontend-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"@rest-hooks/hooks": "^2.0.0",
"@rest-hooks/rest": "^2.2.0",
"@rest-hooks/test": "^7.1.0",
"@testing-library/user-event": "^13.5.0",
"@trussworks/react-uswds": "^2.3.0",
"@types/downloadjs": "^1.4.2",
"@types/hookrouter": "^2.2.5",
Expand Down Expand Up @@ -55,7 +56,8 @@
"build:production": "env-cmd -f .env.production craco build",
"postbuild:staging": "cp build/index.html build/404.html",
"postbuild:production": "cp build/index.html build/404.html",
"test": "react-scripts test",
"test": "craco test",
"test:ci": "CI=true yarn test --coverage",
"eject": "react-scripts eject",
"lint": "npm-run-all -p lint:eslint lint:prettier",
"lint:write": "npm-run-all -p lint:eslint:write lint:prettier:write",
Expand Down
16 changes: 16 additions & 0 deletions frontend-react/src/components/Title.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { render, screen } from "@testing-library/react";

import Title from "./Title";

describe("Title component", () => {
const UNIQUE_TITLE = `Title for test`;
const UNIQUE_PRETITLE = `Unique PreTitle for unit test`;
beforeEach(() => {
render(<Title title={UNIQUE_TITLE} preTitle={UNIQUE_PRETITLE} />);
});

it("verify title shows", async () => {
expect(await screen.findByText(UNIQUE_TITLE)).toBeInTheDocument();
expect(await screen.findByText(UNIQUE_PRETITLE)).toBeInTheDocument();
});
});
17 changes: 1 addition & 16 deletions frontend-react/src/content/content.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
"imgAlt": "Map of the U.S. showing states and territories where ReportStream is currently live",
"linkInternal": "/how-it-works/where-were-live"
}
]
]
},
{
"title": "Interested in learning more about ReportStream?",
Expand All @@ -115,20 +115,5 @@
"buttonText": "Get in touch",
"buttonUrlSubject": "?subject=I'm interested in learning more about ReportStream"
}
],

"freeSecure": [
{
"title": "Free and created by the CDC",
"summary": "Developed for COVID-19 test data and public health departments, ReportStream is 100% free.",
"icon": "cdc-logo.svg",
"iconDescription": "CDC logo"
},
{
"title": "Safe and secure",
"summary": "Test results and patient data are securely stored and protected by two-factor authentication, database encryption, and HTTPS.",
"icon": "shield.svg",
"iconDescription": "Icon of a shield"
}
]
}
24 changes: 13 additions & 11 deletions frontend-react/src/pages/home/Home.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,23 @@ describe("Home rendering", () => {
render(<Home />);
});

test("Container renders", () => {
expect(screen.getByTestId("container")).toBeInTheDocument();
test("Container renders", async () => {
expect(await screen.getByTestId("container")).toBeInTheDocument();
});

test("Renders correct number of elements", async () => {
content.sections.forEach(async (section) => {
expect(await screen.findAllByTestId("feature")).toHaveLength(
section.features?.length || 0
);
});
// these tests require each new feature section has a `data-testid="feature"` set!

// note: forEach() is not async friendly
for (const eachSection of content.sections) {
for (const eachFeature of eachSection.features) {
// make sure each feature for each section appears somewhere on the page.
expect(await screen.findByText(eachFeature.title)).toBeValid();
}
}

expect(await screen.findAllByTestId("section")).toHaveLength(
content.sections.length
);
expect(await screen.findAllByTestId("free-secure")).toHaveLength(
content.freeSecure.length
content.sections.length + content.liveMapContact.length
);
});
});
4 changes: 2 additions & 2 deletions frontend-react/src/pages/home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const Home = () => {
return (
<section
data-testid="section"
key={`section=${sectionIndex}`}
key={`home-${sectionIndex}`}
className="usa-section margin-y-0 tablet:padding-top-6 tablet:padding-bottom-3"
>
<div className="grid-row grid-gap">
Expand Down Expand Up @@ -52,7 +52,7 @@ export const Home = () => {
return (
<section
data-testid="section"
key={`section=${sectionIndex}`}
key={`livemap-${sectionIndex}`}
className="usa-section margin-y-0 tablet:padding-top-2 tablet:padding-bottom-2"
>
<div className="grid-row grid-gap">
Expand Down
18 changes: 8 additions & 10 deletions frontend-react/src/pages/tos-sign/SuccessPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,18 @@ describe("Basic rendering", () => {

test("Data is displayed", () => {
const name = screen.getByText(
`Full name: ${mockData.firstName} ${mockData.lastName}`,
`${mockData.firstName} ${mockData.lastName}`,
{ exact: false }
);
const email = screen.getByText(`Email: ${mockData.email}`, {
const email = screen.getByText(mockData.email, {
exact: false,
});
const territory = screen.getByText(mockData.territory, {
exact: false,
});
const organizationName = screen.getByText(mockData.organizationName, {
exact: false,
});
const territory = screen.getByText(
`State or territory: ${mockData.territory}`,
{ exact: false }
);
const organizationName = screen.getByText(
`Organization name: ${mockData.organizationName}`,
{ exact: false }
);

expect(name).toBeInTheDocument();
expect(email).toBeInTheDocument();
Expand Down
4 changes: 2 additions & 2 deletions frontend-react/src/pages/tos-sign/SuccessPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ function SuccessPage({ data }: { data: AgreementBody | null }) {
Registration request submitted
</h4>
<p className="usa-alert__text">
<strong>Name:</strong> {data.firstName}{" "}
{data.lastName}
<strong>Name:</strong>{" "}
{`${data.firstName} ${data.lastName}`}
<br />
<strong>Email:</strong> {data.email}
<br />
Expand Down
154 changes: 77 additions & 77 deletions frontend-react/src/pages/tos-sign/TermsOfServiceForm.test.tsx
Original file line number Diff line number Diff line change
@@ -1,105 +1,105 @@
import { fireEvent, render, screen } from "@testing-library/react";
import {
fireEvent,
render,
screen,
waitForElementToBeRemoved,
waitFor,
} from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { BrowserRouter } from "react-router-dom";

import site from "../../content/site.json";

import TermsOfServiceForm from "./TermsOfServiceForm";

describe("Basic rendering", () => {
beforeEach(() => {
process.env.REACT_APP_SECRET = "fake secret";
render(
<BrowserRouter>
<TermsOfServiceForm />
</BrowserRouter>
);
});

test("Title renders", () => {
const preTitle = screen.getByText("Account registration");
const title = screen.getByText(
"Register your organization with ReportStream"
);

expect(preTitle).toBeInTheDocument();
expect(title).toBeInTheDocument();
});

/* INFO:
FormGroup, Label, TextInput, Dropdown, and Checkbox, and Button rendering tests should be
handled by the trussworks/USWDS component library */

test("Required fields show error when you submit them as empty", () => {
fireEvent.click(screen.getByText("Submit registration"));
expect(
screen.getByText("First name is a required field")
).toBeInTheDocument();
it("Title renders", async () => {
expect(
screen.getByText("Last name is a required field")
await screen.findByText("Account registration")
).toBeInTheDocument();
expect(
screen.getByText("Email is a required field")
).toBeInTheDocument();
expect(
screen.getByText("Organization is a required field")
).toBeInTheDocument();
expect(
screen.getByText(
"You must agree to the Terms of Service before using ReportStream"
await screen.findByText(
"Register your organization with ReportStream"
)
).toBeInTheDocument();
});

test("Required fields remove error once field is filled in and re-submitted", () => {
const button = screen.getByText("Submit registration");
fireEvent.click(button);
test("Required fields remove error once field is filled in and re-submitted", async () => {
const DATA = [
{
dataTestId: "first-name",
errorMsg: "First name is a required",
},
{
dataTestId: "last-name",
errorMsg: "Last name is a required",
},
{
dataTestId: "email",
errorMsg: "Email is a required field",
},
{
dataTestId: "organization-name",
errorMsg: "Organization is a required",
},
];
const submitBtn = await screen.getByTestId("submit");

expect(
screen.getByText("First name is a required field")
).toBeInTheDocument();
expect(
screen.getByText("Last name is a required field")
).toBeInTheDocument();
expect(
screen.getByText("Email is a required field")
).toBeInTheDocument();
expect(
screen.getByText("Organization is a required field")
).toBeInTheDocument();
expect(
screen.getByText(
"You must agree to the Terms of Service before using ReportStream"
)
).toBeInTheDocument();
for (const eachItem of DATA) {
// clear item, click submit, make sure error is there.
const inputField = await screen.getByTestId(eachItem.dataTestId);

const firstNameInput = screen.getByAltText("First name input");
const lastNameInput = screen.getByAltText("Last name input");
const emailInput = screen.getByAltText("Email input");
const organizationInput = screen.getByAltText("Organization input");
const agreedInput = screen.getByAltText("Agreed checkbox");
// fireEvent.change(inputField, {target: {value: " "}});
fireEvent.change(inputField, { target: { value: "" } });

fireEvent.change(firstNameInput, { target: { value: "Kevin" } });
fireEvent.change(lastNameInput, { target: { value: "Haube" } });
fireEvent.change(emailInput, {
target: { value: site.orgs.CDC.email },
});
fireEvent.change(organizationInput, { target: { value: "Foobar" } });
fireEvent.click(agreedInput);
fireEvent.click(button);
userEvent.click(submitBtn);
expect(
screen.queryByText(eachItem.errorMsg, { exact: false })
).toBeInTheDocument();

// now fill in and see if error messag is cleared
// fireEvent.change(inputField, {target: {value: "test@example.com"}});
userEvent.type(inputField, "[email protected]");

userEvent.click(submitBtn);
expect(
screen.queryByText(eachItem.errorMsg, { exact: false })
).not.toBeInTheDocument();

// leave it cleared. If every field has a valid value, then last click on submit button will submit.
fireEvent.change(inputField, { target: { value: "" } });

userEvent.click(submitBtn);
expect(
screen.queryByText(eachItem.errorMsg, { exact: false })
).toBeInTheDocument();
}

// the agree checkbox is the exception that mucks everything up
const agreeErrorMsg = "must agree to the Terms of Service";
const agreedInput = screen.getByTestId("agree");
userEvent.click(agreedInput);
expect(agreedInput).toBeChecked();
userEvent.click(submitBtn);
// this is "Visible" because it's using a hidden tag unlike other error messages
// "<ErrorMessage>" vs "<ErrorMessageWithFlag>" .. this drove me nuts writing this test
expect(
screen.queryByAltText("First name is a required field")
).toBeFalsy();
expect(
screen.queryByAltText("Last name is a required field")
).toBeFalsy();
expect(screen.queryByAltText("Email is a required field")).toBeFalsy();
expect(
screen.queryByAltText("Organization is a required field")
).toBeFalsy();
screen.queryByText(agreeErrorMsg, { exact: false })
).not.toBeVisible();

// toggle it off
userEvent.click(agreedInput);
expect(agreedInput).not.toBeChecked();
userEvent.click(submitBtn);
expect(
screen.queryByAltText(
"You must agree to the Terms of Service before using ReportStream"
)
).toBeFalsy();
screen.queryByText(agreeErrorMsg, { exact: false })
).toBeVisible();
});
});
Loading

0 comments on commit 42bd1ae

Please sign in to comment.