Integrating purge function in task tests

Hi Community,
If we have a task that depends on some report, par example, an assessment report, and the task has events with dueDate par exmaple every month, till 4 months later than assessment.reported_date, but the assessment report is purged in 90 days, the 4th month event will be cancelled once the assessment report is purged

Is there a way to execute the purge function exported in the purge.js file inside cht-harness so the getTask method or something like this, will be aware that the report at the given test date is purged and have the test failing ?

in this ways developpers should adjust purging in order to get the tests passed.

3 Likes

Great question. Currently there isn’t support for any purge testing in cht-conf-test-harness - but there could be!

Combining Harness + Purge Unit Tests

Here is a snippet of code which is how I usually see people combine the harness + purge function testing.

const { fn: purgeFn } = require('../purge');
const purge = (role, reports) => purgeFn({ roles: [role] }, {}, reports);

describe('purging', () => {
  ... standard harness boilerplate ...

  it('example', async () => {
    const { report: covidReport } = await harness.fillForm('covid', ...inputs.scenario);

    // is not purged on day 10
    await harness.flush(10);
    expect(purge('user_role', [covidReport])).to.be.empty;

    // is purged on day 11
    await harness.flush(1);
    expect(purge('user_role', [covidReport])).to.deep.eq([covidReport._id]);
});

Supporting Purging in the Harness

There has been talk about supporting purging as a first-class citizen of the harness.

In general, the harness aims to provide a convenient pattern for testing application code - but the pattern it uses has limitations. The pattern just isn’t a good fit to test everything - like sentinel transitions, etc. At some point, automation should start CHT services and click around.

That said – my opinion is that the harness should provide convenient patterns for anything written in JavaScript. JavaScript config is where the complexity lies and automation has the highest value.

I can’t build this feature right now. If you’re interested, I can work with you to build it.

A potential solution for Muso

Most of the complexity of adding this in the harness is that the purging function is run once for each contact. Reports need to be grouped by contact and run through the purge function together with a userContext, etc. etc…

I don’t believe you rely on much of that at Muso. Something easier might work for you…

So, let’s say we had a function that knows what reports will ideally remain after purging… This is a concept – I didn’t even run this code:

const removePurgedReports = reports => {
  const purgedReportIds = new Set(purge(harness.userRoles, reports));
  return reports.filter(r => !purgedReportIds.has(r._id));
};

You could then use it to remove all purged docs from the harness’s state like this:

harness.state.reports = removePurgedReports(harness.state.reports);

// reports which are purged will not be available to other calculations made by the harness
await harness.getContactSummary();
await harness.getTasks(); 
await harness.getTargets(); 
etc.
4 Likes

Hi @kenn and @diana thanks a lot for supporting us
I’ve tested the proposed solution and for our needs it works fine
For example, We’ve a malnutrition workflow of 84 days that is triggered when the PATIENT_ASSESSMENT_UNDER_5 report has the field has_MAM==='true', with these events

const MAMEvents = [7, 14, 21, 28, 42, 56, 70, 84];

so with today to 84 days before to the current date

const current_date = new Date();
const _84DaysAgo = new Date(current_date.getTime() - 84 * 24 * 60 * 60 * 1000);
const today = _84DaysAgo.toISOString().slice(0,10);

to test that all 8 follow up tasks will be displayed, I’ve done this:

 MAMEvents.forEach((days,index) =>
    it(`MAM should display follow up ${index+1}`, async () => {
      const result = await harness.fillForm(Forms.PATIENT_ASSESSMENT_UNDER_5, ...malnutritionScenarioMAM.assessmentScenario);
      expect(result.errors).to.be.empty;
      await harness.flush(days);
      harness.state.reports = removePurgedReports(harness.state.reports);
      const tasks = await harness.getTasks();
      expect(tasks).to.have.property('length', 1);
      expect(tasks[0].emission).to.nested.include({
        'actions[0].content.t_follow_up_count':  `${index + 1}`,
        'actions[0].label': 'Follow up'
      });
    })
  );

if a developer modifies the purge and the PATIENT_ASSESMENTS_UNDER_5 reports with an age in days, for example, of 40 days, get purged, the fifth follow up, this is the 42 days followup, will fail since harness.state.reports.length would be 0 and the developer wont be able to merge his code.

2 Likes