diff --git a/src/applications/hca/components/FormPages/FinancialInformation.jsx b/src/applications/hca/components/FormPages/FinancialInformation.jsx index da80fd0c9d97..6106b75a9e7b 100644 --- a/src/applications/hca/components/FormPages/FinancialInformation.jsx +++ b/src/applications/hca/components/FormPages/FinancialInformation.jsx @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import FormNavButtons from '~/platform/forms-system/src/js/components/FormNavButtons'; +import FormNavButtons from 'platform/forms-system/src/js/components/FormNavButtons'; import { LAST_YEAR } from '../../utils/constants'; const HouseholdFinancialOnboarding = props => { diff --git a/src/applications/hca/components/FormPages/FinancialOnboarding.jsx b/src/applications/hca/components/FormPages/FinancialOnboarding.jsx index 0a4ed5a5d4a4..51bb36bbb460 100644 --- a/src/applications/hca/components/FormPages/FinancialOnboarding.jsx +++ b/src/applications/hca/components/FormPages/FinancialOnboarding.jsx @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import FormNavButtons from '~/platform/forms-system/src/js/components/FormNavButtons'; +import FormNavButtons from 'platform/forms-system/src/js/components/FormNavButtons'; import EnhancedEligibilityDescription from '../FormDescriptions/EnhancedEligibilityDescription'; import { LAST_YEAR } from '../../utils/constants'; diff --git a/src/applications/hca/components/FormPages/InsuranceInformation.jsx b/src/applications/hca/components/FormPages/InsuranceInformation.jsx index 9153e7bd12da..2d344790e6da 100644 --- a/src/applications/hca/components/FormPages/InsuranceInformation.jsx +++ b/src/applications/hca/components/FormPages/InsuranceInformation.jsx @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import FormNavButtons from '~/platform/forms-system/src/js/components/FormNavButtons'; +import FormNavButtons from 'platform/forms-system/src/js/components/FormNavButtons'; const InsuranceInformation = props => { const { diff --git a/src/applications/hca/tests/unit/components/FormFields/VaMedicalCenter.unit.spec.js b/src/applications/hca/tests/unit/components/FormFields/VaMedicalCenter.unit.spec.js index 8890053f7e8e..271138b500f2 100644 --- a/src/applications/hca/tests/unit/components/FormFields/VaMedicalCenter.unit.spec.js +++ b/src/applications/hca/tests/unit/components/FormFields/VaMedicalCenter.unit.spec.js @@ -1,27 +1,27 @@ import React from 'react'; import { Provider } from 'react-redux'; -import { render, waitFor } from '@testing-library/react'; +import { fireEvent, render, waitFor } from '@testing-library/react'; +import * as Sentry from '@sentry/browser'; import { expect } from 'chai'; import sinon from 'sinon'; import { mockApiRequest, setFetchJSONResponse, } from 'platform/testing/unit/helpers'; - import VaMedicalCenter from '../../../../components/FormFields/VaMedicalCenter'; describe('hca ', () => { const mockData = [ - { - id: 'vha_528A4', - uniqueId: '528A4', - name: 'ZBatavia VA Medical Center', - }, { id: 'vha_528A5', uniqueId: '528A5', name: 'Canandaigua VA Medical Center', }, + { + id: 'vha_528A4', + uniqueId: '528A4', + name: 'Batavia VA Medical Center', + }, ]; const getData = ({ reviewMode = false, @@ -56,44 +56,47 @@ describe('hca ', () => { }, }, }); - - context('when the component renders on form page', () => { - const { mockStore, props } = getData({}); - - it('should render both `va-select` fields', () => { - const { container } = render( - - - , - ); - const stateSelector = container.querySelector( + const subject = ({ mockStore, props }) => { + const { container } = render( + + + , + ); + const selectors = () => ({ + stateField: container.querySelector( `#${props.idSchema['view:facilityState'].$id}`, - ); - expect(stateSelector).to.exist; - const facilitySelector = container.querySelector( + ), + facilityField: container.querySelector( `#${props.idSchema.vaMedicalFacility.$id}`, - ); - expect(facilitySelector).to.exist; - }); - - it('should not render the containers from review mode', () => { - const { container } = render( - - - , - ); - const stateSelector = container.querySelector( + ), + facilityOptions: container.querySelectorAll( + `#${props.idSchema.vaMedicalFacility.$id} option`, + ), + stateReviewField: container.querySelector( '[data-testid="hca-facility-state"]', - ); - expect(stateSelector).to.not.exist; - const facilitySelector = container.querySelector( + ), + facilityReviewField: container.querySelector( '[data-testid="hca-facility-name"]', - ); - expect(facilitySelector).to.not.exist; + ), + vaAlert: container.querySelector('va-alert'), + vaSelect: container.querySelectorAll('va-select'), + vaLoadingIndicator: container.querySelector('va-loading-indicator'), }); + return { container, selectors }; + }; + + it('should render appropriate components when not in review mode', () => { + const { mockStore, props } = getData({}); + const { selectors } = subject({ mockStore, props }); + const components = selectors(); + expect(components.stateField).to.exist; + expect(components.facilityField).to.exist; + expect(components.stateReviewField).to.not.exist; + expect(components.facilityReviewField).to.not.exist; }); - context('when the component renders in review mode', () => { + it('should render appropriate components when in review mode', async () => { + mockApiRequest(mockData); const { mockStore, props } = getData({ formData: { 'view:facilityState': 'NY', @@ -101,239 +104,128 @@ describe('hca ', () => { }, reviewMode: true, }); - - it('should render the correct state and facility name', async () => { - mockApiRequest(mockData); - const { container } = render( - - - , - ); - - const stateSelector = container.querySelector( - '[data-testid="hca-facility-state"]', - ); - await waitFor(() => { - expect(stateSelector).to.contain.text('New York'); - }); - - const facilitySelector = container.querySelector( - '[data-testid="hca-facility-name"]', - ); - await waitFor(() => { - expect(facilitySelector).to.contain.text(mockData[1].name); - }); + const { selectors } = subject({ mockStore, props }); + + await waitFor(() => { + const components = selectors(); + expect(components.vaAlert).to.not.exist; + expect(components.vaLoadingIndicator).to.not.exist; + expect(components.vaSelect).to.have.lengthOf(0); + expect(components.stateReviewField).to.contain.text('New York'); + expect(components.facilityReviewField).to.contain.text(mockData[1].name); }); + }); - it('should not render the loading indicator', async () => { - mockApiRequest(mockData); - const { container } = render( - - - , - ); - const selector = container.querySelector('va-loading-indicator'); - await waitFor(() => { - expect(selector).to.not.exist; - }); + it('should correctly handle errors when the facility API call fails', async () => { + mockApiRequest(mockData, false); + setFetchJSONResponse( + global.fetch.onCall(0), + // eslint-disable-next-line prefer-promise-reject-errors + Promise.reject({ status: 503, error: 'error' }), + ); + const { mockStore, props } = getData({ + formData: { 'view:facilityState': 'NY' }, }); - - it('should not render the select input', async () => { - mockApiRequest(mockData); - const { container } = render( - - - , - ); - const selector = container.querySelector('va-select'); - await waitFor(() => { - expect(selector).to.not.exist; - }); + const spy = sinon.spy(Sentry, 'withScope'); + const { selectors } = subject({ mockStore, props }); + + await waitFor(() => { + const { stateField, facilityField, vaAlert } = selectors(); + expect(stateField).to.not.exist; + expect(facilityField).to.not.exist; + expect(vaAlert).to.exist; }); - it('should not render the server error alert', async () => { - mockApiRequest(mockData); - const { container } = render( - - - , - ); - const selector = container.querySelector('va-alert'); - await waitFor(() => { - expect(selector).to.not.exist; - }); + await waitFor(() => { + expect(spy.called).to.be.true; + spy.restore(); }); }); - context('when the user selects a facility state', () => { - it('should render the correct number of options, resorted in alphabetical order by name, if API call succeeds', async () => { - mockApiRequest(mockData); - const { mockStore, props } = getData({ - formData: { 'view:facilityState': 'NY' }, - }); - const { container } = render( - - - , - ); - - await waitFor(() => { - const options = container.querySelectorAll( - `#${props.idSchema.vaMedicalFacility.$id} option`, - ); - const alert = container.querySelector('va-alert'); - - expect(options).to.have.lengthOf(mockData.length); - expect(options[0]).to.have.attr('value', mockData[1].uniqueId); - expect(options[1]).to.have.attr('value', mockData[0].uniqueId); - expect(alert).to.not.exist; - }); + it('should render an alphabetized option list when facility API call succeeds', async () => { + mockApiRequest(mockData); + const { mockStore, props } = getData({ + formData: { 'view:facilityState': 'NY' }, }); - - it('should render the error alert if API call fails', async () => { - mockApiRequest(mockData, false); - setFetchJSONResponse( - global.fetch.onCall(0), - // eslint-disable-next-line prefer-promise-reject-errors - Promise.reject({ status: 503, error: 'error' }), - ); - const { mockStore, props } = getData({ - formData: { 'view:facilityState': 'NY' }, - }); - const { container } = render( - - - , - ); - await waitFor(() => { - const vaSelectState = container.querySelector( - `#${props.idSchema['view:facilityState'].$id}`, - ); - const vaSelectFacility = container.querySelector( - `#${props.idSchema.vaMedicalFacility.$id}`, - ); - const alert = container.querySelector('va-alert'); - - expect(vaSelectState).to.not.exist; - expect(vaSelectFacility).to.not.exist; - expect(alert).to.exist; - }); + const { selectors } = subject({ mockStore, props }); + + await waitFor(() => { + const { facilityOptions, vaAlert } = selectors(); + expect(vaAlert).to.not.exist; + expect(facilityOptions).to.have.lengthOf(mockData.length); + expect(facilityOptions[0]).to.have.attr('value', mockData[1].uniqueId); + expect(facilityOptions[1]).to.have.attr('value', mockData[0].uniqueId); }); }); - context('when the user selects a facility from the list', () => { - it('should call the `onChange` spy', async () => { - mockApiRequest(mockData); - const { mockStore, props } = getData({ - formData: { 'view:facilityState': 'NY' }, + it('should fire the `onChange` spy when the user selects a facility from the list', async () => { + mockApiRequest(mockData); + const { mockStore, props } = getData({ + formData: { 'view:facilityState': 'NY' }, + }); + const { selectors } = subject({ mockStore, props }); + + await waitFor(() => { + const { facilityField } = selectors(); + facilityField.__events.vaSelect({ + target: { + name: props.idSchema.vaMedicalFacility.$id, + value: mockData[1].id, + }, }); - const { container } = render( - - - , - ); + expect(props.onChange.called).to.be.true; + }); - await waitFor(() => { - const selector = container.querySelector( - `#${props.idSchema.vaMedicalFacility.$id}`, - ); + await waitFor(() => { + const { facilityField } = selectors(); + fireEvent.blur(facilityField); + expect(facilityField).to.not.have.attr('error'); + }); + }); - selector.__events.vaSelect({ - target: { - name: props.idSchema.vaMedicalFacility.$id, - value: mockData[1].id, - }, - }); + it('should correctly handle errors when the form is submitted without a selected facility', async () => { + const { mockStore, props } = getData({ + formData: {}, + submitted: true, + }); + const { selectors } = subject({ mockStore, props }); - expect(props.onChange.called).to.be.true; - }); + await waitFor(() => { + const { facilityField } = selectors(); + expect(facilityField).to.have.attr('error'); }); }); - context( - 'when the form is submitted without a selected facility', - async () => { - it('should render an error message on the facility field', async () => { - const { mockStore, props } = getData({ - formData: {}, - submitted: true, - }); - const { container } = render( - - - , - ); - await waitFor(() => { - const selector = container.querySelector( - `#${props.idSchema.vaMedicalFacility.$id}`, - ); - expect(selector).to.have.attr('error', 'Please provide a response'); - }); - }); - }, - ); + it('should correctly handle errors when the form is submitted without a selected state or facility', async () => { + const { mockStore, props } = getData({ + formData: {}, + submitted: true, + }); + const { selectors } = subject({ mockStore, props }); - context('when submitted without a selected state or facility', async () => { - it('should render error messages for both fields', async () => { - const { mockStore, props } = getData({ - formData: {}, - submitted: true, - }); - const { container } = render( - - - , - ); - await waitFor(() => { - const vaSelectState = container.querySelector( - `#${props.idSchema['view:facilityState'].$id}`, - ); - const vaSelectFacility = container.querySelector( - `#${props.idSchema.vaMedicalFacility.$id}`, - ); - expect(vaSelectState).to.have.attr( - 'error', - 'Please provide a response', - ); - expect(vaSelectFacility).to.have.attr( - 'error', - 'Please provide a response', - ); - }); + await waitFor(() => { + const { stateField, facilityField } = selectors(); + expect(stateField).to.have.attr('error'); + expect(facilityField).to.have.attr('error'); }); }); - context( - 'when the form is submitted with both state and facility selected', - async () => { - it('should not render error messages', async () => { - mockApiRequest(mockData); - const { mockStore, props } = getData({ - formData: { - 'view:facilityState': 'NY', - vaMedicalFacility: mockData[0].uniqueId, - }, - submitted: true, - }); - const { container } = render( - - - , - ); - await waitFor(() => { - const vaSelectState = container.querySelector( - `#${props.idSchema['view:facilityState'].$id}`, - ); - const vaSelectFacility = container.querySelector( - `#${props.idSchema.vaMedicalFacility.$id}`, - ); - const alert = container.querySelector('va-alert'); + it('should correctly behave when the form is submitted with both state and facility selected', async () => { + mockApiRequest(mockData); + const { mockStore, props } = getData({ + formData: { + 'view:facilityState': 'NY', + vaMedicalFacility: mockData[0].uniqueId, + }, + submitted: true, + }); + const { selectors } = subject({ mockStore, props }); - expect(alert).to.not.exist; - expect(vaSelectState).to.not.have.attr('error'); - expect(vaSelectFacility).to.not.have.attr('error'); - }); - }); - }, - ); + await waitFor(() => { + const { stateField, facilityField, vaAlert } = selectors(); + expect(vaAlert).to.not.exist; + expect(stateField).to.not.have.attr('error'); + expect(facilityField).to.not.have.attr('error'); + }); + }); }); diff --git a/src/applications/hca/tests/unit/components/FormPages/DisabilityConfirmation.unit.spec.js b/src/applications/hca/tests/unit/components/FormPages/DisabilityConfirmation.unit.spec.js index 58c78cf4f731..d315bcbbbb8b 100644 --- a/src/applications/hca/tests/unit/components/FormPages/DisabilityConfirmation.unit.spec.js +++ b/src/applications/hca/tests/unit/components/FormPages/DisabilityConfirmation.unit.spec.js @@ -2,41 +2,33 @@ import React from 'react'; import { fireEvent, render } from '@testing-library/react'; import { expect } from 'chai'; import sinon from 'sinon'; - import DisabilityConfirmation from '../../../../components/FormPages/DisabilityConfirmation'; describe('hca Disability Confirmation page', () => { - const getData = () => ({ - props: { data: {}, goBack: () => {}, goForward: sinon.spy() }, - }); - - context('when the component renders', () => { - const { props } = getData(); - - it('should render `va-alert` with correct status', () => { - const { container } = render(); - const selector = container.querySelector('va-alert'); - expect(selector).to.exist; - expect(selector).to.have.attr('status', 'info'); - }); - - it('should render navigation buttons', () => { - const { container } = render(); - expect( - container.querySelectorAll('.hca-button-progress'), - ).to.have.lengthOf(2); + const subject = ({ goForward = () => {} }) => { + const props = { data: {}, goBack: () => {}, goForward }; + const { container } = render(); + const selectors = () => ({ + vaAlert: container.querySelector('va-alert'), + navBtns: container.querySelectorAll('.hca-button-progress'), + continueBtn: container.querySelector('.usa-button-primary'), }); + return { container, selectors }; + }; + + it('should render the page with content and navigation buttons', () => { + const { selectors } = subject({}); + const { vaAlert, navBtns } = selectors(); + expect(vaAlert).to.exist; + expect(vaAlert).to.have.attr('status', 'info'); + expect(navBtns).to.have.lengthOf(2); }); - context('when the `Continue` button is clicked', () => { - const { props } = getData(); - - it('should call the `goForward` spy', () => { - const { container } = render(); - const selector = container.querySelector('.usa-button-primary'); - - fireEvent.click(selector); - expect(props.goForward.called).to.be.true; - }); + it('should call the `goForward` spy when the `Continue` button is clicked', () => { + const goForwardSpy = sinon.spy(); + const { selectors } = subject({ goForward: goForwardSpy }); + const { continueBtn } = selectors(); + fireEvent.click(continueBtn); + expect(goForwardSpy.called).to.be.true; }); }); diff --git a/src/applications/hca/tests/unit/components/FormPages/FinancialConfirmation.unit.spec.js b/src/applications/hca/tests/unit/components/FormPages/FinancialConfirmation.unit.spec.js index 520f8ef5ab2d..e227c1b77a8a 100644 --- a/src/applications/hca/tests/unit/components/FormPages/FinancialConfirmation.unit.spec.js +++ b/src/applications/hca/tests/unit/components/FormPages/FinancialConfirmation.unit.spec.js @@ -1,29 +1,24 @@ import React from 'react'; import { render } from '@testing-library/react'; import { expect } from 'chai'; - import FinancialConfirmation from '../../../../components/FormPages/FinancialConfirmation'; describe('hca Financial Confirmation page', () => { - const getData = () => ({ - props: { data: {}, goBack: () => {}, goForward: () => {} }, - }); - - context('when the component renders', () => { - const { props } = getData(); - - it('should render `va-alert` with correct status', () => { - const { container } = render(); - const selector = container.querySelector('va-alert'); - expect(selector).to.exist; - expect(selector).to.have.attr('status', 'info'); + const subject = () => { + const props = { data: {}, goBack: () => {}, goForward: () => {} }; + const { container } = render(); + const selectors = () => ({ + vaAlert: container.querySelector('va-alert'), + navBtns: container.querySelectorAll('.hca-button-progress'), }); + return { container, selectors }; + }; - it('should render navigation buttons', () => { - const { container } = render(); - expect( - container.querySelectorAll('.hca-button-progress'), - ).to.have.lengthOf(2); - }); + it('should render the page with content and navigation buttons', () => { + const { selectors } = subject(); + const { vaAlert, navBtns } = selectors(); + expect(vaAlert).to.exist; + expect(vaAlert).to.have.attr('status', 'info'); + expect(navBtns).to.have.lengthOf(2); }); }); diff --git a/src/applications/hca/tests/unit/components/FormPages/FinancialInformation.unit.spec.js b/src/applications/hca/tests/unit/components/FormPages/FinancialInformation.unit.spec.js index 929696c59e9c..642eb912c711 100644 --- a/src/applications/hca/tests/unit/components/FormPages/FinancialInformation.unit.spec.js +++ b/src/applications/hca/tests/unit/components/FormPages/FinancialInformation.unit.spec.js @@ -1,30 +1,24 @@ import React from 'react'; import { render } from '@testing-library/react'; import { expect } from 'chai'; - import FinancialInformation from '../../../../components/FormPages/FinancialInformation'; describe('hca Financial Information page', () => { - const getData = () => ({ - props: { data: {}, goBack: () => {}, goForward: () => {} }, - }); - - context('when the component renders', () => { - const { props } = getData(); - - it('should render with correct title', () => { - const { container } = render(); - const selector = container.querySelector( - '[data-testid="hca-custom-page-title"]', - ); - expect(selector).to.exist; - expect(selector).to.contain.text('Financial information you’ll need'); + const subject = () => { + const props = { data: {}, goBack: () => {}, goForward: () => {} }; + const { container } = render(); + const selectors = () => ({ + continueBtn: container.querySelector('.usa-button-primary'), + backBtn: container.querySelector('.usa-button-secondary'), }); + return { container, selectors }; + }; - it('should render navigation buttons', () => { - const { container } = render(); - expect(container.querySelector('.usa-button-primary')).to.exist; - expect(container.querySelector('.usa-button-secondary')).to.exist; - }); + it('should render the page with content and navigation buttons', () => { + const { container, selectors } = subject(); + const { continueBtn, backBtn } = selectors(); + expect(container).to.not.be.empty; + expect(continueBtn).to.exist; + expect(backBtn).to.exist; }); }); diff --git a/src/applications/hca/tests/unit/components/FormPages/FinancialOnboarding.unit.spec.js b/src/applications/hca/tests/unit/components/FormPages/FinancialOnboarding.unit.spec.js index 2f5a60b4d649..9b4e56e3a545 100644 --- a/src/applications/hca/tests/unit/components/FormPages/FinancialOnboarding.unit.spec.js +++ b/src/applications/hca/tests/unit/components/FormPages/FinancialOnboarding.unit.spec.js @@ -1,32 +1,24 @@ import React from 'react'; import { render } from '@testing-library/react'; import { expect } from 'chai'; - import FinancialOnboarding from '../../../../components/FormPages/FinancialOnboarding'; describe('hca Financial Onboarding page', () => { - const getData = () => ({ - props: { data: {}, goBack: () => {}, goForward: () => {} }, - }); - - context('when the component renders', () => { - const { props } = getData(); - - it('should render with correct title', () => { - const { container } = render(); - const selector = container.querySelector( - '[data-testid="hca-custom-page-title"]', - ); - expect(selector).to.exist; - expect(selector).to.contain.text( - 'How we use your household financial information', - ); + const subject = () => { + const props = { data: {}, goBack: () => {}, goForward: () => {} }; + const { container } = render(); + const selectors = () => ({ + continueBtn: container.querySelector('.usa-button-primary'), + backBtn: container.querySelector('.usa-button-secondary'), }); + return { container, selectors }; + }; - it('should render navigation buttons', () => { - const { container } = render(); - expect(container.querySelector('.usa-button-primary')).to.exist; - expect(container.querySelector('.usa-button-secondary')).to.exist; - }); + it('should render the page with content and navigation buttons', () => { + const { container, selectors } = subject(); + const { continueBtn, backBtn } = selectors(); + expect(container).to.not.be.empty; + expect(continueBtn).to.exist; + expect(backBtn).to.exist; }); }); diff --git a/src/applications/hca/tests/unit/components/FormPages/InsuranceInformation.unit.spec.js b/src/applications/hca/tests/unit/components/FormPages/InsuranceInformation.unit.spec.js new file mode 100644 index 000000000000..b95e7d2a4cc0 --- /dev/null +++ b/src/applications/hca/tests/unit/components/FormPages/InsuranceInformation.unit.spec.js @@ -0,0 +1,24 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import { expect } from 'chai'; +import InsuranceInformation from '../../../../components/FormPages/InsuranceInformation'; + +describe('hca Insurance Information page', () => { + const subject = () => { + const props = { data: {}, goBack: () => {}, goForward: () => {} }; + const { container } = render(); + const selectors = () => ({ + continueBtn: container.querySelector('.usa-button-primary'), + backBtn: container.querySelector('.usa-button-secondary'), + }); + return { container, selectors }; + }; + + it('should render the page with content and navigation buttons', () => { + const { container, selectors } = subject(); + const { continueBtn, backBtn } = selectors(); + expect(container).to.not.be.empty; + expect(continueBtn).to.exist; + expect(backBtn).to.exist; + }); +});