From c48c04f9524b5f8f2810bdbe476d7a1a051bd35f Mon Sep 17 00:00:00 2001 From: Kris Koskelin Date: Wed, 24 Mar 2021 10:01:16 -0500 Subject: [PATCH 1/8] 5311: prevent undefined users from causing errors return not-authorized value instead. --- shared/src/authorization/authorizationClientService.js | 4 ++++ shared/src/authorization/authorizationClientService.test.js | 3 +++ 2 files changed, 7 insertions(+) diff --git a/shared/src/authorization/authorizationClientService.js b/shared/src/authorization/authorizationClientService.js index a1b9d62f18d..46974fd12f1 100644 --- a/shared/src/authorization/authorizationClientService.js +++ b/shared/src/authorization/authorizationClientService.js @@ -224,6 +224,10 @@ exports.AUTHORIZATION_MAP = AUTHORIZATION_MAP; * @returns {boolean} true if user is authorized, false otherwise */ exports.isAuthorized = (user, action, owner) => { + if (!user) { + return false; + } + if (user.userId && user.userId === owner) { return true; } diff --git a/shared/src/authorization/authorizationClientService.test.js b/shared/src/authorization/authorizationClientService.test.js index 331f1862e51..2d0416caf8d 100644 --- a/shared/src/authorization/authorizationClientService.test.js +++ b/shared/src/authorization/authorizationClientService.test.js @@ -6,6 +6,9 @@ const { const { ROLES } = require('../business/entities/EntityConstants'); describe('Authorization client service', () => { + it('returns false for undefined user', () => { + expect(isAuthorized(undefined, 'unknown action', 'someUser')).toBeFalsy(); + }); it('returns true for any user whose userId matches the 3rd owner argument, in this case "someUser" === "someUser"', () => { expect( isAuthorized( From a80554e834201107febb11db0c54ff62eba76839 Mon Sep 17 00:00:00 2001 From: Kris Koskelin Date: Wed, 24 Mar 2021 10:41:42 -0500 Subject: [PATCH 2/8] 5311 fixing authorization bug scenario WIP [skip ci] --- .../src/business/useCases/getReconciliationReportInteractor.js | 1 + 1 file changed, 1 insertion(+) diff --git a/shared/src/business/useCases/getReconciliationReportInteractor.js b/shared/src/business/useCases/getReconciliationReportInteractor.js index 51676f9f8b1..749b03953cd 100644 --- a/shared/src/business/useCases/getReconciliationReportInteractor.js +++ b/shared/src/business/useCases/getReconciliationReportInteractor.js @@ -93,6 +93,7 @@ const assignCaseCaptionFromPersistence = async ( const casesDetails = await applicationContext .getPersistenceGateway() .getCasesByDocketNumbers({ applicationContext, docketNumbers }); + // todo: could there be docket entries for cases that are not in persistence?? accessing "caseCaption" of undefined docketEntries.forEach(docketEntry => { docketEntry.caseCaption = casesDetails.find( detail => detail.docketNumber === docketEntry.docketNumber, From 2358c424aca0332ee10a2e9b17e9f8311408675e Mon Sep 17 00:00:00 2001 From: Kris Koskelin Date: Wed, 24 Mar 2021 13:17:16 -0500 Subject: [PATCH 3/8] 5311: backup method to get docketNumber [skip ci] extract it from PK if not on docketEntry itself. --- .../getReconciliationReportInteractor.js | 9 ++++-- .../getReconciliationReportInteractor.test.js | 31 +++++++++++++++++++ .../elasticsearch/getReconciliationReport.js | 1 + 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/shared/src/business/useCases/getReconciliationReportInteractor.js b/shared/src/business/useCases/getReconciliationReportInteractor.js index 749b03953cd..c06aa77051f 100644 --- a/shared/src/business/useCases/getReconciliationReportInteractor.js +++ b/shared/src/business/useCases/getReconciliationReportInteractor.js @@ -12,7 +12,6 @@ const { const { ReconciliationReportEntry, } = require('../entities/ReconciliationReportEntry'); -const { map } = require('lodash'); const { UnauthorizedError } = require('../../errors/errors'); const isValidDate = dateString => { @@ -89,11 +88,15 @@ const assignCaseCaptionFromPersistence = async ( applicationContext, docketEntries, ) => { - const docketNumbers = map(docketEntries, 'docketNumber'); + const docketNumbers = docketEntries.map(e => { + const docketNumber = e.docketNumber || e.pk.substr(e.pk.indexOf('|') + 1); + e.docketNumber = docketNumber; + return e.docketNumber; + }); const casesDetails = await applicationContext .getPersistenceGateway() .getCasesByDocketNumbers({ applicationContext, docketNumbers }); - // todo: could there be docket entries for cases that are not in persistence?? accessing "caseCaption" of undefined + docketEntries.forEach(docketEntry => { docketEntry.caseCaption = casesDetails.find( detail => detail.docketNumber === docketEntry.docketNumber, diff --git a/shared/src/business/useCases/getReconciliationReportInteractor.test.js b/shared/src/business/useCases/getReconciliationReportInteractor.test.js index fc39b374ad5..8994a2a98de 100644 --- a/shared/src/business/useCases/getReconciliationReportInteractor.test.js +++ b/shared/src/business/useCases/getReconciliationReportInteractor.test.js @@ -20,6 +20,8 @@ describe('getReconciliationReportInteractor', () => { { caseCaption: mockCaseCaption, docketNumber: '135-20', + pk: 'case|135-20', + sk: 'case|135-20', }, ]); applicationContext.getCurrentUser.mockReturnValue({ @@ -134,4 +136,33 @@ describe('getReconciliationReportInteractor', () => { reconciliationDateStart: '2021-01-01T05:00:00.000Z', }); }); + + it('should call the getCasesByDocketNumbers method with a docket number extracted from pk if the record has no defined value for the docketNumber attribute', async () => { + const docketEntries = [ + { + docketEntryId: '3d27e02e-6954-4595-8b3f-0e91bbc1b51e', + docketNumber: undefined, + documentTitle: 'Petition', + eventCode: 'P', + filedBy: 'Petr. Kaitlin Chaney', + filingDate: '2021-01-05T21:14:09.031Z', + pk: 'case|135-20', + servedAt: '2021-01-05T21:14:09.031Z', + }, + ]; + + applicationContext + .getPersistenceGateway() + .getReconciliationReport.mockReturnValue(docketEntries); + + const reconciliationDate = '2021-01-01'; + await getReconciliationReportInteractor(applicationContext, { + reconciliationDate, + }); + + expect( + applicationContext.getPersistenceGateway().getCasesByDocketNumbers.mock + .calls[0][0].docketNumbers, + ).toEqual(['135-20']); + }); }); diff --git a/shared/src/persistence/elasticsearch/getReconciliationReport.js b/shared/src/persistence/elasticsearch/getReconciliationReport.js index 0388f46b801..98317192f51 100644 --- a/shared/src/persistence/elasticsearch/getReconciliationReport.js +++ b/shared/src/persistence/elasticsearch/getReconciliationReport.js @@ -46,6 +46,7 @@ exports.getReconciliationReport = async ({ searchParameters: { body: { _source: [ + 'pk', 'docketNumber', 'documentTitle', 'docketEntryId', From 923274983b864dae182c1016b17717ec8ff7ce57 Mon Sep 17 00:00:00 2001 From: Matt Hopson Date: Wed, 24 Mar 2021 12:27:27 -0600 Subject: [PATCH 4/8] 5311 - Ensure docketNumber gets added to signed stip docket entry --- .../src/business/useCases/saveSignedDocumentInteractor.js | 1 + .../business/useCases/saveSignedDocumentInteractor.test.js | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/shared/src/business/useCases/saveSignedDocumentInteractor.js b/shared/src/business/useCases/saveSignedDocumentInteractor.js index b301e2a3c84..3ff52c34d73 100644 --- a/shared/src/business/useCases/saveSignedDocumentInteractor.js +++ b/shared/src/business/useCases/saveSignedDocumentInteractor.js @@ -93,6 +93,7 @@ exports.saveSignedDocumentInteractor = async ( { createdAt: applicationContext.getUtilities().createISODateString(), docketEntryId: signedDocketEntryId, + docketNumber: caseRecord.docketNumber, documentTitle: SIGNED_DOCUMENT_TYPES.signedStipulatedDecision.documentType, documentType: diff --git a/shared/src/business/useCases/saveSignedDocumentInteractor.test.js b/shared/src/business/useCases/saveSignedDocumentInteractor.test.js index 5538e7b3064..b686ce2d58c 100644 --- a/shared/src/business/useCases/saveSignedDocumentInteractor.test.js +++ b/shared/src/business/useCases/saveSignedDocumentInteractor.test.js @@ -1,6 +1,7 @@ const { DOCUMENT_PROCESSING_STATUS_OPTIONS, PETITIONS_SECTION, + SIGNED_DOCUMENT_TYPES, } = require('../entities/EntityConstants'); const { saveSignedDocumentInteractor, @@ -100,6 +101,12 @@ describe('saveSignedDocumentInteractor', () => { ); expect(caseEntity.docketEntries.length).toEqual(MOCK_DOCUMENTS.length + 1); + const signedDocument = caseEntity.docketEntries.find( + e => + e.documentType === + SIGNED_DOCUMENT_TYPES.signedStipulatedDecision.documentType, + ); + expect(signedDocument.docketNumber).toEqual(caseEntity.docketNumber); const signedDocketEntryEntity = caseEntity.docketEntries.find( doc => From 54368aae0d264b026a913bf90222bb65a29851ed Mon Sep 17 00:00:00 2001 From: Matt Hopson Date: Wed, 24 Mar 2021 13:17:45 -0600 Subject: [PATCH 5/8] 5311 - DocketEntry Entity - set servedPartiesCode when setting doc as served --- shared/src/business/entities/DocketEntry.js | 29 ++++++++++- .../src/business/entities/DocketEntry.test.js | 49 ++++++++++++++++++- .../test/createTestApplicationContext.js | 3 +- .../utilities/getFormattedCaseDetail.js | 19 +------ web-client/src/applicationContext.js | 2 +- 5 files changed, 79 insertions(+), 23 deletions(-) diff --git a/shared/src/business/entities/DocketEntry.js b/shared/src/business/entities/DocketEntry.js index 1a8485147b3..798a28a145e 100644 --- a/shared/src/business/entities/DocketEntry.js +++ b/shared/src/business/entities/DocketEntry.js @@ -5,6 +5,8 @@ const { EXTERNAL_DOCUMENT_TYPES, NOTICE_OF_CHANGE_CONTACT_INFORMATION_EVENT_CODES, PRACTITIONER_ASSOCIATION_DOCUMENT_TYPES, + ROLES, + SERVED_PARTIES_CODES, TRACKED_DOCUMENT_TYPES_EVENT_CODES, } = require('./EntityConstants'); const { @@ -200,6 +202,7 @@ DocketEntry.prototype.setAsServed = function (servedParties = null) { if (servedParties) { this.servedParties = servedParties; + this.servedPartiesCode = getServedPartiesCode(servedParties); } }; @@ -370,4 +373,28 @@ const isServed = function (rawDocketEntry) { return !!rawDocketEntry.servedAt || !!rawDocketEntry.isLegacyServed; }; -module.exports = { DocketEntry: validEntityDecorator(DocketEntry), isServed }; +/** + * Determines the servedPartiesCode based on the given servedParties + * + * @returns {String} served parties code + */ +const getServedPartiesCode = servedParties => { + let servedPartiesCode = ''; + if (servedParties && servedParties.length > 0) { + if ( + servedParties.length === 1 && + servedParties[0].role === ROLES.irsSuperuser + ) { + servedPartiesCode = SERVED_PARTIES_CODES.RESPONDENT; + } else { + servedPartiesCode = SERVED_PARTIES_CODES.BOTH; + } + } + return servedPartiesCode; +}; + +module.exports = { + DocketEntry: validEntityDecorator(DocketEntry), + getServedPartiesCode, + isServed, +}; diff --git a/shared/src/business/entities/DocketEntry.test.js b/shared/src/business/entities/DocketEntry.test.js index 54f16a33bad..b753c728d13 100644 --- a/shared/src/business/entities/DocketEntry.test.js +++ b/shared/src/business/entities/DocketEntry.test.js @@ -11,10 +11,15 @@ const { ORDER_TYPES, PETITIONS_SECTION, ROLES, + SERVED_PARTIES_CODES, TRANSCRIPT_EVENT_CODE, } = require('./EntityConstants'); +const { + DocketEntry, + getServedPartiesCode, + isServed, +} = require('./DocketEntry'); const { applicationContext } = require('../test/createTestApplicationContext'); -const { DocketEntry, isServed } = require('./DocketEntry'); const { omit } = require('lodash'); const { WorkItem } = require('./WorkItem'); @@ -153,6 +158,48 @@ describe('DocketEntry entity', () => { }); }); + describe('getServedPartiesCode', () => { + it('returns an empty string if servedParties is undefined', () => { + const servedPartiesCode = getServedPartiesCode(); + expect(servedPartiesCode).toEqual(''); + }); + + it('returns an empty string if servedParties is an empty array', () => { + const servedPartiesCode = getServedPartiesCode([]); + expect(servedPartiesCode).toEqual(''); + }); + + it('returns the servedParties code for respondent if the only party in the given servedParties array has the irsSuperUser role', () => { + const servedPartiesCode = getServedPartiesCode([ + { + role: ROLES.irsSuperuser, + }, + ]); + expect(servedPartiesCode).toEqual(SERVED_PARTIES_CODES.RESPONDENT); + }); + + it('returns the servedParties code for both if the only party in the given servedParties array does not have the irsSuperUser role', () => { + const servedPartiesCode = getServedPartiesCode([ + { + role: ROLES.petitioner, + }, + ]); + expect(servedPartiesCode).toEqual(SERVED_PARTIES_CODES.BOTH); + }); + + it('returns the servedParties code for both if the the given servedParties array contains multiple servedParties', () => { + const servedPartiesCode = getServedPartiesCode([ + { + role: ROLES.irsSuperuser, + }, + { + role: ROLES.petitioner, + }, + ]); + expect(servedPartiesCode).toEqual(SERVED_PARTIES_CODES.BOTH); + }); + }); + describe('signedAt', () => { it('should implicitly set a signedAt for Notice event codes', () => { const myDoc = new DocketEntry( diff --git a/shared/src/business/test/createTestApplicationContext.js b/shared/src/business/test/createTestApplicationContext.js index e2b21f939a6..509be5b464e 100644 --- a/shared/src/business/test/createTestApplicationContext.js +++ b/shared/src/business/test/createTestApplicationContext.js @@ -66,7 +66,6 @@ const { formatCase, formatCaseDeadlines, formatDocketEntry, - getServedPartiesCode, sortDocketEntries, } = require('../../../src/business/utilities/getFormattedCaseDetail'); const { @@ -159,7 +158,7 @@ const { filterEmptyStrings } = require('../utilities/filterEmptyStrings'); const { formatDollars } = require('../utilities/formatDollars'); const { getConstants } = require('../../../../web-client/src/getConstants'); const { getItem } = require('../../persistence/localStorage/getItem'); -const { isServed } = require('../entities/DocketEntry'); +const { getServedPartiesCode, isServed } = require('../entities/DocketEntry'); const { removeItem } = require('../../persistence/localStorage/removeItem'); const { replaceBracketed } = require('../utilities/replaceBracketed'); const { ROLES } = require('../entities/EntityConstants'); diff --git a/shared/src/business/utilities/getFormattedCaseDetail.js b/shared/src/business/utilities/getFormattedCaseDetail.js index c0efd3203a1..c36c715c95c 100644 --- a/shared/src/business/utilities/getFormattedCaseDetail.js +++ b/shared/src/business/utilities/getFormattedCaseDetail.js @@ -15,23 +15,7 @@ const { } = require('../entities/EntityConstants'); const { Case } = require('../entities/cases/Case'); const { cloneDeep, isEmpty, sortBy } = require('lodash'); -const { isServed } = require('../entities/DocketEntry'); -const { ROLES } = require('../entities/EntityConstants'); - -const getServedPartiesCode = servedParties => { - let servedPartiesCode = ''; - if (servedParties && servedParties.length > 0) { - if ( - servedParties.length === 1 && - servedParties[0].role === ROLES.irsSuperuser - ) { - servedPartiesCode = SERVED_PARTIES_CODES.RESPONDENT; - } else { - servedPartiesCode = SERVED_PARTIES_CODES.BOTH; - } - } - return servedPartiesCode; -}; +const { getServedPartiesCode, isServed } = require('../entities/DocketEntry'); const TRANSCRIPT_AGE_DAYS_MIN = 90; const documentMeetsAgeRequirements = doc => { @@ -596,6 +580,5 @@ module.exports = { formatDocketEntry, getFilingsAndProceedings, getFormattedCaseDetail, - getServedPartiesCode, sortDocketEntries, }; diff --git a/web-client/src/applicationContext.js b/web-client/src/applicationContext.js index f7547e7d4f7..24f2e0ebe4f 100644 --- a/web-client/src/applicationContext.js +++ b/web-client/src/applicationContext.js @@ -5,6 +5,7 @@ import { } from '../../shared/src/business/entities/cases/Case'; import { DocketEntry, + getServedPartiesCode, isServed, } from '../../shared/src/business/entities/DocketEntry'; import { ErrorFactory } from './presenter/errors/ErrorFactory'; @@ -116,7 +117,6 @@ import { formatDocketEntry, getFilingsAndProceedings, getFormattedCaseDetail, - getServedPartiesCode, sortDocketEntries, } from '../../shared/src/business/utilities/getFormattedCaseDetail'; import { forwardMessageInteractor } from '../../shared/src/proxies/messages/forwardMessageProxy'; From ee40a945aa77feff81b00c8edfe57dce471db088 Mon Sep 17 00:00:00 2001 From: Matt Hopson Date: Wed, 24 Mar 2021 14:14:55 -0600 Subject: [PATCH 6/8] 5311 - Migration - update docketNumber and servedPartiesCode on docketEntry items --- .../main/lambdas/migration-segments.js | 9 +- ...entry-docket-number-served-parties-code.js | 41 ++++ ...-docket-number-served-parties-code.test.js | 176 ++++++++++++++++++ 3 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 web-api/migration-terraform/main/lambdas/migrations/0024-docket-entry-docket-number-served-parties-code.js create mode 100644 web-api/migration-terraform/main/lambdas/migrations/0024-docket-entry-docket-number-served-parties-code.test.js diff --git a/web-api/migration-terraform/main/lambdas/migration-segments.js b/web-api/migration-terraform/main/lambdas/migration-segments.js index c85d2553db6..3416c4d78f0 100644 --- a/web-api/migration-terraform/main/lambdas/migration-segments.js +++ b/web-api/migration-terraform/main/lambdas/migration-segments.js @@ -1,6 +1,10 @@ const AWS = require('aws-sdk'); const createApplicationContext = require('../../../src/applicationContext'); +const { + migrateItems: migration0024, +} = require('./migrations/0024-docket-entry-docket-number-served-parties-code'); + const { migrateItems: validationMigration, } = require('./migrations/0000-validate-all-items'); @@ -25,7 +29,10 @@ const sqs = new AWS.SQS({ region: 'us-east-1' }); // eslint-disable-next-line no-unused-vars const migrateRecords = async ({ documentClient, items }) => { - // applicationContext.logger.info('about to run validation migration'); + applicationContext.logger.info('about to run migration 0024'); + items = await migration0024(items, documentClient); + + applicationContext.logger.info('about to run validation migration'); items = await validationMigration(items, documentClient); return items; diff --git a/web-api/migration-terraform/main/lambdas/migrations/0024-docket-entry-docket-number-served-parties-code.js b/web-api/migration-terraform/main/lambdas/migrations/0024-docket-entry-docket-number-served-parties-code.js new file mode 100644 index 00000000000..8ee23f5997a --- /dev/null +++ b/web-api/migration-terraform/main/lambdas/migrations/0024-docket-entry-docket-number-served-parties-code.js @@ -0,0 +1,41 @@ +const createApplicationContext = require('../../../../src/applicationContext'); +const { + DocketEntry, + getServedPartiesCode, +} = require('../../../../../shared/src/business/entities/DocketEntry'); + +const applicationContext = createApplicationContext({}); + +const migrateItems = async items => { + const itemsAfter = []; + for (const item of items) { + if (item.pk.startsWith('case|') && item.sk.startsWith('docket-entry|')) { + if (!item.docketNumber) { + const docketNumber = item.pk.substr(item.pk.indexOf('|') + 1); + item.docketNumber = docketNumber; + } + + if ( + item.servedParties && + item.servedParties.length > 0 && + !item.servedPartiesCode + ) { + item.servedPartiesCode = getServedPartiesCode(item.servedParties); + } + + new DocketEntry(item, { applicationContext }).validate(); + + applicationContext.logger.info( + 'Updating docketNumber and/or servedPartiesCode for docketEntry', + { pk: item.pk, processingStatus: item.processingStatus, sk: item.sk }, + ); + + itemsAfter.push(item); + } else { + itemsAfter.push(item); + } + } + return itemsAfter; +}; + +exports.migrateItems = migrateItems; diff --git a/web-api/migration-terraform/main/lambdas/migrations/0024-docket-entry-docket-number-served-parties-code.test.js b/web-api/migration-terraform/main/lambdas/migrations/0024-docket-entry-docket-number-served-parties-code.test.js new file mode 100644 index 00000000000..2f7b9a2f56c --- /dev/null +++ b/web-api/migration-terraform/main/lambdas/migrations/0024-docket-entry-docket-number-served-parties-code.test.js @@ -0,0 +1,176 @@ +const { + migrateItems, +} = require('./0024-docket-entry-docket-number-served-parties-code'); +const { + ROLES, + SERVED_PARTIES_CODES, +} = require('../../../../../shared/src/business/entities/EntityConstants'); + +describe('migrateItems', () => { + let mockDocketEntry; + beforeEach(() => { + mockDocketEntry = { + createdAt: '2018-11-21T20:49:28.192Z', + docketEntryId: 'c6b81f4d-1e47-423a-8caf-6d2fdc3d3859', + documentTitle: 'Order that case is assigned to [Judge name] [Anything]', + documentType: 'Order that case is assigned', + eventCode: 'OAJ', + filedBy: 'Test Petitioner', + filingDate: '2018-03-01T00:01:00.000Z', + freeText: 'Cheese fries', + index: 1, + isFileAttached: true, + isOnDocketRecord: true, + judge: 'Fieri', + processingStatus: 'complete', + scenario: 'Type B', + signedAt: '2018-03-01T00:01:00.000Z', + signedByUserId: '7805d1ab-18d0-43ec-bafb-654e83405416', + signedJudgeName: 'Judge Guy Fieri', + sk: 'docket-entry|c6b81f4d-1e47-423a-8caf-6d2fdc3d3859', + userId: '7805d1ab-18d0-43ec-bafb-654e83405416', + }; + }); + + it('should return and not modify records that are NOT docket entries', async () => { + const items = [ + { + ...mockDocketEntry, + pk: 'case|000-00', + sk: 'case|6d74eadc-0181-4ff5-826c-305200e8733d', + }, + ]; + + const results = await migrateItems(items); + + expect(results).toEqual([ + { + ...mockDocketEntry, + pk: 'case|000-00', + sk: 'case|6d74eadc-0181-4ff5-826c-305200e8733d', + }, + ]); + }); + + it('should not modify the docketNumber field on records that already have a docketNumber field', async () => { + const items = [ + { + ...mockDocketEntry, + docketNumber: '123-45', + pk: 'case|000-00', // the pk is intentionally not matching the docket number to prove it does not get changed + sk: 'docket-entry|6d74eadc-0181-4ff5-826c-305200e8733d', + }, + ]; + + const results = await migrateItems(items); + + expect(results).toEqual([ + { + ...mockDocketEntry, + docketNumber: '123-45', + pk: 'case|000-00', + sk: 'docket-entry|6d74eadc-0181-4ff5-826c-305200e8733d', + }, + ]); + }); + + it('should not modify the servedPartiesCode field on records that do not have servedParties', async () => { + const items = [ + { + ...mockDocketEntry, + docketNumber: '123-45', + pk: 'case|123-45', + servedParties: undefined, + sk: 'docket-entry|6d74eadc-0181-4ff5-826c-305200e8733d', + }, + ]; + + const results = await migrateItems(items); + + expect(results).toEqual([ + { + ...mockDocketEntry, + docketNumber: '123-45', + pk: 'case|123-45', + sk: 'docket-entry|6d74eadc-0181-4ff5-826c-305200e8733d', + }, + ]); + }); + + it('should not modify the servedPartiesCode field on records that have servedParties and a servedPartiesCode already set', async () => { + const items = [ + { + ...mockDocketEntry, + docketNumber: '123-45', + pk: 'case|123-45', + servedAt: '2018-11-21T20:49:28.192Z', + servedParties: [{ name: 'Test Petitioner', role: ROLES.petitioner }], + servedPartiesCode: SERVED_PARTIES_CODES.BOTH, + sk: 'docket-entry|6d74eadc-0181-4ff5-826c-305200e8733d', + }, + ]; + + const results = await migrateItems(items); + + expect(results).toEqual([ + { + ...mockDocketEntry, + docketNumber: '123-45', + pk: 'case|123-45', + servedAt: '2018-11-21T20:49:28.192Z', + servedParties: [{ name: 'Test Petitioner', role: ROLES.petitioner }], + servedPartiesCode: SERVED_PARTIES_CODES.BOTH, + sk: 'docket-entry|6d74eadc-0181-4ff5-826c-305200e8733d', + }, + ]); + }); + + it('should set the docketNumber on the given item if it does not exist', async () => { + const items = [ + { + ...mockDocketEntry, + pk: 'case|123-45', + servedParties: undefined, + sk: 'docket-entry|6d74eadc-0181-4ff5-826c-305200e8733d', + }, + ]; + + const results = await migrateItems(items); + + expect(results).toEqual([ + { + ...mockDocketEntry, + docketNumber: '123-45', + pk: 'case|123-45', + sk: 'docket-entry|6d74eadc-0181-4ff5-826c-305200e8733d', + }, + ]); + }); + + it('should set the servedPartiesCode on the given item if there are servedParties but no servedPartiesCode', async () => { + const items = [ + { + ...mockDocketEntry, + docketNumber: '123-45', + pk: 'case|123-45', + servedAt: '2018-11-21T20:49:28.192Z', + servedParties: [{ name: 'IRS Superuser', role: ROLES.irsSuperuser }], + sk: 'docket-entry|6d74eadc-0181-4ff5-826c-305200e8733d', + }, + ]; + + const results = await migrateItems(items); + + expect(results).toEqual([ + { + ...mockDocketEntry, + docketNumber: '123-45', + pk: 'case|123-45', + servedAt: '2018-11-21T20:49:28.192Z', + servedParties: [{ name: 'IRS Superuser', role: ROLES.irsSuperuser }], + servedPartiesCode: SERVED_PARTIES_CODES.RESPONDENT, + sk: 'docket-entry|6d74eadc-0181-4ff5-826c-305200e8733d', + }, + ]); + }); +}); From 41f4f7a0f1173efac64a155c468ca6cef343063d Mon Sep 17 00:00:00 2001 From: Matt Hopson Date: Wed, 24 Mar 2021 14:21:36 -0600 Subject: [PATCH 7/8] 5311 - Case Entity - Ensure docketNumber gets added to docketEntry items via addDocketEntry method --- shared/src/business/entities/cases/Case.js | 2 ++ shared/src/business/entities/cases/Case.test.js | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/shared/src/business/entities/cases/Case.js b/shared/src/business/entities/cases/Case.js index 04184b56b5c..f80b3adba38 100644 --- a/shared/src/business/entities/cases/Case.js +++ b/shared/src/business/entities/cases/Case.js @@ -956,6 +956,8 @@ Case.prototype.removePrivatePractitioner = function (practitionerToRemove) { * @param {object} docketEntryEntity the docket entry to add to the case */ Case.prototype.addDocketEntry = function (docketEntryEntity) { + docketEntryEntity.docketNumber = this.docketNumber; + if (docketEntryEntity.isOnDocketRecord) { const updateIndex = shouldGenerateDocketRecordIndex({ caseDetail: this, diff --git a/shared/src/business/entities/cases/Case.test.js b/shared/src/business/entities/cases/Case.test.js index 9c21eacdbb6..3493e79c0ee 100644 --- a/shared/src/business/entities/cases/Case.test.js +++ b/shared/src/business/entities/cases/Case.test.js @@ -1576,10 +1576,10 @@ describe('Case entity', () => { }); }); - describe('addDocument', () => { + describe('addDocketEntry', () => { it('attaches the docket entry to the case', () => { const caseToVerify = new Case( - {}, + { docketNumber: '123-45' }, { applicationContext, }, @@ -1592,6 +1592,7 @@ describe('Case entity', () => { expect(caseToVerify.docketEntries.length).toEqual(1); expect(caseToVerify.docketEntries[0]).toMatchObject({ docketEntryId: '123', + docketNumber: '123-45', documentType: 'Answer', userId: 'irsPractitioner', }); From 21cf8748ccf8928f8515fe4aede413c7de2857bb Mon Sep 17 00:00:00 2001 From: Kris Koskelin Date: Wed, 24 Mar 2021 16:22:01 -0500 Subject: [PATCH 8/8] 5311: updating v2 API documentation added /v2/reconciliation-report information --- docs/api/v2.yaml | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/docs/api/v2.yaml b/docs/api/v2.yaml index 72f247db20d..f53e9495247 100644 --- a/docs/api/v2.yaml +++ b/docs/api/v2.yaml @@ -83,6 +83,37 @@ paths: $ref: '#/components/responses/NotFoundError' '500': $ref: '#/components/responses/ServerError' + /reconciliation-report/{date}: + get: + summary: fetches a list of docket entries served on a date + operationId: + tags: + - irs + description: | + By passing in a date, you can retrieve a list of docket entries served on that date + parameters: + - in: path + name: date + description: A specific date, Eastern time with format YYYY-MM-DD; or 'today' + required: true + schema: + type: string + responses: + '200': + description: + content: + application/json: + schema: + $ref: '#/components/schemas/Report' + '401': + $ref: '#/components/responses/UnauthorizedError' + '403': + $ref: '#/components/responses/ForbiddenError' + '404': + $ref: '#/components/responses/NotFoundError' + '500': + $ref: '#/components/responses/ServerError' +​ components: securitySchemes: bearerAuth: @@ -256,3 +287,47 @@ components: properties: message: type: string + Report: + type: object + properties: + docketEntries: + type: array + items: + $ref: '#/components/schemas/ServedDocument' + reportTitle: + type: string + example: Reconciliation Report + totalDocketEntries: + type: number + example: 0 + reconcilationDate: + type: string + format: date + example: '2020-03-19' + ServedDocument: + type: object + properties: + docketNumber: + type: string + example: '123-20' + description: + type: string + example: 'Request for Place of Trial at Lubbock, Texas' + docketEntryId: + type: string + example: 'e6ab9240-ed8b-4bde-95a8-eb3bccbd6200' + eventCode: + type: string + example: 'RQT' + filedBy: + type: string + example: 'Petr. John Doe' + filingDate: + type: string + example: '2021-01-26T17:25:38.186Z' + caseCaption: + type: string + example: 'John Doe, Petitioner' + servedAt: + type: string + example: '2021-01-05T21:14:09.031Z' \ No newline at end of file