Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[99786] Appoint a Rep add submission types to search results #34105

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import React from 'react';

Check warning on line 1 in src/applications/representative-appoint/components/SearchResult.jsx

View workflow job for this annotation

GitHub Actions / App Isolation Annotations

Staged Continuous Deployment App Isolation Conflict

*WARNING* This PR contains changes related to an application that is currently not isolated. As of Feb 3, 2025 deployment may no longer be possible for apps that are not isolated. Please isolate this app from other directories in 'src/applications' to prevent future deployment issues. More information on your app's status can be seen here: https://department-of-veterans-affairs.github.io/veteran-facing-services-tools/frontend-support-dashboard/cross-app-import-report Please reach out to Frontend Platform Support with any questions.
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { setData } from '~/platform/forms-system/src/js/actions';
import { VaButton } from '@department-of-veterans-affairs/component-library/dist/react-bindings';
import { parsePhoneNumber } from '../utilities/parsePhoneNumber';
import { getFormNumberFromEntity } from '../utilities/helpers';
import useV2FeatureToggle from '../hooks/useV2FeatureVisibility';

const SearchResult = ({
representative,
query,
handleSelectRepresentative,
loadingPOA,
userIsDigitalSubmitEligible,
}) => {
const { id } = representative.data;
const {
Expand All @@ -26,6 +29,9 @@
accreditedOrganizations,
} = representative.data.attributes;

const formNumber = getFormNumberFromEntity(representative.data);
const v2IsEnabled = useV2FeatureToggle();

const representativeName = name || fullName;

const { contact, extension } = parsePhoneNumber(phone);
Expand All @@ -43,6 +49,13 @@
(stateCode ? ` ${stateCode}` : '') +
(zipCode ? ` ${zipCode}` : '');

const submissionTypeContent = v2IsEnabled &&
userIsDigitalSubmitEligible && (
<p data-testid="submission-methods">
Accepts VA Form {formNumber} online, by mail, and in person
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assume for now that all reps/orgs can accept all types

</p>
);

return (
<va-card class="vads-u-padding--4 vads-u-margin-bottom--4">
<div className="representative-result-card-content">
Expand Down Expand Up @@ -82,7 +95,7 @@
</va-additional-info>
</div>
)}

{submissionTypeContent}
<div className="representative-contact-section vads-u-margin-top--3">
{addressExists && (
<div className="address-link vads-u-display--flex">
Expand Down Expand Up @@ -181,6 +194,7 @@
router: PropTypes.object,
routes: PropTypes.array,
stateCode: PropTypes.string,
userIsDigitalSubmitEligible: PropTypes.bool,
zipCode: PropTypes.string,
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useRef, useEffect } from 'react';

Check warning on line 1 in src/applications/representative-appoint/components/SelectAccreditedRepresentative.jsx

View workflow job for this annotation

GitHub Actions / App Isolation Annotations

Staged Continuous Deployment App Isolation Conflict

*WARNING* This PR contains changes related to an application that is currently not isolated. As of Feb 3, 2025 deployment may no longer be possible for apps that are not isolated. Please isolate this app from other directories in 'src/applications' to prevent future deployment issues. More information on your app's status can be seen here: https://department-of-veterans-affairs.github.io/veteran-facing-services-tools/frontend-support-dashboard/cross-app-import-report Please reach out to Frontend Platform Support with any questions.
import { connect } from 'react-redux';
import { setData } from '~/platform/forms-system/src/js/actions';
import PropTypes from 'prop-types';
Expand Down Expand Up @@ -204,6 +204,7 @@
currentSelectedRep={currentSelectedRep.current}
goToPath={goToPath}
handleSelectRepresentative={handleSelectRepresentative}
userIsDigitalSubmitEligible={formData?.userIsDigitalSubmitEligible}
/>
))}
<p className="vads-u-margin-y--4">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { preparerIsVeteran } from '../utilities/helpers';

Check warning on line 1 in src/applications/representative-appoint/config/prefillTransformer.js

View workflow job for this annotation

GitHub Actions / App Isolation Annotations

Staged Continuous Deployment App Isolation Conflict

*WARNING* This PR contains changes related to an application that is currently not isolated. As of Feb 3, 2025 deployment may no longer be possible for apps that are not isolated. Please isolate this app from other directories in 'src/applications' to prevent future deployment issues. More information on your app's status can be seen here: https://department-of-veterans-affairs.github.io/veteran-facing-services-tools/frontend-support-dashboard/cross-app-import-report Please reach out to Frontend Platform Support with any questions.

export default function prefillTransformer(formData) {
const newFormData = {
Expand Down Expand Up @@ -70,5 +70,9 @@
newFormData['Branch of Service'] = undefined;
}

newFormData.userIsDigitalSubmitEligible =
formData?.identityValidation?.hasIcn &&
formData?.identityValidation?.hasParticipantId;

return newFormData;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';

Check warning on line 1 in src/applications/representative-appoint/tests/components/SearchResult.unit.spec.jsx

View workflow job for this annotation

GitHub Actions / App Isolation Annotations

Staged Continuous Deployment App Isolation Conflict

*WARNING* This PR contains changes related to an application that is currently not isolated. As of Feb 3, 2025 deployment may no longer be possible for apps that are not isolated. Please isolate this app from other directories in 'src/applications' to prevent future deployment issues. More information on your app's status can be seen here: https://department-of-veterans-affairs.github.io/veteran-facing-services-tools/frontend-support-dashboard/cross-app-import-report Please reach out to Frontend Platform Support with any questions.
import { render } from '@testing-library/react';
import { expect } from 'chai';
import sinon from 'sinon';
import { SearchResult } from '../../components/SearchResult';
import * as useV2FeatureToggle from '../../hooks/useV2FeatureVisibility';

describe('SearchResult Component', () => {
it('evaluates addressExists correctly', () => {
Expand All @@ -16,6 +18,10 @@
},
};

const useV2FeatureVisibilityStub = sinon
.stub(useV2FeatureToggle, 'default')
.returns(false);

const { container } = render(
<SearchResult
representative={representative}
Expand All @@ -28,6 +34,8 @@
const addressAnchor = container.querySelector('.address-anchor');
expect(addressAnchor).to.exist;
expect(addressAnchor.textContent).to.contain('123 Main St');

useV2FeatureVisibilityStub.restore();
});

it('evaluates addressExists correctly when only city, stateCode, and zipCode exist', () => {
Expand All @@ -41,6 +49,10 @@
},
};

const useV2FeatureVisibilityStub = sinon
.stub(useV2FeatureToggle, 'default')
.returns(false);

const { container } = render(
<SearchResult
representative={representative}
Expand All @@ -53,6 +65,8 @@
const addressAnchor = container.querySelector('.address-anchor');
expect(addressAnchor).to.exist;
expect(addressAnchor.textContent).to.contain('Anytown, CT');

useV2FeatureVisibilityStub.restore();
});

it('includes the representative name in the select button text', () => {
Expand All @@ -69,6 +83,10 @@
},
};

const useV2FeatureVisibilityStub = sinon
.stub(useV2FeatureToggle, 'default')
.returns(false);

const { container } = render(
<SearchResult
representative={representative}
Expand All @@ -83,5 +101,132 @@
);
expect(selectButton).to.exist;
expect(selectButton.getAttribute('text')).to.contain('Robert Smith');

useV2FeatureVisibilityStub.restore();
});

context('when v2 is enabled', () => {
context('when the user is userIsDigitalSubmitEligible', () => {
it('displays submission methods', () => {
const representative = {
data: {
id: 1,
type: 'individual',
attributes: {
addressLine1: '123 Main St',
city: '',
stateCode: '',
zipCode: '',
fullName: 'Robert Smith',
individualType: 'representative',
},
},
};

const useV2FeatureVisibilityStub = sinon
.stub(useV2FeatureToggle, 'default')
.returns(true);

const { container } = render(
<SearchResult
representative={representative}
query={{}}
handleSelectRepresentative={() => {}}
loadingPOA={false}
userIsDigitalSubmitEligible
/>,
);

const submissionMethods = container.querySelector(
'[data-testid="submission-methods"]',
);

expect(submissionMethods).to.exist;

useV2FeatureVisibilityStub.restore();
});
});

context('when the user is not userIsDigitalSubmitEligible', () => {
it('does not display submission methods', () => {
const representative = {
data: {
id: 1,
type: 'individual',
attributes: {
addressLine1: '123 Main St',
city: '',
stateCode: '',
zipCode: '',
fullName: 'Robert Smith',
individualType: 'representative',
},
},
};

const useV2FeatureVisibilityStub = sinon
.stub(useV2FeatureToggle, 'default')
.returns(true);

const { container } = render(
<SearchResult
representative={representative}
query={{}}
handleSelectRepresentative={() => {}}
loadingPOA={false}
userIsDigitalSubmitEligible={false}
/>,
);

const submissionMethods = container.querySelector(
'[data-testid="submission-methods"]',
);

expect(submissionMethods).not.to.exist;

useV2FeatureVisibilityStub.restore();
});
});
});

context('when v2 is not enabled', () => {
it('does not display submission methods', () => {
const representative = {
data: {
id: 1,
type: 'individual',
attributes: {
addressLine1: '123 Main St',
city: '',
stateCode: '',
zipCode: '',
fullName: 'Robert Smith',
individualType: 'representative',
},
},
};

const useV2FeatureVisibilityStub = sinon
.stub(useV2FeatureToggle, 'default')
.returns(false);

const { container } = render(
<SearchResult
representative={representative}
query={{}}
handleSelectRepresentative={() => {}}
loadingPOA={false}
userIsDigitalSubmitEligible
/>,
);

const submissionMethods = container.querySelector(
'[data-testid="submission-methods"]',
);

expect(submissionMethods).not.to.exist;

useV2FeatureVisibilityStub.restore();
});
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { expect } from 'chai';

Check warning on line 1 in src/applications/representative-appoint/tests/config/prefillTransformer.unit.spec.js

View workflow job for this annotation

GitHub Actions / App Isolation Annotations

Staged Continuous Deployment App Isolation Conflict

*WARNING* This PR contains changes related to an application that is currently not isolated. As of Feb 3, 2025 deployment may no longer be possible for apps that are not isolated. Please isolate this app from other directories in 'src/applications' to prevent future deployment issues. More information on your app's status can be seen here: https://department-of-veterans-affairs.github.io/veteran-facing-services-tools/frontend-support-dashboard/cross-app-import-report Please reach out to Frontend Platform Support with any questions.
import prefill from '../fixtures/data/prefill.json';
import prefillTransformer from '../../config/prefillTransformer';

Expand Down Expand Up @@ -120,4 +120,40 @@
expect(result.veteranSocialSecurityNumber).to.be.undefined;
});
});

context('when the user does not have an ICN', () => {
it('sets userIsDigitalSubmitEligible to false', () => {
const data = {
...prefill,
identityValidation: { hasIcn: false, hasParticipantId: true },
};

const result = prefillTransformer(data);

expect(result.userIsDigitalSubmitEligible).to.be.false;
});
});

context('when the user does not have a participant id', () => {
it('sets userIsDigitalSubmitEligible to false', () => {
const data = {
...prefill,
identityValidation: { hasIcn: true, hasParticipantId: false },
};

const result = prefillTransformer(data);

expect(result.userIsDigitalSubmitEligible).to.be.false;
});
});

context('when the user has an ICN and a participant id', () => {
it('sets userIsDigitalSubmitEligible to true', () => {
const data = { ...prefill };

const result = prefillTransformer(data);

expect(result.userIsDigitalSubmitEligible).to.be.true;
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { expect } from 'chai';

Check warning on line 1 in src/applications/representative-appoint/tests/utilities/getFormNumberFromEntity.unit.spec.jsx

View workflow job for this annotation

GitHub Actions / App Isolation Annotations

Staged Continuous Deployment App Isolation Conflict

*WARNING* This PR contains changes related to an application that is currently not isolated. As of Feb 3, 2025 deployment may no longer be possible for apps that are not isolated. Please isolate this app from other directories in 'src/applications' to prevent future deployment issues. More information on your app's status can be seen here: https://department-of-veterans-affairs.github.io/veteran-facing-services-tools/frontend-support-dashboard/cross-app-import-report Please reach out to Frontend Platform Support with any questions.

import { getFormNumberFromEntity } from '../../utilities/helpers';

describe('getFormNumberFromEntity', () => {
it('should return "21-22" when entity type is organization', () => {
const mockFormData = { type: 'organization' };
const result = getFormNumberFromEntity(mockFormData);
expect(result).to.equal('21-22');
});

it('should return "21-22a" when individual type is attorney', () => {
const mockFormData = {
type: 'individual',
attributes: { individualType: 'attorney' },
};
const result = getFormNumberFromEntity(mockFormData);
expect(result).to.equal('21-22a');
});

it('should return "21-22a" when individual type is claimsAgent', () => {
const mockFormData = {
type: 'individual',
attributes: { individualType: 'claimsAgent' },
};
const result = getFormNumberFromEntity(mockFormData);
expect(result).to.equal('21-22a');
});

it('should return "21-22" when individual type is representative', () => {
const mockFormData = {
type: 'individual',
attributes: { individualType: 'representative' },
};
const result = getFormNumberFromEntity(mockFormData);
expect(result).to.equal('21-22');
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';

Check warning on line 1 in src/applications/representative-appoint/utilities/helpers.js

View workflow job for this annotation

GitHub Actions / App Isolation Annotations

Staged Continuous Deployment App Isolation Conflict

*WARNING* This PR contains changes related to an application that is currently not isolated. As of Feb 3, 2025 deployment may no longer be possible for apps that are not isolated. Please isolate this app from other directories in 'src/applications' to prevent future deployment issues. More information on your app's status can be seen here: https://department-of-veterans-affairs.github.io/veteran-facing-services-tools/frontend-support-dashboard/cross-app-import-report Please reach out to Frontend Platform Support with any questions.
import moment from 'moment';

Check warning on line 2 in src/applications/representative-appoint/utilities/helpers.js

View workflow job for this annotation

GitHub Actions / Linting (Files Changed)

src/applications/representative-appoint/utilities/helpers.js:2:1:Use date-fns or Native Date methods instead of moment.js
import { DATE_FORMAT } from '../definitions/constants';

Expand Down Expand Up @@ -26,7 +26,7 @@
);

export const formatDate = (date, format = DATE_FORMAT) => {
const m = moment(date);

Check warning on line 29 in src/applications/representative-appoint/utilities/helpers.js

View workflow job for this annotation

GitHub Actions / Linting (Files Changed)

src/applications/representative-appoint/utilities/helpers.js:29:13:Consider using Native new Date().
return date && m.isValid() ? m.format(format) : 'Unknown';
};

Expand Down Expand Up @@ -115,6 +115,14 @@
return 'VSO Representative';
};

export const getFormNumberFromEntity = entity => {
const repType = getRepType(entity);

return ['Organization', 'VSO Representative'].includes(repType)
? '21-22'
: '21-22a';
};

export const getFormNumber = formData => {
const entity = formData['view:selectedRepresentative'];
const entityType = entity?.type;
Expand Down Expand Up @@ -144,7 +152,7 @@
* Takes representative object (rather than formData object)
*/
export const isVSORepresentative = rep => {
if (rep?.attributes?.accreditedOrganizations?.data?.length > 0) {

Check warning on line 155 in src/applications/representative-appoint/utilities/helpers.js

View workflow job for this annotation

GitHub Actions / Linting (Files Changed)

src/applications/representative-appoint/utilities/helpers.js:155:3:Replace this if-then-else flow by a single return statement.
return true;
}

Expand Down
Loading