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:
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 170cf7178fb9..8a5d6141991f 100644
--- a/src/applications/edu-benefits/10215/pages/calcs.js
+++ b/src/applications/edu-benefits/10215/pages/calcs.js
@@ -1,21 +1,84 @@
-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 (
<>
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".
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,
+ });
});
});