From 806b5906f91d2bbcbe1911aa8864ee19e0bfcaa1 Mon Sep 17 00:00:00 2001
From: Diana Barsan <35681649+dianabarsan@users.noreply.github.com>
Date: Fri, 13 Sep 2024 16:43:37 +0300
Subject: [PATCH] fix(#9429): pass 500 reports to forms contact summar (#9436)
---
.../enketo/config/contact-summary-reports.js | 8 +++
.../contact-summary-reports.wdio-spec.js | 46 +++++++++++++++++
.../enketo/forms/contact-summary-reports.xml | 51 +++++++++++++++++++
.../default/enketo/common-enketo.wdio.page.js | 4 ++
.../contact-view-model-generator.service.ts | 8 +--
webapp/src/ts/services/form.service.ts | 9 ++--
.../karma/ts/services/form.service.spec.ts | 13 +++--
7 files changed, 123 insertions(+), 16 deletions(-)
create mode 100644 tests/e2e/default/enketo/config/contact-summary-reports.js
create mode 100644 tests/e2e/default/enketo/contact-summary-reports.wdio-spec.js
create mode 100644 tests/e2e/default/enketo/forms/contact-summary-reports.xml
diff --git a/tests/e2e/default/enketo/config/contact-summary-reports.js b/tests/e2e/default/enketo/config/contact-summary-reports.js
new file mode 100644
index 0000000000..617c09d4ee
--- /dev/null
+++ b/tests/e2e/default/enketo/config/contact-summary-reports.js
@@ -0,0 +1,8 @@
+module.exports = {
+ cards: [],
+ fields: [],
+ context: {
+ // eslint-disable-next-line no-undef
+ nbr_reports: reports.length,
+ }
+};
diff --git a/tests/e2e/default/enketo/contact-summary-reports.wdio-spec.js b/tests/e2e/default/enketo/contact-summary-reports.wdio-spec.js
new file mode 100644
index 0000000000..6d4c09d933
--- /dev/null
+++ b/tests/e2e/default/enketo/contact-summary-reports.wdio-spec.js
@@ -0,0 +1,46 @@
+const commonPage = require('@page-objects/default/common/common.wdio.page');
+const utils = require('@utils');
+const { cookieLogin } = require('@page-objects/default/login/login.wdio.page');
+const commonEnketoPage = require('@page-objects/default/enketo/common-enketo.wdio.page');
+const chtConfUtils = require('@utils/cht-conf');
+const path = require('path');
+const placeFactory = require('@factories/cht/contacts/place');
+const personFactory = require('@factories/cht/contacts/person');
+const reportsFactory = require('@factories/cht/reports/generic-report');
+
+describe('Contact summary', () => {
+
+ const places = placeFactory.generateHierarchy();
+ const clinic = places.get('clinic');
+ const patient = personFactory.build({
+ name: 'Patient',
+ phone: '+50683444444',
+ patient_id: '12345',
+ parent: { _id: clinic._id, parent: clinic.parent }
+ });
+ const reports = Array
+ .from({ length: 100 })
+ .map(() => reportsFactory.report().build(
+ { form: 'home_visit', content_type: 'xml' },
+ { patient }
+ ));
+
+ before(async () => {
+ await commonEnketoPage.uploadForm('contact-summary-reports');
+ await chtConfUtils.initializeConfigDir();
+ const contactSummaryFile = path.join(__dirname, 'config/contact-summary-reports.js');
+ const { contactSummary } = await chtConfUtils.compileNoolsConfig({ contactSummary: contactSummaryFile });
+ await utils.updateSettings({ contact_summary: contactSummary }, true);
+
+ await utils.saveDocs([...places.values(), patient, ...reports]);
+
+ await cookieLogin();
+ });
+
+ it('should load all reports', async () => {
+ await commonPage.goToPeople(patient._id);
+ await commonPage.openFastActionReport('contact-summary-reports', true);
+
+ expect(await commonEnketoPage.getInputValue('Number of reports')).to.equal(reports.length.toString());
+ });
+});
diff --git a/tests/e2e/default/enketo/forms/contact-summary-reports.xml b/tests/e2e/default/enketo/forms/contact-summary-reports.xml
new file mode 100644
index 0000000000..0aa07c0c6c
--- /dev/null
+++ b/tests/e2e/default/enketo/forms/contact-summary-reports.xml
@@ -0,0 +1,51 @@
+
+
+
+ Just a form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PARENT
+ person
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/page-objects/default/enketo/common-enketo.wdio.page.js b/tests/page-objects/default/enketo/common-enketo.wdio.page.js
index edcb67887a..8317979364 100644
--- a/tests/page-objects/default/enketo/common-enketo.wdio.page.js
+++ b/tests/page-objects/default/enketo/common-enketo.wdio.page.js
@@ -87,6 +87,10 @@ const uploadForm = async (formName, saveDoc = true) => {
internalId: formName,
title: formName,
type: 'form',
+ context: {
+ person: true,
+ place: true,
+ },
_attachments: {
xml: {
content_type: 'application/octet-stream',
diff --git a/webapp/src/ts/services/contact-view-model-generator.service.ts b/webapp/src/ts/services/contact-view-model-generator.service.ts
index 4f261f1ac4..af6d28e55e 100644
--- a/webapp/src/ts/services/contact-view-model-generator.service.ts
+++ b/webapp/src/ts/services/contact-view-model-generator.service.ts
@@ -1,9 +1,5 @@
import { Injectable, NgZone } from '@angular/core';
-import {
- groupBy as _groupBy,
- partial as _partial,
- find as _find,
-} from 'lodash-es';
+import { find as _find, groupBy as _groupBy, partial as _partial, } from 'lodash-es';
import registrationUtils from '@medic/registration-utils';
@@ -315,7 +311,7 @@ export class ContactViewModelGeneratorService {
private _loadReports(model, forms) {
const contacts = [ model.doc ];
- model.children.forEach(group => {
+ model.children?.forEach(group => {
if (group?.type?.person) {
group.contacts.forEach(contact => contacts.push(contact.doc));
}
diff --git a/webapp/src/ts/services/form.service.ts b/webapp/src/ts/services/form.service.ts
index 7991c4bee3..8e4f99deb3 100644
--- a/webapp/src/ts/services/form.service.ts
+++ b/webapp/src/ts/services/form.service.ts
@@ -26,6 +26,7 @@ import { ContactSaveService } from '@mm-services/contact-save.service';
import { reduce as _reduce } from 'lodash-es';
import { ContactTypesService } from '@mm-services/contact-types.service';
import { TargetAggregatesService } from '@mm-services/target-aggregates.service';
+import { ContactViewModelGeneratorService } from '@mm-services/contact-view-model-generator.service';
/**
* Service for interacting with forms. This is the primary entry-point for CHT code to render forms and save the
@@ -58,6 +59,7 @@ export class FormService {
private chtDatasourceService: CHTDatasourceService,
private enketoService: EnketoService,
private targetAggregatesService: TargetAggregatesService,
+ private contactViewModelGeneratorService: ContactViewModelGeneratorService,
) {
this.inited = this.init();
this.globalActions = new GlobalActions(store);
@@ -127,12 +129,7 @@ export class FormService {
}
private getContactReports(contact) {
- const subjectIds = [contact._id];
- const shortCode = contact.patient_id || contact.place_id;
- if (shortCode) {
- subjectIds.push(shortCode);
- }
- return this.searchService.search('reports', { subjectIds: subjectIds }, { include_docs: true });
+ return this.contactViewModelGeneratorService.loadReports({ doc: contact }, []);
}
private getTargetDocs(contact) {
diff --git a/webapp/tests/karma/ts/services/form.service.spec.ts b/webapp/tests/karma/ts/services/form.service.spec.ts
index e7f4be23be..5b8599081a 100644
--- a/webapp/tests/karma/ts/services/form.service.spec.ts
+++ b/webapp/tests/karma/ts/services/form.service.spec.ts
@@ -35,6 +35,7 @@ import { ExtractLineageService } from '@mm-services/extract-lineage.service';
import { EnketoTranslationService } from '@mm-services/enketo-translation.service';
import * as FileManager from '../../../../src/js/enketo/file-manager.js';
import { TargetAggregatesService } from '@mm-services/target-aggregates.service';
+import { ContactViewModelGeneratorService } from '@mm-services/contact-view-model-generator.service';
describe('Form service', () => {
// return a mock form ready for putting in #dbContent
@@ -92,6 +93,7 @@ describe('Form service', () => {
let feedbackService;
let extractLineageService;
let targetAggregatesService;
+ let contactViewModelGeneratorService;
beforeEach(() => {
enketoInit = sinon.stub();
@@ -159,6 +161,7 @@ describe('Form service', () => {
feedbackService = { submit: sinon.stub() };
extractLineageService = { extract: ExtractLineageService.prototype.extract };
targetAggregatesService = { getTargetDocs: sinon.stub() };
+ contactViewModelGeneratorService = { loadReports: sinon.stub() };
TestBed.configureTestingModule({
providers: [
@@ -189,6 +192,7 @@ describe('Form service', () => {
{ provide: FeedbackService, useValue: feedbackService },
{ provide: ExtractLineageService, useValue: extractLineageService },
{ provide: TargetAggregatesService, useValue: targetAggregatesService },
+ { provide: ContactViewModelGeneratorService, useValue: contactViewModelGeneratorService },
],
});
@@ -371,7 +375,7 @@ describe('Form service', () => {
}
};
ContactSummary.resolves({ context: { pregnant: true } });
- Search.resolves([{ _id: 'somereport' }]);
+ contactViewModelGeneratorService.loadReports.resolves([{ _id: 'somereport' }]);
targetAggregatesService.getTargetDocs.resolves([{ _id: 't1' }, { _id: 't2' }]);
LineageModelGenerator.contact.resolves({ lineage: [{ _id: 'someparent' }] });
const formContext = new EnketoFormContext('div', 'report', mockEnketoDoc('myform'), instanceData);
@@ -383,9 +387,10 @@ describe('Form service', () => {
expect(summary.id).to.equal('contact-summary');
const xmlStr = new XMLSerializer().serializeToString(summary.xml);
expect(xmlStr).to.equal('true');
- expect(Search.callCount).to.equal(1);
- expect(Search.args[0][0]).to.equal('reports');
- expect(Search.args[0][1].subjectIds).to.deep.equal(['fffff', '44509']);
+ expect(contactViewModelGeneratorService.loadReports.callCount).to.equal(1);
+ expect(contactViewModelGeneratorService.loadReports.args[0]).to.deep.equal(
+ [ { doc: instanceData.contact }, [] ]
+ );
expect(LineageModelGenerator.contact.callCount).to.equal(1);
expect(LineageModelGenerator.contact.args[0][0]).to.equal('fffff');
expect(targetAggregatesService.getTargetDocs.callCount).to.equal(1);