From 414ddff0f940e1e586864567973ceb3f66b60075 Mon Sep 17 00:00:00 2001 From: Liz Wendling <170662489+GovCIOLiz@users.noreply.github.com> Date: Tue, 24 Dec 2024 10:43:56 -0800 Subject: [PATCH 1/4] Spelling mistake --- src/applications/edu-benefits/10215/pages/program-intro.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/edu-benefits/10215/pages/program-intro.js b/src/applications/edu-benefits/10215/pages/program-intro.js index 82394360338a..a9c0c03f5455 100644 --- a/src/applications/edu-benefits/10215/pages/program-intro.js +++ b/src/applications/edu-benefits/10215/pages/program-intro.js @@ -13,7 +13,7 @@ const ProgramIntro = { On the next several pages, you will provide all 85/15 calculations for your institution. Submit calculations for all approved programs listed on your most recent WEAMS-22-1998 Report. List every program and - iclude calculations, even if a program has a Supported Student or + include calculations, even if a program has a Supported Student or Total Enrollment of "0".

From 1a8d7c070af87adf2430a95cb4ea23b6973eff6c Mon Sep 17 00:00:00 2001 From: Liz Wendling <170662489+GovCIOLiz@users.noreply.github.com> Date: Thu, 26 Dec 2024 12:07:52 -0800 Subject: [PATCH 2/4] 10215 calcs page --- .../edu-benefits/10215/pages/calcs.js | 74 +++++++++++++++++-- 1 file changed, 66 insertions(+), 8 deletions(-) diff --git a/src/applications/edu-benefits/10215/pages/calcs.js b/src/applications/edu-benefits/10215/pages/calcs.js index 170cf7178fb9..c3b07710efd5 100644 --- a/src/applications/edu-benefits/10215/pages/calcs.js +++ b/src/applications/edu-benefits/10215/pages/calcs.js @@ -1,21 +1,79 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; +import { querySelectorWithShadowRoot } from 'platform/utilities/ui/webComponents'; import { getFTECalcs } from '../helpers'; const Calcs = ({ data }) => { - const programIdx = window.location.href.split('?')[0].slice(-1); - const program = data.programs?.[programIdx]; - const { supported, nonSupported, total, supportedFTEPercent } = getFTECalcs( - program, - ); + const [programData, setProgramData] = useState(null); + // + // Form data in redux not updated promptly when inputting data in edit mode hence the following code is necessary at present rather than relying on state.form.data + // + async function updateData() { + const supportedInput = await querySelectorWithShadowRoot( + 'va-text-input[name="root_fte_supported"]', + document, + ); + const supportedInputValue = supportedInput?.shadowRoot.querySelector( + 'input', + ).value; + const nonSupportedInput = await querySelectorWithShadowRoot( + 'va-text-input[name="root_fte_nonSupported"]', + document, + ); + const nonSupportedInputValue = nonSupportedInput?.shadowRoot.querySelector( + 'input', + ).value; + const fteData = { + fte: { + supported: supportedInputValue, + nonSupported: nonSupportedInputValue, + }, + }; + if (fteData !== programData) setProgramData(getFTECalcs(fteData)); + } + + useEffect(() => { + let supportedInput; + let nonSupportedInput; + + async function getInputs() { + supportedInput = await querySelectorWithShadowRoot( + 'va-text-input[name="root_fte_supported"]', + document, + ); + supportedInput = supportedInput?.shadowRoot?.querySelector('input'); + nonSupportedInput = await querySelectorWithShadowRoot( + 'va-text-input[name="root_fte_nonSupported"]', + document, + ); + nonSupportedInput = nonSupportedInput?.shadowRoot?.querySelector('input'); + supportedInput?.addEventListener('change', updateData); + nonSupportedInput?.addEventListener('change', updateData); + } + + if (!programData && data) { + const programIdx = window.location.href.split('?')[0].slice(-1); + const program = data.programs?.[programIdx]; + setProgramData(getFTECalcs(program)); + } + + getInputs(); + + return function cleanup() { + supportedInput.removeEventListener('change', updateData); + nonSupportedInput.removeEventListener('change', updateData); + }; + }, []); return ( <>

- {supported || nonSupported ? total : '--'} + {programData?.supported || programData?.nonSupported + ? programData?.total + : '--'}
@@ -34,7 +92,7 @@ const Calcs = ({ data }) => { Supported student percentage FTE - {supportedFTEPercent || '--%'} + {programData?.supportedFTEPercent || '--%'} From fd89ab0ea24bea00566e13533efa713b0e4e94d1 Mon Sep 17 00:00:00 2001 From: Liz Wendling <170662489+GovCIOLiz@users.noreply.github.com> Date: Thu, 26 Dec 2024 12:13:02 -0800 Subject: [PATCH 3/4] Review page submit btn custom text --- src/applications/edu-benefits/10215/config/form.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/applications/edu-benefits/10215/config/form.js b/src/applications/edu-benefits/10215/config/form.js index beb310342e23..034a7c015bd9 100644 --- a/src/applications/edu-benefits/10215/config/form.js +++ b/src/applications/edu-benefits/10215/config/form.js @@ -46,6 +46,9 @@ const formConfig = { saveInProgress: {}, version: 0, prefillEnabled: true, + customText: { + submitButtonText: 'Continue', + }, savedFormMessages: { notFound: 'Please start over to apply for new form benefits.', noAuth: From b44083c8ee707a4bef58f02c882c8f61743df5f5 Mon Sep 17 00:00:00 2001 From: wafimohamed <158514667+wafimohamed@users.noreply.github.com> Date: Fri, 27 Dec 2024 16:02:31 -0500 Subject: [PATCH 4/4] added more unit test to bring coverage up (above 80%) --- .../10215/containers/ConfirmationPage.jsx | 13 +- .../edu-benefits/10215/pages/calcs.js | 16 +- .../containers/ConfirmationPage.unit.spec.jsx | 17 +- .../10215/tests/pages/calcs.unit.spec.js | 168 +++++++++++++----- 4 files changed, 157 insertions(+), 57 deletions(-) diff --git a/src/applications/edu-benefits/10215/containers/ConfirmationPage.jsx b/src/applications/edu-benefits/10215/containers/ConfirmationPage.jsx index af9e1f5cda83..08bf4e7623af 100644 --- a/src/applications/edu-benefits/10215/containers/ConfirmationPage.jsx +++ b/src/applications/edu-benefits/10215/containers/ConfirmationPage.jsx @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { connect, useSelector } from 'react-redux'; +import { useSelector } from 'react-redux'; import { ConfirmationView } from 'platform/forms-system/src/js/components/ConfirmationView'; const childContent = ( @@ -54,6 +54,7 @@ const childContent = ( window.print()} />

@@ -75,7 +76,7 @@ const childContent = ( ); export const ConfirmationPage = props => { - const form = useSelector(state => state.form || {}); + const form = useSelector(state => state?.form); const { submission } = form; const submitDate = submission.timestamp; @@ -113,10 +114,4 @@ ConfirmationPage.propTypes = { route: PropTypes.object, }; -function mapStateToProps(state) { - return { - form: state.form, - }; -} - -export default connect(mapStateToProps)(ConfirmationPage); +export default ConfirmationPage; diff --git a/src/applications/edu-benefits/10215/pages/calcs.js b/src/applications/edu-benefits/10215/pages/calcs.js index c3b07710efd5..8a5d6141991f 100644 --- a/src/applications/edu-benefits/10215/pages/calcs.js +++ b/src/applications/edu-benefits/10215/pages/calcs.js @@ -69,8 +69,13 @@ const Calcs = ({ data }) => { return ( <>
- - + + {programData?.supported || programData?.nonSupported ? programData?.total : '--'} @@ -88,10 +93,13 @@ const Calcs = ({ data }) => {

-
diff --git a/src/applications/edu-benefits/10215/tests/containers/ConfirmationPage.unit.spec.jsx b/src/applications/edu-benefits/10215/tests/containers/ConfirmationPage.unit.spec.jsx index b72405493341..99692989670e 100644 --- a/src/applications/edu-benefits/10215/tests/containers/ConfirmationPage.unit.spec.jsx +++ b/src/applications/edu-benefits/10215/tests/containers/ConfirmationPage.unit.spec.jsx @@ -1,10 +1,11 @@ import React from 'react'; import { expect } from 'chai'; +import sinon from 'sinon'; import { Provider } from 'react-redux'; -import { render } from '@testing-library/react'; +import { fireEvent, render } from '@testing-library/react'; import configureStore from 'redux-mock-store'; import thunk from 'redux-thunk'; -import { ConfirmationPage } from '../../containers/ConfirmationPage'; +import ConfirmationPage from '../../containers/ConfirmationPage'; const storeBase = { form: { @@ -35,4 +36,16 @@ describe('', () => { ); expect(container).to.exist; }); + it('should print the page', () => { + const printSpy = sinon.spy(window, 'print'); + const { getByTestId } = render( + + + , + ); + expect(getByTestId('print-page')).to.exist; + fireEvent.click(getByTestId('print-page')); + expect(printSpy.calledOnce).to.be.true; + printSpy.restore(); + }); }); diff --git a/src/applications/edu-benefits/10215/tests/pages/calcs.unit.spec.js b/src/applications/edu-benefits/10215/tests/pages/calcs.unit.spec.js index f837cf73031a..1d3af07abdbf 100644 --- a/src/applications/edu-benefits/10215/tests/pages/calcs.unit.spec.js +++ b/src/applications/edu-benefits/10215/tests/pages/calcs.unit.spec.js @@ -1,14 +1,19 @@ -// src/applications/edu-benefits/10215/pages/calcs.test.js import React from 'react'; -import { mount } from 'enzyme'; import { expect } from 'chai'; import { Provider } from 'react-redux'; import configureStore from 'redux-mock-store'; +import { render, waitFor } from '@testing-library/react'; +import sinon from 'sinon'; +import * as webComponents from 'platform/utilities/ui/webComponents'; import Calcs from '../../pages/calcs'; +import * as helpers from '../../helpers'; const mockStore = configureStore(); describe('', () => { + let querySelectorStub; + let getFTECalcsStub; + const mockData = { programs: [ { @@ -17,65 +22,144 @@ describe('', () => { total: 10, supportedFTEPercent: 100, }, + { + supported: true, + nonSupported: true, + total: 20, + supportedFTEPercent: 50, + }, ], }; + beforeEach(() => { + querySelectorStub = sinon.stub( + webComponents, + 'querySelectorWithShadowRoot', + ); + getFTECalcsStub = sinon.stub(helpers, 'getFTECalcs').returns({ + total: 8, + supportedFTEPercent: '62.5%', + }); + }); + + afterEach(() => { + querySelectorStub.restore(); + getFTECalcsStub.restore(); + }); + it('should render correctly with given props', () => { const store = mockStore({ form: { data: mockData } }); - const wrapper = mount( + const { getByTestId } = render( , ); - expect( - wrapper - .find('label') - .at(0) - .text(), - ).to.equal('Total Enrolled FTE'); - expect( - wrapper - .find('span') - .at(0) - .text(), - ).to.equal('--'); - expect( - wrapper - .find('label') - .at(1) - .text(), - ).to.equal('Supported student percentage FTE'); - expect( - wrapper - .find('span') - .at(1) - .text(), - ).to.equal('--%'); - wrapper.unmount(); + expect(getByTestId('num-fte').textContent).to.equal('Total Enrolled FTE'); + expect(getByTestId('nonSupported').textContent).to.equal('--'); + expect(getByTestId('percentage-FTE').textContent).to.equal( + 'Supported student percentage FTE', + ); + expect(getByTestId('supportedFTEPercent').textContent).to.equal('62.5%'); }); it('should render "--" when no data is available', () => { const emptyData = { programs: [] }; const store = mockStore({ form: { data: emptyData } }); - const wrapper = mount( + const { getByTestId } = render( , ); - expect( - wrapper - .find('span') - .at(0) - .text(), - ).to.equal('--'); - expect( - wrapper - .find('span') - .at(1) - .text(), - ).to.equal('--%'); - wrapper.unmount(); + expect(getByTestId('nonSupported').textContent).to.equal('--'); + expect(getByTestId('supportedFTEPercent').textContent).to.equal('62.5%'); + }); + + it('should update programData when updateData is called', async () => { + const store = mockStore({ form: { data: mockData } }); + const mockSupportedInput = { shadowRoot: { querySelector: sinon.stub() } }; + const mockNonSupportedInput = { + shadowRoot: { querySelector: sinon.stub() }, + }; + + mockSupportedInput.shadowRoot.querySelector + .withArgs('input') + .returns({ value: '5' }); + mockNonSupportedInput.shadowRoot.querySelector + .withArgs('input') + .returns({ value: '3' }); + + querySelectorStub + .withArgs('va-text-input[name="root_fte_supported"]', document) + .resolves(mockSupportedInput); + querySelectorStub + .withArgs('va-text-input[name="root_fte_nonSupported"]', document) + .resolves(mockNonSupportedInput); + + const { getByTestId } = render( + + + , + ); + + await webComponents.querySelectorWithShadowRoot(); + + expect(getByTestId('nonSupported').textContent).to.equal('--'); + expect(getByTestId('supportedFTEPercent').textContent).to.equal('62.5%'); + }); + it('should set programData if none exists and data is provided', async () => { + const data = { + programs: [ + { + supported: 'initialValue1', + nonSupported: 'initialValue2', + }, + { + supported: '3', + nonSupported: '5', + }, + ], + }; + const store2 = mockStore({ form: { data } }); + const mockSupportedInput = { + shadowRoot: { + querySelector: sinon.stub().returns({ value: '5' }), + }, + }; + + const mockNonSupportedInput = { + shadowRoot: { + querySelector: sinon.stub().returns({ value: '3' }), + }, + }; + + querySelectorStub + .withArgs('va-text-input[name="root_fte_supported"]', document) + .resolves(mockSupportedInput); + querySelectorStub + .withArgs('va-text-input[name="root_fte_nonSupported"]', document) + .resolves(mockNonSupportedInput); + + const originalLocation = window.location; + delete window.location; + Object.defineProperty(window, 'location', { + value: { ...originalLocation, href: 'https://fake.url/somePage1' }, + writable: true, + }); + render( + + + , + ); + + await waitFor(() => { + const lastCallArg = getFTECalcsStub.lastCall.args[0]; + expect(lastCallArg).to.deep.equal({ supported: '3', nonSupported: '5' }); + }); + Object.defineProperty(window, 'location', { + value: originalLocation, + writable: false, + }); }); });