From eb0b3518efad31278ebefc13d8504a6ed01f2cc0 Mon Sep 17 00:00:00 2001
From: Emily Jablonski <65367387+emilyjablonski@users.noreply.github.com>
Date: Thu, 13 Jun 2024 11:45:09 -0600
Subject: [PATCH] test: move application page cypress tests to unit tests
(#4138)
---
shared-helpers/jest.config.js | 1 +
sites/partners/__tests__/testUtils.tsx | 4 +-
sites/partners/jest.config.js | 1 +
.../applications/contact/address.test.tsx | 72 ++++++++++++++
.../alternate-contact-contact.test.tsx | 49 +++++++++
.../contact/alternate-contact-name.test.tsx | 45 +++++++++
.../contact/alternate-contact-type.test.tsx | 55 +++++++++++
.../pages/applications/contact/name.test.tsx | 62 ++++++++++++
.../applications/financial/income.test.tsx | 45 +++++++++
.../applications/financial/vouchers.test.tsx | 45 +++++++++
.../pages/applications/household/ada.test.tsx | 69 +++++++++++++
.../household/add-members.test.tsx | 33 +++++++
.../applications/household/changes.test.tsx | 47 +++++++++
.../household/live-alone.test.tsx | 46 +++++++++
.../applications/household/member.test.tsx | 76 ++++++++++++++
.../household/members-info.test.tsx | 35 +++++++
.../household/preferred-units.test.tsx | 33 +++++++
.../applications/household/student.test.tsx | 47 +++++++++
.../applications/preferences/all.test.tsx | 33 +++++++
.../applications/preferences/general.test.tsx | 35 +++++++
.../applications/review/confirmation.test.tsx | 38 +++++++
.../applications/review/demographics.test.tsx | 99 +++++++++++++++++++
.../applications/review/summary.test.tsx | 33 +++++++
.../pages/applications/review/terms.test.tsx | 42 ++++++++
sites/public/__tests__/testUtils.tsx | 78 +++++++++++++++
sites/public/cypress/e2e/navigation.spec.ts | 12 ---
.../pages/application/contact/address.spec.ts | 78 ---------------
.../contact/alternate-contact-contact.spec.ts | 19 ----
.../contact/alternate-contact-name.spec.ts | 17 ----
.../contact/alternate-contact-type.spec.ts | 24 -----
.../pages/application/contact/name.spec.ts | 32 ------
.../application/financial/income.spec.ts | 18 ----
.../application/financial/vouchers.spec.ts | 18 ----
.../pages/application/household/ada.spec.ts | 29 ------
.../application/household/add-members.spec.ts | 22 -----
.../household/expecting-changes.spec.ts | 19 ----
.../application/household/live-alone.spec.ts | 12 ---
.../application/household/member.spec.ts | 33 -------
.../household/members-info.spec.ts | 12 ---
.../household/preferred-units.spec.ts | 12 ---
.../application/household/programs.spec.ts | 78 ---------------
.../application/household/student.spec.ts | 19 ----
.../application/preferences/general.spec.ts | 12 ---
.../application/review/confirmation.spec.ts | 17 ----
.../application/review/demographics.spec.ts | 12 ---
.../pages/application/review/summary.spec.ts | 12 ---
.../pages/application/review/terms.spec.ts | 21 ----
.../cypress/mockData/applicationData.ts | 2 +-
sites/public/cypress/support/commands.js | 3 +-
sites/public/jest.config.js | 16 ++-
sites/public/package.json | 2 +
.../lib/applications/AlternateContactStep.ts | 2 +-
.../contact/alternate-contact-contact.tsx | 4 +-
.../contact/alternate-contact-name.tsx | 4 +-
.../applications/household/live-alone.tsx | 2 +
.../pages/applications/household/member.tsx | 4 +-
.../applications/review/demographics.tsx | 2 +
sites/public/src/pages/disclaimer.tsx | 2 +-
sites/public/src/pages/privacy.tsx | 2 +-
sites/public/tsconfig.json | 4 +-
sites/public/tsconfig.test.json | 5 +-
61 files changed, 1156 insertions(+), 549 deletions(-)
create mode 100644 sites/public/__tests__/pages/applications/contact/address.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/contact/alternate-contact-contact.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/contact/alternate-contact-name.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/contact/alternate-contact-type.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/contact/name.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/financial/income.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/financial/vouchers.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/household/ada.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/household/add-members.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/household/changes.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/household/live-alone.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/household/member.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/household/members-info.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/household/preferred-units.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/household/student.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/preferences/all.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/preferences/general.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/review/confirmation.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/review/demographics.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/review/summary.test.tsx
create mode 100644 sites/public/__tests__/pages/applications/review/terms.test.tsx
create mode 100644 sites/public/__tests__/testUtils.tsx
delete mode 100644 sites/public/cypress/e2e/navigation.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/contact/address.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/contact/alternate-contact-contact.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/contact/alternate-contact-name.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/contact/alternate-contact-type.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/contact/name.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/financial/income.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/financial/vouchers.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/household/ada.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/household/add-members.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/household/expecting-changes.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/household/live-alone.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/household/member.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/household/members-info.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/household/preferred-units.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/household/programs.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/household/student.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/preferences/general.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/review/confirmation.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/review/demographics.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/review/summary.spec.ts
delete mode 100644 sites/public/cypress/e2e/pages/application/review/terms.spec.ts
diff --git a/shared-helpers/jest.config.js b/shared-helpers/jest.config.js
index efdebe6bdb..c2573b0731 100644
--- a/shared-helpers/jest.config.js
+++ b/shared-helpers/jest.config.js
@@ -20,6 +20,7 @@ module.exports = {
globals: {
"ts-jest": {
tsconfig: "tsconfig.json",
+ isolatedModules: true,
},
},
moduleNameMapper: {
diff --git a/sites/partners/__tests__/testUtils.tsx b/sites/partners/__tests__/testUtils.tsx
index 37e1820e91..7736adcfa3 100644
--- a/sites/partners/__tests__/testUtils.tsx
+++ b/sites/partners/__tests__/testUtils.tsx
@@ -1,7 +1,7 @@
-import { AuthProvider, ConfigProvider } from "@bloom-housing/shared-helpers"
-import { render, RenderOptions } from "@testing-library/react"
import React, { FC, ReactElement } from "react"
+import { render, RenderOptions } from "@testing-library/react"
import { SWRConfig } from "swr"
+import { AuthProvider, ConfigProvider } from "@bloom-housing/shared-helpers"
const AllTheProviders: FC<{ children: React.ReactNode }> = ({ children }) => {
return (
diff --git a/sites/partners/jest.config.js b/sites/partners/jest.config.js
index e2918eb246..b3c1ca3e12 100644
--- a/sites/partners/jest.config.js
+++ b/sites/partners/jest.config.js
@@ -20,6 +20,7 @@ module.exports = {
globals: {
"ts-jest": {
tsconfig: "tsconfig.test.json",
+ isolatedModules: true,
},
},
rootDir: "../..",
diff --git a/sites/public/__tests__/pages/applications/contact/address.test.tsx b/sites/public/__tests__/pages/applications/contact/address.test.tsx
new file mode 100644
index 0000000000..489bf2ba38
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/contact/address.test.tsx
@@ -0,0 +1,72 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { fireEvent } from "@testing-library/react"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationAddress from "../../../../src/pages/applications/contact/address"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("address step", () => {
+ it("should render form fields", () => {
+ const { getByText, getByTestId, getAllByTestId } = render()
+
+ expect(
+ getByText("Now we need to know how to contact you about your application.", {
+ exact: false,
+ })
+ ).toBeInTheDocument()
+ expect(getByTestId("app-primary-phone-number")).toBeInTheDocument()
+ expect(getByTestId("app-primary-phone-number-type")).toBeInTheDocument()
+ expect(getByTestId("app-primary-no-phone")).toBeInTheDocument()
+ expect(getByTestId("app-primary-additional-phone")).toBeInTheDocument()
+ expect(getByTestId("app-primary-address-street")).toBeInTheDocument()
+ expect(getByTestId("app-primary-address-street2")).toBeInTheDocument()
+ expect(getByTestId("app-primary-address-city")).toBeInTheDocument()
+ expect(getByTestId("app-primary-address-state")).toBeInTheDocument()
+ expect(getByTestId("app-primary-address-zip")).toBeInTheDocument()
+ expect(getByTestId("app-primary-send-to-mailing")).toBeInTheDocument()
+ expect(getAllByTestId("app-primary-contact-preference")).toHaveLength(4)
+ expect(getByTestId("app-primary-work-in-region-yes")).toBeInTheDocument()
+ expect(getByTestId("app-primary-work-in-region-no")).toBeInTheDocument()
+ })
+
+ it("should require form input", async () => {
+ const { getByText, findByText } = render()
+
+ fireEvent.click(getByText("Next"))
+ expect(
+ await findByText("There are errors you'll need to resolve before moving on.")
+ ).toBeInTheDocument()
+ expect(getByText("Please enter a phone number")).toBeInTheDocument()
+ expect(getByText("Please enter a phone number type")).toBeInTheDocument()
+ expect(getByText("Please enter an address")).toBeInTheDocument()
+ expect(getByText("Please select at least one option.")).toBeInTheDocument()
+ expect(getByText("Please select one of the options above.")).toBeInTheDocument()
+ })
+
+ it("should disable phone fields if user indicates they don't have a phone", async () => {
+ const { getByText, findByTestId, getByTestId } = render()
+
+ expect(getByTestId("app-primary-phone-number").firstChild).toBeEnabled()
+ fireEvent.click(getByText("I don't have a telephone number"))
+ expect((await findByTestId("app-primary-phone-number")).firstChild).toBeDisabled()
+ expect(await findByTestId("app-primary-phone-number-type")).toBeDisabled()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/contact/alternate-contact-contact.test.tsx b/sites/public/__tests__/pages/applications/contact/alternate-contact-contact.test.tsx
new file mode 100644
index 0000000000..43bd6f069b
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/contact/alternate-contact-contact.test.tsx
@@ -0,0 +1,49 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { fireEvent } from "@testing-library/react"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationAlternateContactContact from "../../../../src/pages/applications/contact/alternate-contact-contact"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("alternate contact contact step", () => {
+ it("should render form fields", () => {
+ const { getByText, getByTestId } = render()
+
+ expect(getByText("Let us know how to reach your alternate contact.")).toBeInTheDocument()
+ expect(getByTestId("app-alternate-phone-number")).toBeInTheDocument()
+ expect(getByTestId("app-alternate-email")).toBeInTheDocument()
+ expect(getByTestId("app-alternate-mailing-address-street")).toBeInTheDocument()
+ expect(getByTestId("app-alternate-mailing-address-street2")).toBeInTheDocument()
+ expect(getByTestId("app-alternate-mailing-address-city")).toBeInTheDocument()
+ expect(getByTestId("app-alternate-mailing-address-state")).toBeInTheDocument()
+ expect(getByTestId("app-alternate-mailing-address-zip")).toBeInTheDocument()
+ })
+
+ it("should require form input", async () => {
+ const { getByText, findByText } = render()
+
+ fireEvent.click(getByText("Next"))
+ expect(
+ await findByText("There are errors you'll need to resolve before moving on.")
+ ).toBeInTheDocument()
+ expect(getByText("Please enter a phone number")).toBeInTheDocument()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/contact/alternate-contact-name.test.tsx b/sites/public/__tests__/pages/applications/contact/alternate-contact-name.test.tsx
new file mode 100644
index 0000000000..a43ab7dee8
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/contact/alternate-contact-name.test.tsx
@@ -0,0 +1,45 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { fireEvent } from "@testing-library/react"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationAlternateContactName from "../../../../src/pages/applications/contact/alternate-contact-name"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("alternate contact name step", () => {
+ it("should render form fields", () => {
+ const { getByText, getByTestId } = render()
+
+ expect(getByText("Who is your alternate contact?")).toBeInTheDocument()
+ expect(getByTestId("app-alternate-first-name")).toBeInTheDocument()
+ expect(getByTestId("app-alternate-last-name")).toBeInTheDocument()
+ })
+
+ it("should require form input", async () => {
+ const { getByText, findByText } = render()
+
+ fireEvent.click(getByText("Next"))
+ expect(
+ await findByText("There are errors you'll need to resolve before moving on.")
+ ).toBeInTheDocument()
+ expect(getByText("Please enter a Given Name")).toBeInTheDocument()
+ expect(getByText("Please enter a Family Name")).toBeInTheDocument()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/contact/alternate-contact-type.test.tsx b/sites/public/__tests__/pages/applications/contact/alternate-contact-type.test.tsx
new file mode 100644
index 0000000000..39deba1446
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/contact/alternate-contact-type.test.tsx
@@ -0,0 +1,55 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { fireEvent } from "@testing-library/react"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationAlternateContactType from "../../../../src/pages/applications/contact/alternate-contact-type"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("alternate contact type step", () => {
+ it("should render form fields", () => {
+ const { getByText, getAllByTestId } = render()
+
+ expect(
+ getByText(
+ "Is there someone else you'd like to authorize us to contact if we can't reach you?"
+ )
+ ).toBeInTheDocument()
+ expect(getAllByTestId("app-alternate-type")).toHaveLength(5)
+ })
+
+ it("should require form input", async () => {
+ const { getByText, findByText } = render()
+
+ fireEvent.click(getByText("Next"))
+ expect(
+ await findByText("There are errors you'll need to resolve before moving on.")
+ ).toBeInTheDocument()
+ expect(getByText("Please select an alternate contact")).toBeInTheDocument()
+ })
+
+ it("should enable additional text field if user selects other type", () => {
+ const { getByText, getByTestId, queryByText } = render()
+
+ expect(queryByText("app-alternate-other-type")).not.toBeInTheDocument()
+ fireEvent.click(getByText("Other"))
+ expect(getByTestId("app-alternate-other-type")).toBeInTheDocument()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/contact/name.test.tsx b/sites/public/__tests__/pages/applications/contact/name.test.tsx
new file mode 100644
index 0000000000..ca055c289b
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/contact/name.test.tsx
@@ -0,0 +1,62 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { fireEvent } from "@testing-library/react"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationName from "../../../../src/pages/applications/contact/name"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("name step", () => {
+ it("should render form fields", () => {
+ const { getByText, getByTestId } = render()
+
+ expect(getByText("What's your name?")).toBeInTheDocument()
+ expect(getByTestId("app-primary-first-name")).toBeInTheDocument()
+ expect(getByTestId("app-primary-middle-name")).toBeInTheDocument()
+ expect(getByTestId("app-primary-last-name")).toBeInTheDocument()
+ expect(getByTestId("dob-field-month")).toBeInTheDocument()
+ expect(getByTestId("dob-field-day")).toBeInTheDocument()
+ expect(getByTestId("dob-field-year")).toBeInTheDocument()
+ expect(getByTestId("app-primary-email")).toBeInTheDocument()
+ })
+
+ it("should require form input", async () => {
+ const { getByText, findByText } = render()
+
+ fireEvent.click(getByText("Next"))
+ expect(
+ await findByText("There are errors you'll need to resolve before moving on.")
+ ).toBeInTheDocument()
+ expect(getByText("Please enter a Given Name")).toBeInTheDocument()
+ expect(getByText("Please enter a Family Name")).toBeInTheDocument()
+ expect(
+ getByText("Please enter a valid Date of Birth, must be 18 or older")
+ ).toBeInTheDocument()
+ expect(getByText("Please enter an email address")).toBeInTheDocument()
+ })
+
+ it("should disable email field if user indicates they don't have an email", async () => {
+ const { getByText, findByTestId, getByTestId } = render()
+
+ expect(getByTestId("app-primary-email")).toBeEnabled()
+ fireEvent.click(getByText("I don't have an email address"))
+ expect(await findByTestId("app-primary-email")).toBeDisabled()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/financial/income.test.tsx b/sites/public/__tests__/pages/applications/financial/income.test.tsx
new file mode 100644
index 0000000000..b8367ccbe1
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/financial/income.test.tsx
@@ -0,0 +1,45 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { fireEvent } from "@testing-library/react"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationIncome from "../../../../src/pages/applications/financial/income"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("income step", () => {
+ it("should render form fields", () => {
+ const { getByText, getByTestId, getAllByTestId } = render()
+
+ expect(getByText("Let's move to income.")).toBeInTheDocument()
+ expect(getByTestId("app-income")).toBeInTheDocument()
+ expect(getAllByTestId("app-income-period")).toHaveLength(2)
+ })
+
+ it("should require form input", async () => {
+ const { getByText, findByText } = render()
+
+ fireEvent.click(getByText("Next"))
+ expect(
+ await findByText("There are errors you'll need to resolve before moving on.")
+ ).toBeInTheDocument()
+ expect(getByText("Please enter a valid number greater than 0.")).toBeInTheDocument()
+ expect(getByText("Please select one of the options above.")).toBeInTheDocument()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/financial/vouchers.test.tsx b/sites/public/__tests__/pages/applications/financial/vouchers.test.tsx
new file mode 100644
index 0000000000..781e4d298a
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/financial/vouchers.test.tsx
@@ -0,0 +1,45 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { fireEvent } from "@testing-library/react"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationVouchers from "../../../../src/pages/applications/financial/vouchers"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("vouchers step", () => {
+ it("should render form fields", () => {
+ const { getByText, getAllByTestId } = render()
+
+ expect(
+ getByText("Do you or anyone on this application receive any of the following?")
+ ).toBeInTheDocument()
+ expect(getAllByTestId("app-income-vouchers")).toHaveLength(2)
+ })
+
+ it("should require form input", async () => {
+ const { getByText, findByText } = render()
+
+ fireEvent.click(getByText("Next"))
+ expect(
+ await findByText("There are errors you'll need to resolve before moving on.")
+ ).toBeInTheDocument()
+ expect(getByText("Please select an option.")).toBeInTheDocument()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/household/ada.test.tsx b/sites/public/__tests__/pages/applications/household/ada.test.tsx
new file mode 100644
index 0000000000..82402d3bdb
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/household/ada.test.tsx
@@ -0,0 +1,69 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { fireEvent } from "@testing-library/react"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationAda from "../../../../src/pages/applications/household/ada"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("ada step", () => {
+ it("should render form fields", () => {
+ const { getByText, getByTestId } = render()
+
+ expect(
+ getByText(
+ "Do you or anyone in your household need any of the following ADA accessibility features?"
+ )
+ ).toBeInTheDocument()
+ expect(getByTestId("app-ada-mobility")).toBeInTheDocument()
+ expect(getByTestId("app-ada-vision")).toBeInTheDocument()
+ expect(getByTestId("app-ada-hearing")).toBeInTheDocument()
+ expect(getByTestId("app-ada-none")).toBeInTheDocument()
+ })
+
+ it("should require form input", async () => {
+ const { getByText, findByText } = render()
+
+ fireEvent.click(getByText("Next"))
+ expect(
+ await findByText("There are errors you'll need to resolve before moving on.")
+ ).toBeInTheDocument()
+ expect(getByText("Please select one of the options above.")).toBeInTheDocument()
+ })
+
+ it("should uncheck all other boxes when 'No' is selected", () => {
+ const { getByText, getByTestId } = render()
+ fireEvent.click(getByText("For Mobility Impairments"))
+ fireEvent.click(getByText("For Vision Impairments"))
+ fireEvent.click(getByText("For Hearing Impairments"))
+
+ expect(getByTestId("app-ada-mobility")).toBeChecked()
+ expect(getByTestId("app-ada-vision")).toBeChecked()
+ expect(getByTestId("app-ada-hearing")).toBeChecked()
+ expect(getByTestId("app-ada-none")).not.toBeChecked()
+
+ fireEvent.click(getByText("No"))
+
+ expect(getByTestId("app-ada-mobility")).not.toBeChecked()
+ expect(getByTestId("app-ada-vision")).not.toBeChecked()
+ expect(getByTestId("app-ada-hearing")).not.toBeChecked()
+ expect(getByTestId("app-ada-none")).toBeChecked()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/household/add-members.test.tsx b/sites/public/__tests__/pages/applications/household/add-members.test.tsx
new file mode 100644
index 0000000000..578ae6b7e9
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/household/add-members.test.tsx
@@ -0,0 +1,33 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationAddMembers from "../../../../src/pages/applications/household/add-members"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("add members step", () => {
+ it("should render form fields", () => {
+ const { getByText } = render()
+
+ expect(getByText("Tell us about your household.")).toBeInTheDocument()
+ expect(getByText("Edit")).toBeInTheDocument()
+ expect(getByText("Add Household Member", { exact: false })).toBeInTheDocument()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/household/changes.test.tsx b/sites/public/__tests__/pages/applications/household/changes.test.tsx
new file mode 100644
index 0000000000..213ea002d7
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/household/changes.test.tsx
@@ -0,0 +1,47 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { fireEvent } from "@testing-library/react"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationHouseholdChanges from "../../../../src/pages/applications/household/changes"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("changes step", () => {
+ it("should render form fields", () => {
+ const { getByText, getAllByTestId } = render()
+
+ expect(
+ getByText(
+ "Do you anticipate any changes in your household in the next 12 months, such as the number of people?"
+ )
+ ).toBeInTheDocument()
+ expect(getAllByTestId("app-expecting-changes")).toHaveLength(2)
+ })
+
+ it("should require form input", async () => {
+ const { getByText, findByText } = render()
+
+ fireEvent.click(getByText("Next"))
+ expect(
+ await findByText("There are errors you'll need to resolve before moving on.")
+ ).toBeInTheDocument()
+ expect(getByText("Please select an option.")).toBeInTheDocument()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/household/live-alone.test.tsx b/sites/public/__tests__/pages/applications/household/live-alone.test.tsx
new file mode 100644
index 0000000000..55f8306017
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/household/live-alone.test.tsx
@@ -0,0 +1,46 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { fireEvent } from "@testing-library/react"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationLiveAlone from "../../../../src/pages/applications/household/live-alone"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("live alone step", () => {
+ it("should render form fields", () => {
+ const { getByText, getByTestId } = render()
+
+ expect(
+ getByText("Next we would like to know about the others who will live with you in the unit.")
+ ).toBeInTheDocument()
+ expect(getByTestId("app-household-live-alone")).toBeInTheDocument()
+ expect(getByTestId("app-household-with-others")).toBeInTheDocument()
+ })
+
+ it("should require form input", async () => {
+ const { getByText, findByText } = render()
+
+ fireEvent.click(getByText("Next"))
+ expect(
+ await findByText("There are errors you'll need to resolve before moving on.")
+ ).toBeInTheDocument()
+ expect(getByText("Please select one of the options above.")).toBeInTheDocument()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/household/member.test.tsx b/sites/public/__tests__/pages/applications/household/member.test.tsx
new file mode 100644
index 0000000000..b8fba9855f
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/household/member.test.tsx
@@ -0,0 +1,76 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { fireEvent } from "@testing-library/react"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationMember from "../../../../src/pages/applications/household/member"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("member step", () => {
+ it("should render form fields", () => {
+ const { getByText, getByTestId, getAllByTestId } = render()
+
+ expect(getByText("Tell us about this person.")).toBeInTheDocument()
+ expect(getByTestId("app-household-member-first-name")).toBeInTheDocument()
+ expect(getByTestId("app-household-member-first-name")).toBeInTheDocument()
+ expect(getByTestId("app-household-member-first-name")).toBeInTheDocument()
+ expect(getByTestId("dob-field-month")).toBeInTheDocument()
+ expect(getByTestId("dob-field-day")).toBeInTheDocument()
+ expect(getByTestId("dob-field-year")).toBeInTheDocument()
+ expect(getAllByTestId("app-household-member-same-address")).toHaveLength(2)
+ expect(getAllByTestId("app-household-member-work-in-region")).toHaveLength(2)
+ expect(getByTestId("app-household-member-relationship")).toBeInTheDocument()
+ })
+
+ it("should require form input", async () => {
+ const { getByText, findByText, getAllByText } = render()
+
+ fireEvent.click(getByText("Save household member"))
+ expect(
+ await findByText("There are errors you'll need to resolve before moving on.")
+ ).toBeInTheDocument()
+ expect(getByText("Please enter a Given Name")).toBeInTheDocument()
+ expect(getByText("Please enter a Family Name")).toBeInTheDocument()
+ expect(getByText("Please enter a valid Date of Birth")).toBeInTheDocument()
+ expect(getAllByText("Please select one of the options above.")).toHaveLength(3)
+ })
+
+ it("should show more address fields if same address is not selected", () => {
+ const { getAllByText, getByTestId } = render()
+
+ fireEvent.click(getAllByText("No")[0])
+ expect(getByTestId("app-household-member-address-street")).toBeInTheDocument()
+ expect(getByTestId("app-household-member-address-street2")).toBeInTheDocument()
+ expect(getByTestId("app-household-member-address-city")).toBeInTheDocument()
+ expect(getByTestId("app-household-member-address-state")).toBeInTheDocument()
+ expect(getByTestId("app-household-member-address-zip")).toBeInTheDocument()
+ })
+
+ it("should show more address fields if work in region is selected", () => {
+ const { getAllByText, getByTestId } = render()
+
+ fireEvent.click(getAllByText("Yes")[1])
+ expect(getByTestId("app-household-member-work-address-street")).toBeInTheDocument()
+ expect(getByTestId("app-household-member-work-address-street2")).toBeInTheDocument()
+ expect(getByTestId("app-household-member-work-address-city")).toBeInTheDocument()
+ expect(getByTestId("app-household-member-work-address-state")).toBeInTheDocument()
+ expect(getByTestId("app-household-member-work-address-zip")).toBeInTheDocument()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/household/members-info.test.tsx b/sites/public/__tests__/pages/applications/household/members-info.test.tsx
new file mode 100644
index 0000000000..8c072f838f
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/household/members-info.test.tsx
@@ -0,0 +1,35 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationMembersInfo from "../../../../src/pages/applications/household/members-info"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("members info step", () => {
+ it("should render page content", () => {
+ const { getByText } = render()
+
+ expect(
+ getByText(
+ "Before adding other people, make sure that they aren't named on any other application for this listing."
+ )
+ ).toBeInTheDocument()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/household/preferred-units.test.tsx b/sites/public/__tests__/pages/applications/household/preferred-units.test.tsx
new file mode 100644
index 0000000000..b2496ade9f
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/household/preferred-units.test.tsx
@@ -0,0 +1,33 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationPreferredUnits from "../../../../src/pages/applications/household/preferred-units"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("preferred units step", () => {
+ // TODO: We need to mock the units on the listing object, otherwise no unit types appear
+ it("should render form fields", () => {
+ const { getByText } = render()
+
+ expect(getByText("What unit sizes are you interested in?")).toBeInTheDocument()
+ expect(getByText("Check all that apply")).toBeInTheDocument()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/household/student.test.tsx b/sites/public/__tests__/pages/applications/household/student.test.tsx
new file mode 100644
index 0000000000..c570b0692f
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/household/student.test.tsx
@@ -0,0 +1,47 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { fireEvent } from "@testing-library/react"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationHouseholdStudent from "../../../../src/pages/applications/household/student"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("student step", () => {
+ it("should render form fields", () => {
+ const { getByText, getAllByTestId } = render()
+
+ expect(
+ getByText(
+ "Is someone in your household a full time student or going to turn 18 years old within 60 days?"
+ )
+ ).toBeInTheDocument()
+ expect(getAllByTestId("app-student")).toHaveLength(2)
+ })
+
+ it("should require form input", async () => {
+ const { getByText, findByText } = render()
+
+ fireEvent.click(getByText("Next"))
+ expect(
+ await findByText("There are errors you'll need to resolve before moving on.")
+ ).toBeInTheDocument()
+ expect(getByText("Please select an option.")).toBeInTheDocument()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/preferences/all.test.tsx b/sites/public/__tests__/pages/applications/preferences/all.test.tsx
new file mode 100644
index 0000000000..748061ba98
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/preferences/all.test.tsx
@@ -0,0 +1,33 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationPreferencesAll from "../../../../src/pages/applications/preferences/all"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("preferences all step", () => {
+ it("should render page content", () => {
+ const { getByText } = render()
+
+ expect(
+ getByText("Your household may qualify for the following housing preferences.")
+ ).toBeInTheDocument()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/preferences/general.test.tsx b/sites/public/__tests__/pages/applications/preferences/general.test.tsx
new file mode 100644
index 0000000000..922f0b7446
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/preferences/general.test.tsx
@@ -0,0 +1,35 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationPreferencesGeneral from "../../../../src/pages/applications/preferences/general"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("preferences general step", () => {
+ it("should render page content", () => {
+ const { getByText } = render()
+
+ expect(
+ getByText(
+ "Based on the information you have entered, your household has not claimed any housing preferences."
+ )
+ ).toBeInTheDocument()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/review/confirmation.test.tsx b/sites/public/__tests__/pages/applications/review/confirmation.test.tsx
new file mode 100644
index 0000000000..a3e5556d28
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/review/confirmation.test.tsx
@@ -0,0 +1,38 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationConfirmation from "../../../../src/pages/applications/review/confirmation"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("confirmation step", () => {
+ it("should render page content", () => {
+ const { getByText } = render()
+
+ expect(
+ getByText("Thanks. We have received your application", { exact: false })
+ ).toBeInTheDocument()
+ expect(
+ getByText(
+ "Please write down your application number and keep it in a safe place. We have also emailed this number to you if you have provided an email address."
+ )
+ ).toBeInTheDocument()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/review/demographics.test.tsx b/sites/public/__tests__/pages/applications/review/demographics.test.tsx
new file mode 100644
index 0000000000..708cbfbec7
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/review/demographics.test.tsx
@@ -0,0 +1,99 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { fireEvent } from "@testing-library/react"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationDemographics from "../../../../src/pages/applications/review/demographics"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("demographics step", () => {
+ it("should render form fields", () => {
+ const { getByText, getByTestId, getAllByTestId } = render()
+
+ expect(
+ getByText("Help us ensure we are meeting our goal to serve all people.")
+ ).toBeInTheDocument()
+ expect(getByTestId("americanIndianAlaskanNative")).toBeInTheDocument()
+ expect(getByTestId("asian")).toBeInTheDocument()
+ expect(getByTestId("blackAfricanAmerican")).toBeInTheDocument()
+ expect(getByTestId("nativeHawaiianOtherPacificIslander")).toBeInTheDocument()
+ expect(getByTestId("white")).toBeInTheDocument()
+ expect(getByTestId("otherMultiracial")).toBeInTheDocument()
+ expect(getByTestId("declineToRespond")).toBeInTheDocument()
+ expect(getByTestId("app-demographics-ethnicity")).toBeInTheDocument()
+ expect(getAllByTestId("app-demographics-how-did-you-hear")).toHaveLength(9)
+ })
+
+ it("should render sub demographics fields when parent is checked", () => {
+ const { getByText, queryByText } = render()
+
+ expect(queryByText("Asian Indian")).not.toBeInTheDocument()
+ expect(queryByText("Chinese")).not.toBeInTheDocument()
+ expect(queryByText("Filipino")).not.toBeInTheDocument()
+ expect(queryByText("Japanese")).not.toBeInTheDocument()
+ expect(queryByText("Korean")).not.toBeInTheDocument()
+ expect(queryByText("Vietnamese")).not.toBeInTheDocument()
+ expect(queryByText("Other Asian")).not.toBeInTheDocument()
+
+ fireEvent.click(getByText("Asian"))
+
+ expect(getByText("Asian Indian")).toBeInTheDocument()
+ expect(getByText("Chinese")).toBeInTheDocument()
+ expect(getByText("Filipino")).toBeInTheDocument()
+ expect(getByText("Japanese")).toBeInTheDocument()
+ expect(getByText("Korean")).toBeInTheDocument()
+ expect(getByText("Vietnamese")).toBeInTheDocument()
+ expect(getByText("Other Asian")).toBeInTheDocument()
+
+ expect(queryByText("Native Hawaiian")).not.toBeInTheDocument()
+ expect(queryByText("Guamanian or Chamorro")).not.toBeInTheDocument()
+ expect(queryByText("Samoan")).not.toBeInTheDocument()
+ expect(queryByText("Other Pacific Islander")).not.toBeInTheDocument()
+
+ fireEvent.click(getByText("Native Hawaiian / Other Pacific Islander"))
+
+ expect(getByText("Native Hawaiian")).toBeInTheDocument()
+ expect(getByText("Guamanian or Chamorro")).toBeInTheDocument()
+ expect(getByText("Samoan")).toBeInTheDocument()
+ expect(getByText("Other Pacific Islander")).toBeInTheDocument()
+ })
+
+ it("should show other text fields when other options are checked", async () => {
+ const { getByText, queryByTitle, findByTitle } = render()
+
+ expect(queryByTitle("asian-otherAsian")).not.toBeInTheDocument()
+ fireEvent.click(getByText("Asian"))
+ fireEvent.click(getByText("Other Asian"))
+ expect(await findByTitle("asian-otherAsian")).toBeInTheDocument()
+
+ expect(
+ queryByTitle("nativeHawaiianOtherPacificIslander-otherPacificIslander")
+ ).not.toBeInTheDocument()
+ fireEvent.click(getByText("Native Hawaiian / Other Pacific Islander"))
+ fireEvent.click(getByText("Other Pacific Islander"))
+ expect(
+ await findByTitle("nativeHawaiianOtherPacificIslander-otherPacificIslander")
+ ).toBeInTheDocument()
+
+ expect(queryByTitle("otherMultiracial")).not.toBeInTheDocument()
+ fireEvent.click(getByText("Other / Multiracial"))
+ expect(await findByTitle("otherMultiracial")).toBeInTheDocument()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/review/summary.test.tsx b/sites/public/__tests__/pages/applications/review/summary.test.tsx
new file mode 100644
index 0000000000..f9f8f063f3
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/review/summary.test.tsx
@@ -0,0 +1,33 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationSummary from "../../../../src/pages/applications/review/summary"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("summary step", () => {
+ it("should render page content", () => {
+ const { getByText } = render()
+
+ expect(
+ getByText("Take a moment to review your information before submitting your application.")
+ ).toBeInTheDocument()
+ })
+ })
+})
diff --git a/sites/public/__tests__/pages/applications/review/terms.test.tsx b/sites/public/__tests__/pages/applications/review/terms.test.tsx
new file mode 100644
index 0000000000..655ba49d73
--- /dev/null
+++ b/sites/public/__tests__/pages/applications/review/terms.test.tsx
@@ -0,0 +1,42 @@
+import React from "react"
+import { setupServer } from "msw/lib/node"
+import { fireEvent } from "@testing-library/react"
+import { mockNextRouter, render } from "../../../testUtils"
+import ApplicationTerms from "../../../../src/pages/applications/review/terms"
+
+window.scrollTo = jest.fn()
+
+const server = setupServer()
+
+beforeAll(() => {
+ server.listen()
+ mockNextRouter()
+})
+
+afterEach(() => server.resetHandlers())
+
+afterAll(() => server.close())
+
+describe("applications pages", () => {
+ afterAll(() => {
+ jest.clearAllMocks()
+ })
+
+ describe("terms step", () => {
+ it("should render form fields", () => {
+ const { getByText, getByTestId } = render()
+
+ expect(getByText("Terms")).toBeInTheDocument()
+ expect(getByTestId("app-terms-agree")).toBeInTheDocument()
+ })
+
+ it("should require form input", async () => {
+ const { getByText, findByText } = render()
+
+ fireEvent.click(getByText("Submit"))
+ expect(
+ await findByText("You must agree to the terms in order to continue")
+ ).toBeInTheDocument()
+ })
+ })
+})
diff --git a/sites/public/__tests__/testUtils.tsx b/sites/public/__tests__/testUtils.tsx
new file mode 100644
index 0000000000..75949860ca
--- /dev/null
+++ b/sites/public/__tests__/testUtils.tsx
@@ -0,0 +1,78 @@
+import React, { FC, ReactElement } from "react"
+import { render, RenderOptions } from "@testing-library/react"
+import {
+ AuthProvider,
+ ConfigProvider,
+ blankApplication,
+ MessageContext,
+ MessageProvider,
+} from "@bloom-housing/shared-helpers"
+import { Listing } from "@bloom-housing/shared-helpers/src/types/backend-swagger"
+import { Toast } from "@bloom-housing/ui-seeds"
+import {
+ AppSubmissionContext,
+ retrieveApplicationConfig,
+} from "../src/lib/applications/AppSubmissionContext"
+import ApplicationConductor from "../src/lib/applications/ApplicationConductor"
+
+const AllTheProviders: FC<{ children: React.ReactNode }> = ({ children }) => {
+ const conductor = new ApplicationConductor({}, {})
+ const applicationConfig = retrieveApplicationConfig(conductor.listing)
+ conductor.config = applicationConfig
+
+ const ToastProvider = (props) => {
+ const { toastMessagesRef } = React.useContext(MessageContext)
+ return (
+
+ {toastMessagesRef.current?.map((toastMessage) => (
+
+ {toastMessage.message}
+
+ ))}
+ {props.children}
+
+ )
+ }
+
+ return (
+ {
+ return
+ },
+ syncListing: () => {
+ return
+ },
+ }}
+ >
+
+
+ {children}
+
+
+
+ )
+}
+
+const customRender = (ui: ReactElement, options?: Omit) =>
+ render(ui, { wrapper: AllTheProviders, ...options })
+
+// re-export everything
+// eslint-disable-next-line import/export
+export * from "@testing-library/react"
+
+// override render method
+// eslint-disable-next-line import/export
+export { customRender as render }
+
+export const mockNextRouter = () => {
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
+ const useRouter = jest.spyOn(require("next/router"), "useRouter")
+ useRouter.mockImplementation(() => ({
+ pathname: "/",
+ }))
+ return useRouter
+}
diff --git a/sites/public/cypress/e2e/navigation.spec.ts b/sites/public/cypress/e2e/navigation.spec.ts
deleted file mode 100644
index e2ce027bd2..0000000000
--- a/sites/public/cypress/e2e/navigation.spec.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-describe("Site navigation", () => {
- it("should load the home page", () => {
- cy.visit("/")
- cy.getByID("hero-component").should("be.visible")
- })
-
- it("should load the listings page", () => {
- cy.visit("/listings")
-
- cy.getByTestId("listing-card-component").should("be.visible")
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/contact/address.spec.ts b/sites/public/cypress/e2e/pages/application/contact/address.spec.ts
deleted file mode 100644
index 96d663ec1a..0000000000
--- a/sites/public/cypress/e2e/pages/application/contact/address.spec.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-describe("applications/contact/address", function () {
- const route = "/applications/contact/address"
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("should render the primary applicant address sub-form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-
- it("should require form input", function () {
- cy.goNext()
- cy.checkErrorAlert("be.visible")
- cy.checkErrorMessages("be.visible")
- })
-
- it("should disable phone number & phone number type fields when user indicates they have no phone number", function () {
- cy.getByTestId("app-primary-no-phone").check()
- cy.getPhoneFieldByTestId("app-primary-phone-number").should("be.disabled")
- cy.getByTestId("app-primary-phone-number-type").should("be.disabled")
- cy.getByTestId("app-primary-additional-phone").should("be.disabled")
- cy.reload()
- })
-
- it("should provide a way to validate address via API", function () {
- // fake the address call to the mocked data
- cy.intercept("GET", "/geocoding/v5/**", { fixture: "address" })
- cy.getByTestId("app-primary-no-phone").check()
-
- cy.getByTestId("app-primary-address-street").type("600 Mongomery St")
- cy.getByTestId("app-primary-address-city").type("San Francisco")
- cy.getByTestId("app-primary-address-state").select("CA")
- cy.getByTestId("app-primary-address-zip").type("94112")
-
- cy.getByTestId("app-primary-contact-preference").eq(0).check()
- cy.getByTestId("app-primary-work-in-region-no").check()
-
- cy.goNext()
- cy.getByTestId("app-found-address-label").should("be.visible")
- cy.getByTestId("app-found-address-label").should("include.text", "Montgomery St")
- cy.getByTestId("app-found-address-label").should("include.text", "94111")
- cy.reload()
- })
-
- it("should handle garbage input", function () {
- // fake the address call to the mocked data
- cy.intercept("GET", "/geocoding/v5/**", { fixture: "address-bad" })
- cy.getByTestId("app-primary-no-phone").check()
-
- // Let's add gibberish
- cy.getByTestId("app-primary-address-street").type("l;iaj;ewlijvlij")
- cy.getByTestId("app-primary-address-city").type("San Francisco")
- cy.getByTestId("app-primary-address-state").select("CA")
- cy.getByTestId("app-primary-address-zip").type("oqr8buoi@@hn")
-
- cy.getByTestId("app-primary-contact-preference").eq(0).check()
- cy.getByTestId("app-primary-work-in-region-no").check()
-
- cy.goNext()
-
- cy.checkErrorAlert("not.exist")
- cy.checkErrorMessages("not.exist")
- cy.get(`[data-testid="app-found-address-label"]`).should("not.exist")
-
- // Let's go back and add other weirdness
- cy.getByID("app-edit-original-address").click()
- cy.getByTestId("app-primary-address-street").clear().type("98765 NW 10")
- cy.getByTestId("app-primary-address-zip").clear().type("54321")
-
- cy.goNext()
-
- cy.checkErrorAlert("not.exist")
- cy.checkErrorMessages("not.exist")
- cy.get(`[data-testid="app-found-address-label"]`).should("not.exist")
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/contact/alternate-contact-contact.spec.ts b/sites/public/cypress/e2e/pages/application/contact/alternate-contact-contact.spec.ts
deleted file mode 100644
index 9bb5780127..0000000000
--- a/sites/public/cypress/e2e/pages/application/contact/alternate-contact-contact.spec.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-describe("applications/contact/alternate-contact-contact", function () {
- const route = "/applications/contact/alternate-contact-contact"
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("should render the alternate contact contact sub-form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-
- it("should require form input", function () {
- cy.goNext()
- cy.location("pathname").should("include", route)
- cy.checkErrorAlert("be.visible")
- cy.checkErrorMessages("be.visible")
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/contact/alternate-contact-name.spec.ts b/sites/public/cypress/e2e/pages/application/contact/alternate-contact-name.spec.ts
deleted file mode 100644
index e4b787fe0b..0000000000
--- a/sites/public/cypress/e2e/pages/application/contact/alternate-contact-name.spec.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-describe("applications/contact/alternate-contact-name", function () {
- const route = "/applications/contact/alternate-contact-name"
-
- it("should render the alternate contact name sub-form", function () {
- cy.visit(route)
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-
- it("should require form input", function () {
- cy.visit(route)
- cy.goNext()
- cy.location("pathname").should("include", route)
- cy.checkErrorAlert("be.visible")
- cy.checkErrorMessages("be.visible")
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/contact/alternate-contact-type.spec.ts b/sites/public/cypress/e2e/pages/application/contact/alternate-contact-type.spec.ts
deleted file mode 100644
index 5827ecdbb2..0000000000
--- a/sites/public/cypress/e2e/pages/application/contact/alternate-contact-type.spec.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-describe("applications/contact/alternate-contact-type", function () {
- const route = "/applications/contact/alternate-contact-type"
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("should render the alternate contact type sub-form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-
- it("should require form input", function () {
- cy.goNext()
- cy.checkErrorAlert("be.visible")
- cy.location("pathname").should("include", route)
- })
-
- it("should require text input when the Other type is selected", function () {
- cy.getByTestId("app-alternate-type").eq(3).check()
- cy.goNext()
- cy.checkErrorAlert("be.visible")
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/contact/name.spec.ts b/sites/public/cypress/e2e/pages/application/contact/name.spec.ts
deleted file mode 100644
index ca4de11f0b..0000000000
--- a/sites/public/cypress/e2e/pages/application/contact/name.spec.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-describe("applications/contact/name", function () {
- const route = "/applications/contact/name"
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("should render the primary contact name sub-form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-
- it("should require form input", function () {
- cy.goNext()
- cy.location("pathname").should("include", route)
- cy.checkErrorAlert("be.visible")
- })
-
- it("should validate email fields", function () {
- cy.getByTestId("app-primary-email").type("not email format")
- cy.goNext()
- cy.location("pathname").should("include", route)
- cy.checkErrorAlert("be.visible")
- cy.reload()
- })
-
- it("should disable email field when user indicates they have no email", function () {
- cy.getByTestId("app-primary-no-email").check()
- cy.getByTestId("app-primary-email").should("be.disabled")
- cy.reload()
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/financial/income.spec.ts b/sites/public/cypress/e2e/pages/application/financial/income.spec.ts
deleted file mode 100644
index a48a685f2f..0000000000
--- a/sites/public/cypress/e2e/pages/application/financial/income.spec.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-describe("applications/financial/income", function () {
- const route = "applications/financial/income"
-
- beforeEach(() => {
- cy.visit(route)
- })
- it("should render the income sub-form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-
- it("should require form input", function () {
- cy.goNext()
- cy.location("pathname").should("include", route)
- cy.checkErrorAlert("be.visible")
- cy.checkErrorMessages("be.visible")
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/financial/vouchers.spec.ts b/sites/public/cypress/e2e/pages/application/financial/vouchers.spec.ts
deleted file mode 100644
index 2b66f25fbd..0000000000
--- a/sites/public/cypress/e2e/pages/application/financial/vouchers.spec.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-describe("applications/financial/vouchers", function () {
- const route = "/applications/financial/vouchers"
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("should render vouchers sub-form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-
- it("should require form input", function () {
- cy.goNext()
- cy.location("pathname").should("include", route)
- cy.checkErrorAlert("be.visible")
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/household/ada.spec.ts b/sites/public/cypress/e2e/pages/application/household/ada.spec.ts
deleted file mode 100644
index 2c5141d30c..0000000000
--- a/sites/public/cypress/e2e/pages/application/household/ada.spec.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-describe("applications/household/ada", function () {
- const route = "/applications/household/ada"
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("should render ada sub-form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-
- it("should require form input", function () {
- cy.goNext()
- cy.checkErrorAlert("be.visible")
- cy.location("pathname").should("include", route)
- })
-
- it("should uncheck all other checkboxes when 'No' is selected", function () {
- cy.get("[data-testid=app-ada-mobility]").check()
- cy.get("[data-testid=app-ada-vision]").check()
- cy.get("[data-testid=app-ada-hearing]").check()
-
- cy.get("[data-testid=app-ada-none]").check()
- cy.get("[data-testid=app-ada-mobility]").should("not.be.checked")
- cy.get("[data-testid=app-ada-vision]").should("not.be.checked")
- cy.get("[data-testid=app-ada-hearing]").should("not.be.checked")
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/household/add-members.spec.ts b/sites/public/cypress/e2e/pages/application/household/add-members.spec.ts
deleted file mode 100644
index 0977ae6622..0000000000
--- a/sites/public/cypress/e2e/pages/application/household/add-members.spec.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-describe("applications/household/add-members", function () {
- const route = "/applications/household/add-members"
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("should render add household members sub-form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-
- it("should move backward in form to /contact/name after editing primary household member", function () {
- cy.get(".app-household-member-edit-button").click()
- cy.location("pathname").should("include", "applications/contact/name")
- })
-
- it("should move to correct route on Add Member click", function () {
- cy.getByID("app-add-household-member-button").click()
- cy.location("pathname").should("include", "applications/household/member")
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/household/expecting-changes.spec.ts b/sites/public/cypress/e2e/pages/application/household/expecting-changes.spec.ts
deleted file mode 100644
index 4e09051edd..0000000000
--- a/sites/public/cypress/e2e/pages/application/household/expecting-changes.spec.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-describe("applications/household/changes", function () {
- const route = "/applications/household/changes"
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("should render expecting household changes sub-form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-
- it("should require form input", function () {
- cy.goNext()
-
- cy.checkErrorAlert("be.visible")
- cy.checkErrorMessages("be.visible")
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/household/live-alone.spec.ts b/sites/public/cypress/e2e/pages/application/household/live-alone.spec.ts
deleted file mode 100644
index 43a2dae32f..0000000000
--- a/sites/public/cypress/e2e/pages/application/household/live-alone.spec.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-describe("applications/household/live-alone", function () {
- const route = "/applications/household/live-alone"
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("should render live alone sub-form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/household/member.spec.ts b/sites/public/cypress/e2e/pages/application/household/member.spec.ts
deleted file mode 100644
index edfc40ce7b..0000000000
--- a/sites/public/cypress/e2e/pages/application/household/member.spec.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-describe("applications/household/member", function () {
- const route = "/applications/household/member"
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("should render add household member sub-form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-
- it("should require form input", function () {
- cy.getByID("app-household-member-save").click()
- cy.location("pathname").should("include", route)
- cy.checkErrorAlert("be.visible")
- })
-
- it("should show member address if user indicates they do not live at the same address", function () {
- cy.getByTestId("app-household-member-same-address").eq(1).check()
- cy.getByTestId("app-household-member-address-street").should("be.visible")
- })
-
- it("should show member work address if user indicates they work in the region", function () {
- cy.getByTestId("app-household-member-work-in-region").eq(0).check()
- cy.getByTestId("app-household-member-work-address-street").should("be.visible")
- })
-
- it("should go back to members screen without adding current member when user cancels", function () {
- cy.getByID("app-household-member-cancel").click()
- cy.location("pathname").should("include", "/applications/household/add-members")
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/household/members-info.spec.ts b/sites/public/cypress/e2e/pages/application/household/members-info.spec.ts
deleted file mode 100644
index c6da73859e..0000000000
--- a/sites/public/cypress/e2e/pages/application/household/members-info.spec.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-describe("applications/household/members-info", function () {
- const route = "/applications/household/members-info"
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("Should render form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/household/preferred-units.spec.ts b/sites/public/cypress/e2e/pages/application/household/preferred-units.spec.ts
deleted file mode 100644
index f023e4cfcb..0000000000
--- a/sites/public/cypress/e2e/pages/application/household/preferred-units.spec.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-describe("applications/household/preferred-units", function () {
- const route = "/applications/household/preferred-units"
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("should render preferred units sub-form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/household/programs.spec.ts b/sites/public/cypress/e2e/pages/application/household/programs.spec.ts
deleted file mode 100644
index efb3a9a721..0000000000
--- a/sites/public/cypress/e2e/pages/application/household/programs.spec.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-describe("applications/programs/programs", function () {
- const route = "/applications/programs/programs"
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("Should render form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-})
-/* describe("applications/household/programs", function () {
- const route = "/applications/household/programs"
-
- const servedInMilitaryYesId = "servedInMilitary"
- const tayNoId = "doNotConsider"
-
- beforeEach(() => {
- cy.fixture("listing.json")
- .as("listing")
- .then((listing) => {
- const programs = listing.listingPrograms
-
- cy.loadConfig(
- {
- listingPrograms: programs,
- },
- "applicationConfigFilled.json"
- )
- })
-
- cy.visit(route)
- })
-
- it("Should render form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-
- it("Should display initial form errors", function () {
- // not sure why this needs to be here twice to work -JW
- cy.goNext()
- cy.goNext()
-
- cy.checkErrorAlert("be.visible")
- })
-
- it("Should save values", function () {
- cy.getByID(servedInMilitaryYesId).check()
- cy.goNext()
- cy.getByID(tayNoId).check()
- cy.goNext()
-
- // test first preference submission
- cy.getSubmissionContext()
- .its("programs")
- .should(
- "deep.nested.include",
- {
- key: "servedInMilitary",
- claimed: true,
- options: [
- { key: "servedInMilitary", checked: true, extraData: [] },
- { key: "doNotConsider", checked: false, extraData: [] },
- ],
- },
- {
- key: "tay",
- claimed: true,
- options: [
- { key: "tay", checked: false, extraData: [] },
- { key: "doNotConsider", checked: true, extraData: [] },
- ],
- }
- )
- })
-})*/
diff --git a/sites/public/cypress/e2e/pages/application/household/student.spec.ts b/sites/public/cypress/e2e/pages/application/household/student.spec.ts
deleted file mode 100644
index 7542f9f802..0000000000
--- a/sites/public/cypress/e2e/pages/application/household/student.spec.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-describe("applications/household/student", function () {
- const route = "/applications/household/student"
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("should render household student sub-form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-
- it("should require form input", function () {
- cy.goNext()
-
- cy.checkErrorAlert("be.visible")
- cy.checkErrorMessages("be.visible")
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/preferences/general.spec.ts b/sites/public/cypress/e2e/pages/application/preferences/general.spec.ts
deleted file mode 100644
index e80d9ce6fc..0000000000
--- a/sites/public/cypress/e2e/pages/application/preferences/general.spec.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-describe("applications/preferences/general", function () {
- const route = "/applications/preferences/general"
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("Should render form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/review/confirmation.spec.ts b/sites/public/cypress/e2e/pages/application/review/confirmation.spec.ts
deleted file mode 100644
index 7860728aec..0000000000
--- a/sites/public/cypress/e2e/pages/application/review/confirmation.spec.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-describe("applications/review/confirmation", function () {
- const route = "/applications/review/confirmation"
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("should redirect to home page on click", function () {
- cy.getByTestId("app-confirmation-browse").click()
- cy.location("pathname").should("equals", "/listings")
- })
-
- it("should redirect to create account page", function () {
- cy.getByID("app-confirmation-create-account").click()
- cy.location("pathname").should("equals", "/create-account")
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/review/demographics.spec.ts b/sites/public/cypress/e2e/pages/application/review/demographics.spec.ts
deleted file mode 100644
index 7585d33934..0000000000
--- a/sites/public/cypress/e2e/pages/application/review/demographics.spec.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-describe("applications/review/demographics", function () {
- const route = "/applications/review/demographics"
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("should render demographics sub-form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/review/summary.spec.ts b/sites/public/cypress/e2e/pages/application/review/summary.spec.ts
deleted file mode 100644
index 9e6220f2fe..0000000000
--- a/sites/public/cypress/e2e/pages/application/review/summary.spec.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-describe("applications/review/summary", function () {
- const route = "/applications/review/summary"
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("should render summary page", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-})
diff --git a/sites/public/cypress/e2e/pages/application/review/terms.spec.ts b/sites/public/cypress/e2e/pages/application/review/terms.spec.ts
deleted file mode 100644
index f8793db78c..0000000000
--- a/sites/public/cypress/e2e/pages/application/review/terms.spec.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-describe("applications/review/terms", function () {
- const route = "/applications/review/terms"
-
- function submitApplication() {
- cy.getByID("app-terms-submit-button").click()
- }
-
- beforeEach(() => {
- cy.visit(route)
- })
-
- it("should render terms sub-form", function () {
- cy.get("form").should("be.visible")
- cy.location("pathname").should("include", route)
- })
-
- it("should require form input", function () {
- submitApplication()
- cy.checkErrorMessages("be.visible")
- })
-})
diff --git a/sites/public/cypress/mockData/applicationData.ts b/sites/public/cypress/mockData/applicationData.ts
index 0cb45fc91e..3ed16d7ba5 100644
--- a/sites/public/cypress/mockData/applicationData.ts
+++ b/sites/public/cypress/mockData/applicationData.ts
@@ -230,7 +230,7 @@ export const ElmVillageApplication: Application = {
],
demographics: {
...idDefaults,
- race: ["race-white"],
+ race: ["americanIndianAlaskanNative"],
ethnicity: "hispanicLatino",
gender: "",
sexualOrientation: "",
diff --git a/sites/public/cypress/support/commands.js b/sites/public/cypress/support/commands.js
index 2cc36a7dc7..0f88467569 100644
--- a/sites/public/cypress/support/commands.js
+++ b/sites/public/cypress/support/commands.js
@@ -467,8 +467,7 @@ Cypress.Commands.add("step16GeneralPool", () => {
Cypress.Commands.add("step17Demographics", (application) => {
cy.location("pathname").should("include", "applications/review/demographics")
application.demographics.race.forEach((race) => {
- const raceIndex = raceCheckboxesOrder.indexOf(race)
- cy.getByTestId("app-demographics-race").eq(raceIndex).check()
+ cy.getByTestId(race).check()
})
if (application.demographics.ethnicity) {
diff --git a/sites/public/jest.config.js b/sites/public/jest.config.js
index c7ac82abdf..a3e67845bb 100644
--- a/sites/public/jest.config.js
+++ b/sites/public/jest.config.js
@@ -5,7 +5,16 @@ process.env.TZ = "UTC"
module.exports = {
testRegex: ["/*.test.tsx$", "/*.test.ts$"],
- collectCoverageFrom: ["**/*.ts", "!**/*.tsx"],
+ collectCoverageFrom: ["**/*.ts", "**/*.tsx"],
+ coveragePathIgnorePatterns: [
+ "cypress",
+ "types",
+ "__tests__",
+ "next-env.d.ts",
+ "sentry.client.config.ts",
+ "sentry.server.config.ts",
+ "sentry.edge.config.ts",
+ ],
coverageReporters: ["lcov", "text"],
coverageDirectory: "test-coverage",
coverageThreshold: {
@@ -20,16 +29,15 @@ module.exports = {
globals: {
"ts-jest": {
tsconfig: "tsconfig.test.json",
+ isolatedModules: true,
},
},
- rootDir: "../..",
- roots: ["/sites/public"],
transform: {
"^.+\\.[t|j]sx?$": "ts-jest",
},
transformIgnorePatterns: ["node_modules/?!(@bloom-housing/ui-components)"],
setupFiles: ["dotenv/config"],
- setupFilesAfterEnv: ["/sites/public/.jest/setup-tests.js"],
+ setupFilesAfterEnv: ["../public/.jest/setup-tests.js"],
moduleNameMapper: {
"\\.(scss|css|less)$": "identity-obj-proxy",
},
diff --git a/sites/public/package.json b/sites/public/package.json
index ce221a5f39..5d3101152f 100644
--- a/sites/public/package.json
+++ b/sites/public/package.json
@@ -17,6 +17,7 @@
"test:headless": "concurrently \"yarn dev\" \"cypress run\"",
"test:coverage": "yarn nyc report --reporter=text-summary --check-coverage",
"test:unit": "jest -w 1",
+ "test:unit:coverage": "jest -w 1 --coverage --watchAll=false",
"start": "next start -p ${NEXTJS_PORT:-3000}",
"test:backend:core:dbsetup": "cd ../../ && yarn test:backend:core:dbsetup",
"dev:listings": "cd ../../backend/core && yarn dev",
@@ -69,6 +70,7 @@
"@types/react": "^18.0.33",
"concurrently": "^5.3.0",
"cypress": "^12.8.1",
+ "jest": "^26.5.3",
"js-levenshtein": "^1.1.6",
"nyc": "^15.1.0",
"postcss": "^8.3.6",
diff --git a/sites/public/src/lib/applications/AlternateContactStep.ts b/sites/public/src/lib/applications/AlternateContactStep.ts
index 779743b6a0..20f9e2ba54 100644
--- a/sites/public/src/lib/applications/AlternateContactStep.ts
+++ b/sites/public/src/lib/applications/AlternateContactStep.ts
@@ -2,6 +2,6 @@ import StepDefinition from "./StepDefinition"
export default class AlternateContactStep extends StepDefinition {
skipStep() {
- return this.application.alternateContact.type === "noContact"
+ return this.application.alternateContact?.type === "noContact"
}
}
diff --git a/sites/public/src/pages/applications/contact/alternate-contact-contact.tsx b/sites/public/src/pages/applications/contact/alternate-contact-contact.tsx
index 75e00ed10c..ad021c1cb5 100644
--- a/sites/public/src/pages/applications/contact/alternate-contact-contact.tsx
+++ b/sites/public/src/pages/applications/contact/alternate-contact-contact.tsx
@@ -16,7 +16,7 @@ import ApplicationFormLayout from "../../../layouts/application-form"
import FormsLayout from "../../../layouts/forms"
import styles from "../../../layouts/application-form.module.scss"
-export default () => {
+const ApplicationAlternateContactContact = () => {
const { profile } = useContext(AuthContext)
const { conductor, application, listing } = useFormConductor("alternateContactInfo")
const currentPageSection = 1
@@ -195,3 +195,5 @@ export default () => {
)
}
+
+export default ApplicationAlternateContactContact
diff --git a/sites/public/src/pages/applications/contact/alternate-contact-name.tsx b/sites/public/src/pages/applications/contact/alternate-contact-name.tsx
index 7d9da43195..36fd43ac3a 100644
--- a/sites/public/src/pages/applications/contact/alternate-contact-name.tsx
+++ b/sites/public/src/pages/applications/contact/alternate-contact-name.tsx
@@ -10,7 +10,7 @@ import { UserStatus } from "../../../lib/constants"
import ApplicationFormLayout from "../../../layouts/application-form"
import styles from "../../../layouts/application-form.module.scss"
-export default () => {
+const ApplicationAlternateContactName = () => {
const { profile } = useContext(AuthContext)
const { conductor, application, listing } = useFormConductor("alternateContactName")
const currentPageSection = 1
@@ -130,3 +130,5 @@ export default () => {
)
}
+
+export default ApplicationAlternateContactName
diff --git a/sites/public/src/pages/applications/household/live-alone.tsx b/sites/public/src/pages/applications/household/live-alone.tsx
index 0c8e759566..99076b11cc 100644
--- a/sites/public/src/pages/applications/household/live-alone.tsx
+++ b/sites/public/src/pages/applications/household/live-alone.tsx
@@ -40,11 +40,13 @@ const ApplicationLiveAlone = () => {
id: "householdSizeLiveAlone",
value: "liveAlone",
label: t("application.household.liveAlone.willLiveAlone"),
+ dataTestId: "app-household-live-alone",
},
{
id: "householdSizeLiveWithOthers",
value: "withOthers",
label: t("application.household.liveAlone.liveWithOtherPeople"),
+ dataTestId: "app-household-with-others",
},
]
diff --git a/sites/public/src/pages/applications/household/member.tsx b/sites/public/src/pages/applications/household/member.tsx
index 7b0bc501a5..0d88a29d53 100644
--- a/sites/public/src/pages/applications/household/member.tsx
+++ b/sites/public/src/pages/applications/household/member.tsx
@@ -84,8 +84,8 @@ const ApplicationMember = () => {
const router = useRouter()
const currentPageSection = 2
- if (router.query.memberId) {
- memberId = parseInt(router.query.memberId.toString())
+ if (router.query?.memberId) {
+ memberId = parseInt(router.query?.memberId.toString())
member = application.householdMember[memberId]
saveText = t("application.household.member.updateHouseholdMember")
cancelText = t("application.household.member.deleteThisPerson")
diff --git a/sites/public/src/pages/applications/review/demographics.tsx b/sites/public/src/pages/applications/review/demographics.tsx
index e846eda8d2..c7fb3618c2 100644
--- a/sites/public/src/pages/applications/review/demographics.tsx
+++ b/sites/public/src/pages/applications/review/demographics.tsx
@@ -78,7 +78,9 @@ const ApplicationDemographics = () => {
defaultChecked: isKeyIncluded(subKey, application.demographics?.race),
additionalText: subKey.indexOf("other") >= 0,
defaultText: getCustomValue(subKey, application.demographics?.race),
+ dataTestId: subKey,
})),
+ dataTestId: rootKey,
}))
}, [register])
diff --git a/sites/public/src/pages/disclaimer.tsx b/sites/public/src/pages/disclaimer.tsx
index 296ab702d9..f9a70770a8 100644
--- a/sites/public/src/pages/disclaimer.tsx
+++ b/sites/public/src/pages/disclaimer.tsx
@@ -23,7 +23,7 @@ const Disclaimer = () => {
- {pageContent}
+ {pageContent.toString()}
)
diff --git a/sites/public/src/pages/privacy.tsx b/sites/public/src/pages/privacy.tsx
index ed307ff5bc..b20006f739 100644
--- a/sites/public/src/pages/privacy.tsx
+++ b/sites/public/src/pages/privacy.tsx
@@ -23,7 +23,7 @@ const Privacy = () => {
- {pageContent}
+ {pageContent.toString()}
)
diff --git a/sites/public/tsconfig.json b/sites/public/tsconfig.json
index 406afd0400..1c1692c6aa 100644
--- a/sites/public/tsconfig.json
+++ b/sites/public/tsconfig.json
@@ -6,6 +6,6 @@
"allowJs": true,
"incremental": true
},
- "exclude": ["node_modules", "cypress"],
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
+ "exclude": ["node_modules", "cypress", "cypress-file-upload"],
+ "include": ["next-env.d.ts", "src/**/*.ts", "src/**/*.tsx"]
}
diff --git a/sites/public/tsconfig.test.json b/sites/public/tsconfig.test.json
index 6727d07ce2..4fd5045d7d 100644
--- a/sites/public/tsconfig.test.json
+++ b/sites/public/tsconfig.test.json
@@ -1,7 +1,6 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
- "jsx": "react"
- },
- "include": ["next-env.d.ts", "src/**/*.ts", "src/**/*.tsx"]
+ "jsx": "react-jsx"
+ }
}