Skip to content

Commit dbf1de0

Browse files
btposeyfmaddenflxjamesobrooks
committed
Add legacy division guard to transfer order actions
Jira ticket: CAMS-473 Co-authored-by: Fritz Madden <[email protected]> Co-authored-by: James Brooks <[email protected]> Co-authored-by: Brian Posey <[email protected]>,
1 parent ddf83f0 commit dbf1de0

File tree

5 files changed

+83
-0
lines changed

5 files changed

+83
-0
lines changed

backend/functions/lib/controllers/orders/orders.controller.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
getOrdersGateway,
99
getOrdersRepository,
1010
getRuntimeStateRepository,
11+
getStorageGateway,
1112
} from '../../factory';
1213
import { OrdersUseCase, SyncOrdersOptions, SyncOrdersStatus } from '../../use-cases/orders/orders';
1314
import {
@@ -46,6 +47,7 @@ export class OrdersController implements CamsController, CamsTimerController {
4647
getOrdersGateway(context),
4748
getRuntimeStateRepository<OrderSyncState>(context),
4849
getConsolidationOrdersRepository(context),
50+
getStorageGateway(context),
4951
);
5052
}
5153

backend/functions/lib/use-cases/orders/orders-consolidation-approval.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
getCasesRepository,
1111
getCasesGateway,
1212
getConsolidationOrdersRepository,
13+
getStorageGateway,
1314
} from '../../factory';
1415
import {
1516
ConsolidationOrderActionApproval,
@@ -56,6 +57,7 @@ describe('Orders use case', () => {
5657
ordersGateway,
5758
runtimeStateRepo,
5859
consolidationRepo,
60+
getStorageGateway(mockContext),
5961
);
6062
});
6163

backend/functions/lib/use-cases/orders/orders-local-gateway.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
getOrdersGateway,
1414
getOrdersRepository,
1515
getRuntimeStateRepository,
16+
getStorageGateway,
1617
} from '../../factory';
1718
import { CasesRepository, ConsolidationOrdersRepository } from '../gateways.types';
1819
import { ApplicationContext } from '../../adapters/types/basic';
@@ -125,6 +126,8 @@ describe('orders use case tests', () => {
125126
let ordersRepo;
126127
let runtimeStateRepo;
127128
let casesGateway;
129+
let storageGateway;
130+
128131
const authorizedUser = MockData.getCamsUser({
129132
roles: [CamsRole.DataVerifier],
130133
offices: [REGION_02_GROUP_NY],
@@ -137,6 +140,7 @@ describe('orders use case tests', () => {
137140
runtimeStateRepo = getRuntimeStateRepository(mockContext);
138141
ordersRepo = getOrdersRepository(mockContext);
139142
casesGateway = getCasesGateway(mockContext);
143+
storageGateway = getStorageGateway(mockContext);
140144
});
141145

142146
test('should not create a second lead case for an existing consolidation', async () => {
@@ -159,6 +163,7 @@ describe('orders use case tests', () => {
159163
ordersGateway,
160164
runtimeStateRepo,
161165
localConsolidationsRepo,
166+
storageGateway,
162167
);
163168

164169
// attempt to set up a consolidation with a different lead case

backend/functions/lib/use-cases/orders/orders.test.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import {
1010
getCasesRepository,
1111
getCasesGateway,
1212
getConsolidationOrdersRepository,
13+
getStorageGateway,
1314
} from '../../factory';
15+
import * as factory from '../../factory';
1416
import { OrderSyncState } from '../gateways.types';
1517
import {
1618
ConsolidationOrder,
@@ -41,6 +43,7 @@ import { CaseAssignmentUseCase } from '../case-assignment';
4143
import { REGION_02_GROUP_NY } from '../../../../../common/src/cams/test-utilities/mock-user';
4244
import { getCourtDivisionCodes } from '../../../../../common/src/cams/users';
4345
import { MockMongoRepository } from '../../testing/mock-gateways/mock-mongo.repository';
46+
import { UstpDivisionMeta } from '../../../../../common/src/cams/offices';
4447

4548
describe('Orders use case', () => {
4649
const CASE_ID = '000-11-22222';
@@ -51,6 +54,8 @@ describe('Orders use case', () => {
5154
let runtimeStateRepo;
5255
let casesGateway;
5356
let consolidationRepo;
57+
let storageGateway;
58+
5459
let useCase: OrdersUseCase;
5560
const authorizedUser = MockData.getCamsUser({
5661
roles: [CamsRole.DataVerifier],
@@ -67,13 +72,15 @@ describe('Orders use case', () => {
6772
casesRepo = getCasesRepository(mockContext);
6873
casesGateway = getCasesGateway(mockContext);
6974
consolidationRepo = getConsolidationOrdersRepository(mockContext);
75+
storageGateway = getStorageGateway(mockContext);
7076
useCase = new OrdersUseCase(
7177
casesRepo,
7278
casesGateway,
7379
ordersRepo,
7480
ordersGateway,
7581
runtimeStateRepo,
7682
consolidationRepo,
83+
storageGateway,
7784
);
7885
});
7986

@@ -639,4 +646,55 @@ describe('Orders use case', () => {
639646
expect.objectContaining({ updatedBy: getCamsUserReference(authorizedUser) }),
640647
);
641648
});
649+
650+
test('should fail to update to a legacy office', async () => {
651+
const courtDivisionCode = '000';
652+
jest.spyOn(factory, 'getStorageGateway').mockImplementation(() => {
653+
return {
654+
get: jest.fn(),
655+
getRoleMapping: jest.fn(),
656+
getUstpOffices: jest.fn(),
657+
getUstpDivisionMeta: jest.fn().mockImplementation(() => {
658+
return new Map<string, UstpDivisionMeta>([[courtDivisionCode, { isLegacy: true }]]);
659+
}),
660+
};
661+
});
662+
663+
const localUseCase = new OrdersUseCase(
664+
casesRepo,
665+
casesGateway,
666+
ordersRepo,
667+
ordersGateway,
668+
runtimeStateRepo,
669+
consolidationRepo,
670+
factory.getStorageGateway(mockContext),
671+
);
672+
673+
const newCase = MockData.getCaseSummary({ override: { courtDivisionCode } });
674+
const order: TransferOrder = MockData.getTransferOrder({
675+
override: { status: 'approved', newCase },
676+
});
677+
678+
const action: TransferOrderAction = {
679+
id: order.id,
680+
orderType: 'transfer',
681+
caseId: order.caseId,
682+
newCase: order.newCase,
683+
status: 'approved',
684+
};
685+
686+
const updateOrderFn = jest.spyOn(ordersRepo, 'update').mockResolvedValue({ id: 'mock-guid' });
687+
const getOrderFn = jest.spyOn(ordersRepo, 'read').mockResolvedValue(order);
688+
const transferToFn = jest.spyOn(casesRepo, 'createTransferTo');
689+
const transferFromFn = jest.spyOn(casesRepo, 'createTransferFrom');
690+
const auditFn = jest.spyOn(casesRepo, 'createCaseHistory');
691+
mockContext.session = await createMockApplicationContextSession({ user: authorizedUser });
692+
693+
await expect(localUseCase.updateTransferOrder(mockContext, order.id, action)).rejects.toThrow();
694+
expect(updateOrderFn).not.toHaveBeenCalled();
695+
expect(getOrderFn).not.toHaveBeenCalled();
696+
expect(transferToFn).not.toHaveBeenCalled();
697+
expect(transferFromFn).not.toHaveBeenCalled();
698+
expect(auditFn).not.toHaveBeenCalled();
699+
});
642700
});

backend/functions/lib/use-cases/orders/orders.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import { UnauthorizedError } from '../../common-errors/unauthorized-error';
4747
import { createAuditRecord } from '../../../../../common/src/cams/auditable';
4848
import { OrdersSearchPredicate } from '../../../../../common/src/api/search';
4949
import { isNotFoundError } from '../../common-errors/not-found-error';
50+
import { StorageGateway } from '../../adapters/types/storage';
5051

5152
const MODULE_NAME = 'ORDERS_USE_CASE';
5253

@@ -70,6 +71,7 @@ export class OrdersUseCase {
7071
private readonly ordersRepo: OrdersRepository;
7172
private readonly consolidationsRepo: ConsolidationOrdersRepository;
7273
private readonly runtimeStateRepo: RuntimeStateRepository<OrderSyncState>;
74+
private readonly storageGateway: StorageGateway;
7375

7476
constructor(
7577
casesRepo: CasesRepository,
@@ -78,13 +80,15 @@ export class OrdersUseCase {
7880
ordersGateway: OrdersGateway,
7981
runtimeRepo: RuntimeStateRepository<OrderSyncState>,
8082
consolidationRepo: ConsolidationOrdersRepository,
83+
storageGateway: StorageGateway,
8184
) {
8285
this.casesRepo = casesRepo;
8386
this.casesGateway = casesGateway;
8487
this.ordersRepo = ordersRepo;
8588
this.ordersGateway = ordersGateway;
8689
this.runtimeStateRepo = runtimeRepo;
8790
this.consolidationsRepo = consolidationRepo;
91+
this.storageGateway = storageGateway;
8892
}
8993

9094
public async getOrders(context: ApplicationContext): Promise<Array<Order>> {
@@ -114,6 +118,18 @@ export class OrdersUseCase {
114118
throw new UnauthorizedError(MODULE_NAME);
115119
}
116120

121+
const divisionMeta = this.storageGateway.getUstpDivisionMeta();
122+
const divisionCodeMaybe = data['newCase'] ? data['newCase'].courtDivisionCode : null;
123+
if (
124+
divisionCodeMaybe &&
125+
divisionMeta.has(divisionCodeMaybe) &&
126+
divisionMeta.get(divisionCodeMaybe).isLegacy
127+
) {
128+
throw new BadRequestError(MODULE_NAME, {
129+
message: 'Cannot transfer to legacy division.',
130+
});
131+
}
132+
117133
context.logger.info(MODULE_NAME, 'Updating transfer order:', data);
118134
const initialOrder = await this.ordersRepo.read(id, data.caseId);
119135
let order: Order;

0 commit comments

Comments
 (0)