Skip to content

Commit

Permalink
Merge pull request #12096 from transcom/B-18060-UI-Download-AOA-Packe…
Browse files Browse the repository at this point in the history
…t-Customer

MAIN - BP-18060 - Wire up AOA packet link customer/office
  • Loading branch information
r-mettler authored Mar 12, 2024
2 parents c50f1d0 + f2feab1 commit ccb204d
Show file tree
Hide file tree
Showing 16 changed files with 631 additions and 24 deletions.
14 changes: 11 additions & 3 deletions src/components/Office/DefinitionLists/PPMShipmentInfoList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import shipmentDefinitionListsStyles from './ShipmentDefinitionLists.module.scss

import styles from 'styles/descriptionList.module.scss';
import { formatDate } from 'shared/dates';
import AsyncPacketDownloadLink from 'shared/AsyncPacketDownloadLink/AsyncPacketDownloadLink';
import { ShipmentShape } from 'types/shipment';
import { formatCentsTruncateWhole, formatWeight } from 'utils/formatters';
import { setFlagStyles, setDisplayFlags, getDisplayFlags, fieldValidationShape } from 'utils/displayFlags';
import { ADVANCE_STATUSES } from 'constants/ppms';
import affiliation from 'content/serviceMemberAgencies';
import { permissionTypes } from 'constants/permissions';
import Restricted from 'components/Restricted/Restricted';
import { downloadPPMAOAPacket } from 'services/ghcApi';

const PPMShipmentInfoList = ({
className,
Expand All @@ -22,6 +24,7 @@ const PPMShipmentInfoList = ({
showWhenCollapsed,
isExpanded,
isForEvaluationReport,
onErrorModalToggle,
}) => {
const {
hasRequestedAdvance,
Expand Down Expand Up @@ -187,9 +190,12 @@ const PPMShipmentInfoList = ({
<dt>AOA Packet</dt>
<dd data-testid="aoaPacketDownload">
<p className={styles.downloadLink}>
<a href="">
<span>Download AOA Paperwork (PDF)</span>
</a>
<AsyncPacketDownloadLink
id={shipment?.ppmShipment?.id}
label="Download AOA Paperwork (PDF)"
asyncRetrieval={downloadPPMAOAPacket}
onFailure={onErrorModalToggle}
/>
</p>
</dd>
</div>
Expand Down Expand Up @@ -277,6 +283,7 @@ PPMShipmentInfoList.propTypes = {
showWhenCollapsed: PropTypes.arrayOf(PropTypes.string),
isExpanded: PropTypes.bool,
isForEvaluationReport: PropTypes.bool,
onErrorModalToggle: PropTypes.func,
};

PPMShipmentInfoList.defaultProps = {
Expand All @@ -286,6 +293,7 @@ PPMShipmentInfoList.defaultProps = {
showWhenCollapsed: [],
isExpanded: false,
isForEvaluationReport: false,
onErrorModalToggle: undefined,
};

export default PPMShipmentInfoList;
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import PPMShipmentInfoList from './PPMShipmentInfoList';

import affiliation from 'content/serviceMemberAgencies';
import { MockProviders } from 'testUtils';
import { permissionTypes } from 'constants/permissions';
import { ADVANCE_STATUSES } from 'constants/ppms';
import { downloadPPMAOAPacket } from 'services/ghcApi';

jest.mock('services/ghcApi', () => ({
...jest.requireActual('services/ghcApi'),
downloadPPMAOAPacket: jest.fn(),
}));

afterEach(() => {
jest.resetAllMocks();
});

const renderWithPermissions = (shipment) => {
render(
Expand Down Expand Up @@ -50,4 +62,55 @@ describe('PPMShipmentInfoList', () => {
expect(screen.getByTestId('closeout').textContent).toEqual('—');
expect(screen.getByText('Closeout office')).toBeInTheDocument();
});

it('PPM Download AOA Paperwork - success', async () => {
const mockResponse = {
ok: true,
headers: {
'content-disposition': 'filename="test.pdf"',
},
status: 200,
data: null,
};
downloadPPMAOAPacket.mockImplementation(() => Promise.resolve(mockResponse));

renderWithPermissions({ ppmShipment: { advanceStatus: ADVANCE_STATUSES.APPROVED.apiValue } });

expect(screen.getByText('Download AOA Paperwork (PDF)', { exact: false })).toBeInTheDocument();

const downloadAOAButton = screen.getByText('Download AOA Paperwork (PDF)');
expect(downloadAOAButton).toBeInTheDocument();

await userEvent.click(downloadAOAButton);

await waitFor(() => {
expect(downloadPPMAOAPacket).toHaveBeenCalledTimes(1);
});
});

it('PPM Download AOA Paperwork - failure', async () => {
downloadPPMAOAPacket.mockRejectedValue({
response: { body: { title: 'Error title', detail: 'Error detail' } },
});

const shipment = { ppmShipment: { advanceStatus: ADVANCE_STATUSES.APPROVED.apiValue } };
const onErrorHandler = jest.fn();

render(
<MockProviders permissions={[permissionTypes.viewCloseoutOffice]}>
<PPMShipmentInfoList shipment={shipment} onErrorModalToggle={onErrorHandler} />
</MockProviders>,
);

expect(screen.getByText('Download AOA Paperwork (PDF)')).toBeInTheDocument();

const downloadAOAButton = screen.getByText('Download AOA Paperwork (PDF)');
expect(downloadAOAButton).toBeInTheDocument();
await userEvent.click(downloadAOAButton);

await waitFor(() => {
expect(downloadPPMAOAPacket).toHaveBeenCalledTimes(1);
expect(onErrorHandler).toHaveBeenCalledTimes(1);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const ShipmentInfoListSelector = ({
shipmentType,
isForEvaluationReport,
destinationDutyLocationPostalCode,
onErrorModalToggle,
}) => {
switch (shipmentType) {
case SHIPMENT_OPTIONS.PPM:
Expand All @@ -33,6 +34,7 @@ const ShipmentInfoListSelector = ({
showWhenCollapsed={showWhenCollapsed}
isExpanded={isExpanded}
isForEvaluationReport={isForEvaluationReport}
onErrorModalToggle={onErrorModalToggle}
/>
);
case SHIPMENT_OPTIONS.HHG:
Expand Down Expand Up @@ -105,6 +107,7 @@ ShipmentInfoListSelector.propTypes = {
]),
isForEvaluationReport: PropTypes.bool,
destinationDutyLocationPostalCode: PropTypes.string,
onErrorModalToggle: PropTypes.func,
};

ShipmentInfoListSelector.defaultProps = {
Expand All @@ -117,6 +120,7 @@ ShipmentInfoListSelector.defaultProps = {
neverShow: [],
isForEvaluationReport: false,
destinationDutyLocationPostalCode: '',
onErrorModalToggle: undefined,
};

export default ShipmentInfoListSelector;
8 changes: 8 additions & 0 deletions src/components/Office/ShipmentDisplay/ShipmentDisplay.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Checkbox, Tag } from '@trussworks/react-uswds';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import classnames from 'classnames';

import DownloadAOAErrorModal from 'shared/DownloadAOAErrorModal/DownloadAOAErrorModal';
import { EditButton, ReviewButton } from 'components/form/IconButtons';
import ShipmentInfoListSelector from 'components/Office/DefinitionLists/ShipmentInfoListSelector';
import ShipmentContainer from 'components/Office/ShipmentContainer/ShipmentContainer';
Expand Down Expand Up @@ -41,6 +42,7 @@ const ShipmentDisplay = ({
const [isExpanded, setIsExpanded] = useState(false);
const tac = retrieveTAC(displayInfo.tacType, ordersLOA);
const sac = retrieveSAC(displayInfo.sacType, ordersLOA);
const [isDownloadAOAErrorModalVisible, setIsDownloadAOAErrorModalVisible] = useState(false);

const disableApproval = errorIfMissing.some((requiredInfo) =>
objectIsMissingFieldWithCondition(displayInfo, requiredInfo),
Expand All @@ -54,6 +56,10 @@ const ShipmentDisplay = ({
'chevron-down': !isExpanded,
});

const toggleDownloadAOAErrorModal = () => {
setIsDownloadAOAErrorModalVisible((prev) => !prev);
};

return (
<div className={styles.ShipmentCard} data-testid="shipment-display">
<ShipmentContainer className={containerClasses} shipmentType={shipmentType}>
Expand Down Expand Up @@ -104,7 +110,9 @@ const ShipmentDisplay = ({
errorIfMissing={errorIfMissing}
showWhenCollapsed={showWhenCollapsed}
neverShow={neverShow}
onErrorModalToggle={toggleDownloadAOAErrorModal}
/>
<DownloadAOAErrorModal isOpen={isDownloadAOAErrorModalVisible} closeModal={toggleDownloadAOAErrorModal} />
<Restricted to={permissionTypes.updateShipment}>
{editURL && (
<EditButton
Expand Down
19 changes: 15 additions & 4 deletions src/pages/MyMove/Home/MoveHome.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import {
HelperPPMCloseoutSubmitted,
} from './HomeHelpers';

import AsyncPacketDownloadLink from 'shared/AsyncPacketDownloadLink/AsyncPacketDownloadLink';
import DownloadAOAErrorModal from 'shared/DownloadAOAErrorModal/DownloadAOAErrorModal';
import ConnectedDestructiveShipmentConfirmationModal from 'components/ConfirmationModals/DestructiveShipmentConfirmationModal';
import Contact from 'components/Customer/Home/Contact';
import DocsUploaded from 'components/Customer/Home/DocsUploaded';
Expand All @@ -30,7 +32,7 @@ import MOVE_STATUSES from 'constants/moves';
import { customerRoutes } from 'constants/routes';
import { ppmShipmentStatuses, shipmentTypes } from 'constants/shipments';
import ConnectedFlashMessage from 'containers/FlashMessage/FlashMessage';
import { deleteMTOShipment, getAllMoves, getMTOShipmentsForMove } from 'services/internalApi';
import { deleteMTOShipment, getAllMoves, getMTOShipmentsForMove, downloadPPMAOAPacket } from 'services/internalApi';
import { withContext } from 'shared/AppContext';
import { SHIPMENT_OPTIONS } from 'shared/constants';
import {
Expand Down Expand Up @@ -79,6 +81,7 @@ const MoveHome = ({ serviceMemberMoves, isProfileComplete, serviceMember, signed
const [targetShipmentId, setTargetShipmentId] = useState(null);
const [showDeleteSuccessAlert, setShowDeleteSuccessAlert] = useState(false);
const [showDeleteErrorAlert, setShowDeleteErrorAlert] = useState(false);
const [showDownloadPPMAOAPaperworkErrorAlert, setShowDownloadPPMAOAPaperworkErrorAlert] = useState(false);

// fetching all move data on load since this component is dependent on that data
// this will run each time the component is loaded/accessed
Expand Down Expand Up @@ -366,6 +369,10 @@ const MoveHome = ({ serviceMemberMoves, isProfileComplete, serviceMember, signed
);
};

const toggleDownloadAOAErrorModal = () => {
setShowDownloadPPMAOAPaperworkErrorAlert(!showDownloadPPMAOAPaperworkErrorAlert);
};

// early return if loading user/service member
if (!serviceMember) {
return (
Expand Down Expand Up @@ -410,6 +417,7 @@ const MoveHome = ({ serviceMemberMoves, isProfileComplete, serviceMember, signed
submitText="Yes, Delete"
closeText="No, Keep It"
/>
<DownloadAOAErrorModal isOpen={showDownloadPPMAOAPaperworkErrorAlert} closeModal={toggleDownloadAOAErrorModal} />
<div className={styles.homeContainer}>
<header data-testid="customer-header" className={styles['customer-header']}>
<div className={`usa-prose grid-container ${styles['grid-container']}`}>
Expand Down Expand Up @@ -585,9 +593,12 @@ const MoveHome = ({ serviceMemberMoves, isProfileComplete, serviceMember, signed
{shipment?.ppmShipment?.advanceStatus === ADVANCE_STATUSES.APPROVED.apiValue && (
// TODO: B-18060 will add link to method that will create the AOA packet and return for download
<p className={styles.downloadLink}>
<a href="">
<span>Download AOA Paperwork (PDF)</span>
</a>
<AsyncPacketDownloadLink
id={shipment?.ppmShipment?.id}
label="Download AOA Paperwork (PDF)"
asyncRetrieval={downloadPPMAOAPacket}
onFailure={toggleDownloadAOAErrorModal}
/>
</p>
)}
{shipment?.ppmShipment?.advanceStatus === ADVANCE_STATUSES.REJECTED.apiValue && (
Expand Down
39 changes: 38 additions & 1 deletion src/pages/MyMove/Home/MoveHome.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
import React from 'react';
import { v4 } from 'uuid';
import { mount } from 'enzyme';
import { waitFor } from '@testing-library/react';

import MoveHome from './MoveHome';

import { customerRoutes } from 'constants/routes';
import { MockProviders } from 'testUtils';
import { downloadPPMAOAPacket } from 'services/internalApi';

jest.mock('containers/FlashMessage/FlashMessage', () => {
const MockFlash = () => <div>Flash message</div>;
Expand All @@ -29,6 +31,7 @@ jest.mock('services/internalApi', () => ({
deleteMTOShipment: jest.fn(),
getMTOShipmentsForMove: jest.fn(),
getAllMoves: jest.fn().mockImplementation(() => Promise.resolve()),
downloadPPMAOAPacket: jest.fn().mockImplementation(() => Promise.resolve()),
}));

const props = {
Expand Down Expand Up @@ -794,6 +797,8 @@ const defaultPropsAmendedOrdersWithAdvanceRequested = {
uploadedAmendedOrderDocuments: [],
};

const expectedPpmShipmentID = 'd18b865f-fd12-495d-91fa-65b53d72705a';

const defaultPropsWithAdvanceAndPPMApproved = {
...props,
serviceMemberMoves: {
Expand Down Expand Up @@ -829,7 +834,7 @@ const defaultPropsWithAdvanceAndPPMApproved = {
hasProGear: false,
hasReceivedAdvance: null,
hasRequestedAdvance: true,
id: 'd18b865f-fd12-495d-91fa-65b53d72705a',
id: expectedPpmShipmentID,
movingExpenses: [],
pickupPostalCode: '74133',
proGearWeight: null,
Expand Down Expand Up @@ -1248,5 +1253,37 @@ describe('Home component', () => {
expect(confirmMoveRequest.prop('actionBtnDisabled')).toBeFalsy();
expect(confirmMoveRequest.prop('actionBtnLabel')).toBe('Review your request');
});

it('Download AOA Paperwork - success', async () => {
const buttonId = `button[data-testid="asyncPacketDownloadLink${expectedPpmShipmentID}"]`;
expect(wrapper.find(buttonId).length).toBe(1);
const mockResponse = {
ok: true,
headers: {
'content-disposition': 'filename="test.pdf"',
},
status: 200,
data: null,
};
downloadPPMAOAPacket.mockImplementation(() => Promise.resolve(mockResponse));
await wrapper.find(buttonId).simulate('click');
await waitFor(() => {
expect(downloadPPMAOAPacket).toHaveBeenCalledTimes(1);
});
});

it('Download AOA Paperwork - failure', async () => {
const buttonId = `button[data-testid="asyncPacketDownloadLink${expectedPpmShipmentID}"]`;
expect(wrapper.find(buttonId).length).toBe(1);
downloadPPMAOAPacket.mockRejectedValue({
response: { body: { title: 'Error title', detail: 'Error detail' } },
});
await wrapper.find(buttonId).simulate('click');
await waitFor(() => {
// scrape text from error modal
expect(wrapper.text()).toContain('Something went wrong downloading PPM AOA paperwork');
expect(downloadPPMAOAPacket).toHaveBeenCalledTimes(1);
});
});
});
});
Loading

0 comments on commit ccb204d

Please sign in to comment.