diff --git a/src/applications/claims-status/reducers/serialize.js b/src/applications/claims-status/reducers/serialize.js index 067af1881a2e..bbbd18677b31 100644 --- a/src/applications/claims-status/reducers/serialize.js +++ b/src/applications/claims-status/reducers/serialize.js @@ -1,19 +1,23 @@ -import { getTrackedItemDate } from '../utils/helpers'; +import { + getTrackedItemDate, + getTrackedItemHumanReadableName, +} from '../utils/helpers'; -// NOTE: I think that in the long term it will make sense to move -// this logic into the backend, but doing it here for now makes it -// easier to modify this in the short term +// NOTE: In the long term it will make sense to move some of this logic into +// the backend, but doing it here for now makes it easier to modify in +// the short-term. // -// This does 2 things: -// 1) Grabs all of the supporting documents associated with -// tracked items and embeds them within their respective -// tracked items in a new `documents` key that has been -// added to each tracked item -// 2) Gets a new array of supporting documents that only -// includes the documents that are not associated with -// any tracked items. These items should already be -// embedded in their respective tracked items anyways, -// so they are no longer needed +// This does a few things: +// 1) Grabs all of the supporting documents associated with tracked items and +// embeds them within their respective tracked items in a new `documents` +// key that has been added to each tracked item +// 2) Gets a new array of supporting documents that only includes the documents +// that are not associated with any tracked items. These items should +// already be embedded in their respective tracked items anyways, so they +// are no longer needed +// 3) Performs any additional necessary transforms on supporting document and +// tracked item data, such as replacing display names and adding date +// attributes const isLighthouseClaim = claim => claim.type === 'claim'; const isAssociatedWithAnyTrackedItem = doc => doc.trackedItemId !== null; @@ -25,27 +29,49 @@ const getDocsAssociatedWithTrackedItems = docs => docs.filter(isAssociatedWithAnyTrackedItem); const getDocsAssociatedWithTrackedItem = (item, docs) => { - const predicate = isAssociatedWithTrackedItem(item); - return docs.filter(predicate); + return docs.filter(isAssociatedWithTrackedItem(item)); }; const associateDocsWithTrackedItems = (items, docs) => { - return items.map(item => { - const newItem = { ...item }; - const associatedDocs = getDocsAssociatedWithTrackedItem(newItem, docs); - newItem.documents = associatedDocs || []; - newItem.date = getTrackedItemDate(item); - return newItem; - }); + return items.map(item => ({ + ...item, + documents: getDocsAssociatedWithTrackedItem(item, docs), + })); }; const filterAssociatedDocs = docs => docs.filter(doc => !isAssociatedWithAnyTrackedItem(doc)); +const transformUnassociatedDocs = docs => + docs.map(doc => ({ + ...doc, + date: doc.uploadDate, + })); + +const transformAssociatedTrackedItems = items => + items.map(item => ({ + ...item, + // + // Override the first-party status of PMR (Private Medical Record) Pending + // requests to third-party by replacing "NEEDED_FROM_YOU" with + // "NEEDED_FROM_OTHERS". + // See GH issue for more details: + // https://github.com/department-of-veterans-affairs/va.gov-team/issues/93456 + // TODO: Remove this block once the Lighthouse API is returning + // PMR Pending requests with more accurate status information. + status: + item.displayName === 'PMR Pending' ? 'NEEDED_FROM_OTHERS' : item.status, + // + date: getTrackedItemDate(item), + // This might need to be removed / moved elsewhere if future application + // logic depends on the original `displayName` of the tracked item. + displayName: getTrackedItemHumanReadableName(item.displayName), + })); + export const serializeClaim = claim => { if (!claim || !isLighthouseClaim(claim)) return claim; - const { supportingDocuments, trackedItems } = claim.attributes; + const { supportingDocuments = [], trackedItems = [] } = claim.attributes; const associatedDocuments = getDocsAssociatedWithTrackedItems( supportingDocuments, @@ -56,19 +82,20 @@ export const serializeClaim = claim => { associatedDocuments, ); + const transformedUnassociatedDocuments = transformUnassociatedDocs( + filterAssociatedDocs(supportingDocuments), + ); + + const transformedAssociatedTrackedItems = transformAssociatedTrackedItems( + associatedTrackedItems, + ); + return { ...claim, attributes: { ...claim.attributes, - supportingDocuments: filterAssociatedDocs(supportingDocuments).map( - doc => { - return { - ...doc, - date: doc.uploadDate, - }; - }, - ), - trackedItems: associatedTrackedItems, + supportingDocuments: transformedUnassociatedDocuments, + trackedItems: transformedAssociatedTrackedItems, }, }; }; diff --git a/src/applications/claims-status/tests/reducers/serialize.unit.spec.jsx b/src/applications/claims-status/tests/reducers/serialize.unit.spec.jsx index 4ae081a12385..02d27ec5430e 100644 --- a/src/applications/claims-status/tests/reducers/serialize.unit.spec.jsx +++ b/src/applications/claims-status/tests/reducers/serialize.unit.spec.jsx @@ -44,6 +44,22 @@ describe('Claim Serializer', () => { }); }); + it('should set supporting documents and tracked items to empty arrays when data is missing', () => { + const claim = { + id: 1, + type: 'claim', + attributes: {}, + }; + const serializedClaim = serializeClaim(claim); + expect(serializedClaim).to.eql({ + ...claim, + attributes: { + supportingDocuments: [], + trackedItems: [], + }, + }); + }); + it('should return no supporting docs when there is only one and it is associated with a tracked item', () => { const claim = { id: 1, @@ -136,4 +152,48 @@ describe('Claim Serializer', () => { expect(trackedItem3.documents.length).to.be.equal(2); expect(trackedItem3.documents.map(d => d.id).sort()).to.eql([3, 4]); }); + + // + // See notes on PMR Pending in serialize.js + it('should manually override the status of PMR Pending requests', () => { + const claim = { + id: 1, + type: 'claim', + attributes: { + trackedItems: [ + { + id: 1, + displayName: 'PMR Pending', + status: 'NEEDED_FROM_YOU', + }, + ], + }, + }; + const serializedClaim = serializeClaim(claim); + const trackedItem1 = serializedClaim.attributes.trackedItems.find( + d => d.id === 1, + ); + expect(trackedItem1.status).to.eql('NEEDED_FROM_OTHERS'); + }); + // + + it('should replace the display name of some types of tracked items', () => { + const claim = { + id: 1, + type: 'claim', + attributes: { + trackedItems: [ + { + id: 1, + displayName: 'PMR Pending', + }, + ], + }, + }; + const serializedClaim = serializeClaim(claim); + const trackedItem1 = serializedClaim.attributes.trackedItems.find( + d => d.id === 1, + ); + expect(trackedItem1.displayName).to.eql('Private Medical Record'); + }); }); diff --git a/src/applications/claims-status/tests/utils/helpers.unit.spec.js b/src/applications/claims-status/tests/utils/helpers.unit.spec.js index 1619af939047..779680a00c07 100644 --- a/src/applications/claims-status/tests/utils/helpers.unit.spec.js +++ b/src/applications/claims-status/tests/utils/helpers.unit.spec.js @@ -43,6 +43,7 @@ import { sentenceCase, generateClaimTitle, isStandard5103Notice, + getTrackedItemHumanReadableName, } from '../../utils/helpers'; import { @@ -1542,4 +1543,14 @@ describe('Disability benefits helpers: ', () => { }); }); }); + describe('getTrackedItemHumanReadableName', () => { + it('should return a replacment name if one is available', () => { + expect(getTrackedItemHumanReadableName('PMR Pending')).to.equal( + 'Private Medical Record', + ); + }); + it("should return the provided name if a replacement doesn't exist", () => { + expect(getTrackedItemHumanReadableName('test')).to.equal('test'); + }); + }); }); diff --git a/src/applications/claims-status/utils/helpers.js b/src/applications/claims-status/utils/helpers.js index 2195671797f7..f1361825a083 100644 --- a/src/applications/claims-status/utils/helpers.js +++ b/src/applications/claims-status/utils/helpers.js @@ -1231,3 +1231,15 @@ export const getTrackedItemDateFromStatus = item => { return item.requestedDate; } }; + +// Many of the display names for tracked items provided by the API are rather +// esoteric, so we replace some of them to make them more user-friendly. +const trackedItemsHumanReadableNames = new Map([ + ['PMR Pending', 'Private Medical Record'], +]); +// Currently only being used by reducers/serialize, but it might need to be +// moved elsewhere if future application logic depends on the original +// `displayName` of the tracked item. +export const getTrackedItemHumanReadableName = name => { + return trackedItemsHumanReadableNames.get(name) || name; +};