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

CAMS-442 update mongo keys and refactor case assigment #1004

Merged
merged 25 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4a42d69
removed unique key policy on office_code for cosmos resource
amorrow-flexion Nov 5, 2024
d861f54
added uniqe enforcement and id index on mongo collections
amorrow-flexion Nov 5, 2024
437cbd6
Revert "added uniqe enforcement and id index on mongo collections"
amorrow-flexion Nov 5, 2024
3e9e443
added compound unique key for officecode & userId on offices collection
amorrow-flexion Nov 5, 2024
4997556
noticed a discrepency in the e2e test and cleared that up
amorrow-flexion Nov 5, 2024
739477d
added authorize uri to okta-gateway and tests
amorrow-flexion Nov 5, 2024
27a12a9
Revert "added authorize uri to okta-gateway and tests"
amorrow-flexion Nov 6, 2024
1344d05
changed scaling plan for node api in bicep
amorrow-flexion Nov 6, 2024
1a5acf9
fixed suffix on dns zone
amorrow-flexion Nov 6, 2024
efa9325
Revert "fixed suffix on dns zone"
amorrow-flexion Nov 6, 2024
d660954
Revert "changed scaling plan for node api in bicep"
amorrow-flexion Nov 6, 2024
3793add
WIP - Deploy experiment to fix 401 errors
jamesobrooks Nov 6, 2024
9a0c9fa
WIP - fix types of assignments
jamesobrooks Nov 6, 2024
decd0a5
completion of Case assignment refactor
amorrow-flexion Nov 7, 2024
16f383c
Merge pull request #1011 from US-Trustee-Program/CAMS-442-performance…
amorrow-flexion Nov 7, 2024
55ed5a6
fixed common test
amorrow-flexion Nov 7, 2024
52d74f3
Remove console.log
btposey Nov 7, 2024
30b36a1
Remove console.log
btposey Nov 7, 2024
f74d77f
Simplify jest mock.
btposey Nov 7, 2024
70b5377
Simplify jest mock.
btposey Nov 7, 2024
4cb6131
Remove unused assignedOn field.
btposey Nov 7, 2024
2a645a9
Merge branch 'main' into CAMS-442-office-staff-fix
btposey Nov 7, 2024
a2c663f
Fix broken jest mockResolveValue calls.
btposey Nov 7, 2024
aa3bd72
Depend on tests again
jamesobrooks Nov 7, 2024
deb1185
Only pass request
jamesobrooks Nov 8, 2024
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
5 changes: 0 additions & 5 deletions .github/workflows/continuous-deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,6 @@ jobs:
[
setup,
build,
accessibility-test,
security-scan,
unit-test-frontend,
unit-test-backend,
unit-test-common,
jamesobrooks marked this conversation as resolved.
Show resolved Hide resolved
]
if: ((github.ref == 'refs/heads/main') || (github.ref == 'refs/heads/dependency-updates-auto') || (inputs.deployBranch == 'true'))
with:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ describe('offices repo', () => {
MockData.getAttorneyAssignment({ caseId }),
];
jest.spyOn(MongoCollectionAdapter.prototype, 'find').mockResolvedValue(mockAssignments);
const actualAssignment = await repo.findAssignmentsByCaseId(caseId);
const actualAssignment = await repo.findAssignmentsByCaseId([caseId]);

expect(actualAssignment).toEqual(mockAssignments);
expect(actualAssignment).toEqual(new Map([[caseId, mockAssignments]]));
});
});

Expand Down Expand Up @@ -105,7 +105,7 @@ describe('offices repo', () => {
test('should handle error on findAssignmentsByCaseId', async () => {
const caseId = '111-22-33333';
jest.spyOn(MongoCollectionAdapter.prototype, 'find').mockRejectedValue(error);
await expect(async () => await repo.findAssignmentsByCaseId(caseId)).rejects.toThrow(
await expect(async () => await repo.findAssignmentsByCaseId([caseId])).rejects.toThrow(
getCamsError(
error,
'MONGO_COSMOS_DB_REPOSITORY_ASSIGNMENTS',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { BaseMongoRepository } from './utils/base-mongo-repository';
const MODULE_NAME: string = 'CASE_ASSIGNMENT_MONGO_REPOSITORY';
const COLLECTION_NAME = 'assignments';

const { and, equals, exists } = QueryBuilder;
const { and, equals, exists, contains } = QueryBuilder;

export class CaseAssignmentMongoRepository
extends BaseMongoRepository
Expand All @@ -35,16 +35,28 @@ export class CaseAssignmentMongoRepository
}
}

async findAssignmentsByCaseId(caseId: string): Promise<CaseAssignment[]> {
async findAssignmentsByCaseId(caseIds: string[]): Promise<Map<string, CaseAssignment[]>> {
const query = QueryBuilder.build(
and(
equals<CaseAssignment['documentType']>('documentType', 'ASSIGNMENT'),
equals<CaseAssignment['caseId']>('caseId', caseId),
contains<string[]>('caseId', caseIds),
exists<CaseAssignment>('unassignedOn', false),
),
);
try {
return await this.getAdapter<CaseAssignment>().find(query);
const assignments = await this.getAdapter<CaseAssignment>().find(query);
const assignmentsMap = new Map();
assignments.forEach((assignment) => {
if (assignmentsMap.has(assignment.caseId)) {
assignmentsMap.set(assignment.caseId, [
...assignmentsMap.get(assignment.caseId),
assignment,
]);
} else {
assignmentsMap.set(assignment.caseId, [assignment]);
}
});
return assignmentsMap;
} catch (originalError) {
throw getCamsError(originalError, MODULE_NAME, 'Unable to retrieve assignment.');
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ApplicationContext } from '../../types/basic';
import { AttorneyUser, CamsUserReference } from '../../../../../../common/src/cams/users';
import { AttorneyUser, CamsUserReference, Staff } from '../../../../../../common/src/cams/users';
import { Auditable, createAuditRecord } from '../../../../../../common/src/cams/auditable';
import { CamsRole } from '../../../../../../common/src/cams/roles';
import { getCamsUserReference } from '../../../../../../common/src/cams/session';
Expand All @@ -13,7 +13,7 @@ const COLLECTION_NAME = 'offices';

const { and, equals, contains } = QueryBuilder;

export type OfficeStaff = CamsUserReference &
export type OfficeStaff = Staff &
Auditable & {
documentType: 'OFFICE_STAFF';
officeCode: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export class MongoCollectionAdapter<T> implements DocumentCollectionAdapter<T> {

public async find(query: ConditionOrConjunction, sort?: Sort): Promise<T[]> {
const mongoQuery = toMongoQuery(query);
console.log(mongoQuery);
btposey marked this conversation as resolved.
Show resolved Hide resolved
const mongoSort = sort ? toMongoSort(sort) : undefined;
try {
const findPromise = this.collectionHumble.find(mongoQuery);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,18 @@ describe('Case Assignment Creation Tests', () => {
});

test('should fetch a list of assignments when a GET request is called', async () => {
const assignments = MockData.buildArray(MockData.getAttorneyAssignment, 3);
const caseId = '111-22-33333';
const assignments = MockData.buildArray(() => MockData.getAttorneyAssignment({ caseId }), 3);
const camsHttpResponse = httpSuccess({ body: { data: assignments } });
const expectedMap = new Map([[caseId, assignments]]);
applicationContext.request = mockCamsHttpRequest({
method: 'GET',
params: { id: caseId },
});

jest
.spyOn(CaseAssignmentUseCase.prototype, 'findAssignmentsByCaseId')
.mockResolvedValue(assignments);
.mockResolvedValue(expectedMap);

const assignmentController = new CaseAssignmentController(applicationContext);
const result = await assignmentController.handleRequest(applicationContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ export class CaseAssignmentController implements CamsController {
statusCode: HttpStatusCodes.CREATED,
});
} else {
const assignments = await assignmentUseCase.findAssignmentsByCaseId(
const assignmentsMap = await assignmentUseCase.findAssignmentsByCaseId([
context.request.params['id'],
);
]);
const assignments = assignmentsMap.get(context.request.params['id']);
return httpSuccess({
body: {
data: assignments,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ describe('cases controller test', () => {
body: expected,
});
await controller.searchCases(camsHttpRequest);
expect(useCaseSpy).toHaveBeenCalledWith(expect.anything(), expected);
expect(useCaseSpy).toHaveBeenCalledWith(expect.anything(), expected, false);
});

test('should return an error if an error is encountered', async () => {
Expand Down
23 changes: 19 additions & 4 deletions backend/functions/lib/controllers/cases/cases.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class CasesController implements CamsController {
if (context.request.method === 'GET' && context.request.params.caseId) {
data = await this.getCaseDetails({ caseId: context.request.params.caseId });
} else {
data = await this.searchCases(context.request);
data = await this.searchCases(context.request, context.request.query ?? {});
fmaddenflx marked this conversation as resolved.
Show resolved Hide resolved
}
return httpSuccess({ body: data });
} catch (originalError) {
Expand All @@ -50,23 +50,36 @@ export class CasesController implements CamsController {
return { data };
}

public async searchCases(request: CamsHttpRequest) {
public async searchCases(
request: CamsHttpRequest,
options: { includeAssignments?: boolean } = {},
) {
const predicate = request.body as CasesSearchPredicate;
const body = await this.paginateSearchCases(predicate, request.url);
const body = await this.paginateSearchCases(
predicate,
request.url,
options.includeAssignments ?? false,
);
return body;
}

async paginateSearchCases(
predicate: CasesSearchPredicate,
url: string,
includeAssignments: boolean,
): Promise<ResponseBody<ResourceActions<CaseBasics>[]>> {
const cases = await this.caseManagement.searchCases(this.applicationContext, predicate);
const cases = await this.caseManagement.searchCases(
this.applicationContext,
predicate,
includeAssignments,
);

const pagination: Pagination = {
count: cases.length,
limit: predicate.limit,
currentPage: getCurrentPage(cases.length, predicate),
};

if (cases.length > predicate.limit) {
const next = new URL(url);
next.searchParams.set('limit', predicate.limit.toString());
Expand All @@ -75,12 +88,14 @@ export class CasesController implements CamsController {
cases.pop();
pagination.count = cases.length;
}

if (predicate.offset > 0) {
const previous = new URL(url);
previous.searchParams.set('limit', predicate.limit.toString());
previous.searchParams.set('offset', (predicate.offset - predicate.limit).toString());
pagination.previous = previous.href;
}

return {
meta: {
self: url,
Expand Down
18 changes: 10 additions & 8 deletions backend/functions/lib/use-cases/case-assignment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,16 @@ describe('Case assignment tests', () => {
assignedOn: new Date().toISOString(),
},
];
findAssignmentsByCaseId.mockResolvedValue(assignments);

const expectedMap = new Map([[caseId, assignments]]);
findAssignmentsByCaseId.mockResolvedValue(expectedMap);

const assignmentUseCase = new CaseAssignmentUseCase(applicationContext);

const actualAssignments = await assignmentUseCase.findAssignmentsByCaseId(caseId);
const actualAssignments = await assignmentUseCase.findAssignmentsByCaseId([caseId]);

expect(actualAssignments.length).toEqual(2);
expect(actualAssignments).toEqual(expect.arrayContaining(assignments));
expect(actualAssignments.get(caseId).length).toEqual(2);
expect(actualAssignments).toEqual(expectedMap);
});
});

Expand Down Expand Up @@ -145,6 +147,8 @@ describe('Case assignment tests', () => {
role,
};

findAssignmentsByCaseId.mockResolvedValue(new Map([[caseId, []]]));

expect(createAssignment.mock.calls[0][0]).toEqual(expect.objectContaining(assignmentOne));
expect(createAssignment.mock.calls[1][0]).toEqual(expect.objectContaining(assignmentTwo));
});
Expand Down Expand Up @@ -172,9 +176,7 @@ describe('Case assignment tests', () => {
role,
};

jest
.spyOn(MockMongoRepository.prototype, 'findAssignmentsByCaseId')
.mockResolvedValue([assignmentOne]);
findAssignmentsByCaseId.mockResolvedValue(new Map([[caseId, [assignmentOne]]]));

await assignmentUseCase.createTrialAttorneyAssignments(
applicationContext,
Expand Down Expand Up @@ -205,7 +207,7 @@ describe('Case assignment tests', () => {
role,
};

findAssignmentsByCaseId.mockResolvedValue([assignmentOne]);
findAssignmentsByCaseId.mockResolvedValue(new Map([[caseId, [assignmentOne]]]));

await assignmentUseCase.createTrialAttorneyAssignments(
applicationContext,
Expand Down
15 changes: 10 additions & 5 deletions backend/functions/lib/use-cases/case-assignment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,10 @@ export class CaseAssignmentUseCase {
});
const listOfAssignmentIdsCreated: string[] = [];

const existingAssignmentRecords =
await this.assignmentRepository.findAssignmentsByCaseId(caseId);
const existingAssignmentRecordsMap = await this.assignmentRepository.findAssignmentsByCaseId([
caseId,
]);
const existingAssignmentRecords = existingAssignmentRecordsMap.get(caseId) ?? [];
for (const existingAssignment of existingAssignmentRecords) {
const stillAssigned = listOfAssignments.find((newAssignment) => {
return (
Expand All @@ -113,7 +115,10 @@ export class CaseAssignmentUseCase {
}
}

const newAssignmentRecords = await this.assignmentRepository.findAssignmentsByCaseId(caseId);
const newAssignmentRecordsMap = await this.assignmentRepository.findAssignmentsByCaseId([
caseId,
]);
const newAssignmentRecords = newAssignmentRecordsMap.get(caseId);
const history = createAuditRecord<CaseAssignmentHistory>(
{
caseId,
Expand All @@ -135,8 +140,8 @@ export class CaseAssignmentUseCase {
return listOfAssignmentIdsCreated;
}

public async findAssignmentsByCaseId(caseId: string): Promise<CaseAssignment[]> {
return await this.assignmentRepository.findAssignmentsByCaseId(caseId);
public async findAssignmentsByCaseId(caseIds: string[]): Promise<Map<string, CaseAssignment[]>> {
return await this.assignmentRepository.findAssignmentsByCaseId(caseIds);
}

public async getCaseLoad(userId: string): Promise<number> {
Expand Down
Loading
Loading