Skip to content

Commit

Permalink
Merge branch 'main' into MHV-55400/medications-shipped-tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
dcloud authored Mar 28, 2024
2 parents 1402272 + 15153b9 commit 79f01a2
Show file tree
Hide file tree
Showing 306 changed files with 35,711 additions and 420 deletions.
8 changes: 8 additions & 0 deletions src/applications/appeals/shared/components/FileField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ import { focusAddAnotherButton, focusCancelButton } from '../utils/focus';
import {
MISSING_PASSWORD_ERROR,
INCORRECT_PASSWORD_ERROR,
FILE_NAME_TOO_LONG_ERROR,
createContent,
reMapErrorMessage,
checkIsFileNameTooLong,
hasSomeUploading,
checkUploadVisibility,
} from '../utils/upload';
Expand Down Expand Up @@ -211,6 +213,12 @@ const FileField = props => {
name: currentFile.name,
};

if (checkIsFileNameTooLong(currentFile.name)) {
allFiles[idx].errorMessage = FILE_NAME_TOO_LONG_ERROR;
props.onChange(allFiles);
return;
}

if (currentFile.type === 'testing') {
// Skip read file for Cypress testing
checkResults = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import FileField from '../../components/FileField';

import {
errormessageMaps,
FILE_NAME_TOO_LONG_ERROR,
MAX_FILE_NAME_LENGTH,
MISSING_PASSWORD_ERROR,
INCORRECT_PASSWORD_ERROR,
} from '../../utils/upload';
Expand Down Expand Up @@ -537,6 +539,54 @@ describe('Schemaform <FileField>', () => {
expect($('div.usa-input-error-message', container)).to.exist;
});

it('should render file name too long error', async () => {
const onChangeSpy = sinon.spy();
const schema = {
additionalItems: {},
items: [
{
properties: {},
},
],
};
const uiSchema = fileUploadUI('Files');
const fileWithLongName = new File(
['test 123'],
'a'.repeat(MAX_FILE_NAME_LENGTH + 1),
{
type: fileTypeSignatures.pdf.mime,
},
);
const errorSchema = {};
const registry = {
fields: {
SchemaField: () => <div />,
},
};
const { container } = render(
<FileField
registry={registry}
schema={schema}
uiSchema={uiSchema}
idSchema={idSchema}
errorSchema={errorSchema}
formData={[]}
formContext={formContext}
onChange={onChangeSpy}
requiredSchema={requiredSchema}
/>,
);

fireEvent.change($('input[type="file"]', container), {
target: { files: [fileWithLongName] },
});

expect(onChangeSpy.calledOnce).to.be.true;
expect(onChangeSpy.args[0][0][0].errorMessage).to.eq(
FILE_NAME_TOO_LONG_ERROR,
);
});

it('should remap PDF dimension error', () => {
const error = 'exceeds the page size limit';
const schema = {
Expand Down
20 changes: 20 additions & 0 deletions src/applications/appeals/shared/tests/utils/upload.unit.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { expect } from 'chai';
import {
createPayload,
parseResponse,
MAX_FILE_NAME_LENGTH,
checkIsFileNameTooLong,
hasSomeUploading,
checkUploadVisibility,
createContent,
Expand Down Expand Up @@ -47,6 +49,24 @@ describe('parseResponse', () => {
});
});

describe('checkIsFileNameTooLong', () => {
it('should return false for file names under the size limit', () => {
expect(checkIsFileNameTooLong()).to.be.false;
expect(checkIsFileNameTooLong('')).to.be.false;
expect(checkIsFileNameTooLong('abcd')).to.be.false;
expect(checkIsFileNameTooLong('a'.repeat(MAX_FILE_NAME_LENGTH / 2))).to.be
.false;
expect(checkIsFileNameTooLong('a'.repeat(MAX_FILE_NAME_LENGTH - 1))).to.be
.false;
});
it('should return true for file names over the size limit', () => {
expect(checkIsFileNameTooLong('a'.repeat(MAX_FILE_NAME_LENGTH + 1))).to.be
.true;
expect(checkIsFileNameTooLong('a'.repeat(MAX_FILE_NAME_LENGTH * 2))).to.be
.true;
});
});

describe('hasSomeUploading', () => {
it('should return false if no files are uploading', () => {
expect(hasSomeUploading([])).to.be.false;
Expand Down
7 changes: 7 additions & 0 deletions src/applications/appeals/shared/utils/upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ export const MISSING_PASSWORD_ERROR = [
'Document is locked with a user password',
];

// Lighthouse limits file names to 255 characters
export const MAX_FILE_NAME_LENGTH = 255;
export const FILE_NAME_TOO_LONG_ERROR = `Your file name can’t exceed ${MAX_FILE_NAME_LENGTH} characters. Rename your file and try again.`;

export const INCORRECT_PASSWORD_ERROR =
'We couldn’t unlock your PDF. Save the PDF without a password and try again.';

Expand All @@ -24,6 +28,9 @@ export const reMapErrorMessage = error => {
return errormessageMaps?.[result] ?? error;
};

export const checkIsFileNameTooLong = (name = '') =>
name.length > MAX_FILE_NAME_LENGTH;

export const createPayload = (file, _formId, password) => {
const payload = new FormData();
payload.append('decision_review_evidence_attachment[file_data]', file);
Expand Down
14 changes: 0 additions & 14 deletions src/applications/claims-status/components/appeals-v2/Docket.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { flow, sortBy, toPairs } from 'lodash';
import omit from 'platform/utilities/data/omit';

import DocketCard from './DocketCard';
import DurationCard from './DurationCard';
import {
APPEAL_ACTIONS,
DOCKET_TYPES,
Expand Down Expand Up @@ -50,11 +49,6 @@ function Docket({
'MMMM YYYY',
);

const etaFormatted =
eta &&
eta[amaDocket] &&
moment(eta[amaDocket], 'YYYY-MM-DD').format('MMMM YYYY');

const otherEtas = flow(
e => omit(amaDocket, e),
toPairs,
Expand Down Expand Up @@ -148,14 +142,6 @@ function Docket({
</p>
{yourPlaceText}
{ahead && <DocketCard total={total} ahead={ahead} docket={amaDocket} />}
{etaFormatted && (
<DurationCard
durationText={etaFormatted}
cardDescription={`Estimate of when your appeal will reach the front of the ${getDocketName(
amaDocket,
)} docket line`}
/>
)}
<h2>Is there a way to prioritize my appeal?</h2>
<p>
If you are suffering a serious illness or are in financial distress,
Expand Down

This file was deleted.

17 changes: 2 additions & 15 deletions src/applications/claims-status/components/appeals-v2/NextEvent.jsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,18 @@
import React from 'react';
import PropTypes from 'prop-types';
import DurationCard from './DurationCard';

const NextEvent = ({
title,
description,
durationText,
cardDescription,
showSeparator,
}) => (
const NextEvent = ({ description, showSeparator, title }) => (
<li className="next-event">
<h3>{title}</h3>
<div>{description}</div>
<DurationCard
durationText={durationText}
cardDescription={cardDescription}
/>
{showSeparator && <span className="sidelines">or</span>}
</li>
);

NextEvent.propTypes = {
title: PropTypes.string.isRequired,
description: PropTypes.element.isRequired,
durationText: PropTypes.string.isRequired,
cardDescription: PropTypes.string.isRequired,
showSeparator: PropTypes.bool.isRequired,
title: PropTypes.string.isRequired,
};

export default NextEvent;
27 changes: 0 additions & 27 deletions src/applications/claims-status/components/appeals-v2/WhatsNext.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import NextEvent from './NextEvent';
import DurationCard from './DurationCard';

const WhatsNext = ({ nextEvents }) => {
const { header, events } = nextEvents;
Expand All @@ -10,35 +9,15 @@ const WhatsNext = ({ nextEvents }) => {
key={event.title}
title={event.title}
description={event.description}
durationText={event.durationText}
cardDescription={event.cardDescription}
// show a separator after all events except the last one
showSeparator={index !== events.length - 1}
/>
));

// Some current status types (really, just pendingSoc) have multiple
// NextEvents that each have the same duration. In these cases, we want to
// show one duration card, above the NextEvent list, instead of one card for
// each NextEvent item. getNextEvents() will only return a headerCard
// property if the corresponding current status type should be treated in
// this way
let headerDurationCard = null;
if (nextEvents.headerCard) {
const { durationText, cardDescription } = nextEvents.headerCard;
headerDurationCard = (
<DurationCard
durationText={durationText}
cardDescription={cardDescription}
/>
);
}

return (
<div>
<h2>What happens next?</h2>
<p>{header}</p>
{headerDurationCard}
<ul className="appeals-next-list">{eventsList}</ul>
</div>
);
Expand All @@ -47,16 +26,10 @@ const WhatsNext = ({ nextEvents }) => {
WhatsNext.propTypes = {
nextEvents: PropTypes.shape({
header: PropTypes.string.isRequired,
headerCard: PropTypes.shape({
durationText: PropTypes.string.isRequired,
cardDescription: PropTypes.string.isRequired,
}),
events: PropTypes.arrayOf(
PropTypes.shape({
title: PropTypes.string.isRequired,
description: PropTypes.element.isRequired,
durationText: PropTypes.string.isRequired,
cardDescription: PropTypes.string.isRequired,
}),
).isRequired,
}).isRequired,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,6 @@ describe('Appeals V2 Docket', () => {
wrapper.unmount();
});

it('should render a time estimate', () => {
const wrapper = shallow(<Docket {...amaProps} />);
expect(wrapper.find('DurationCard').length).to.equal(1);
wrapper.unmount();
});

it('should include docket switch instructions if eligible', () => {
const wrapper = shallow(<Docket {...amaProps} />);
expect(wrapper.text()).to.contain(
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ const defaultProps = {
your appeal to the Board of Veterans’ Appeals. This evidence could cause VBA
to grant your appeal, but if not, they will need to produce an additional
Statement of the Case.`,
durationText: '11 months',
cardDescription: 'Test description',
showSeparator: true,
};

Expand Down
Loading

0 comments on commit 79f01a2

Please sign in to comment.