Skip to content
This repository has been archived by the owner on Oct 21, 2022. It is now read-only.

Commit

Permalink
Merge pull request #50 from OpenFn/49-integration-tests-guide
Browse files Browse the repository at this point in the history
Make integration tests work and explain their constrains in readme
  • Loading branch information
taylordowns2000 committed Dec 23, 2021
2 parents 4be696f + 4a21fd1 commit 56f7b54
Show file tree
Hide file tree
Showing 16 changed files with 3,995 additions and 10,263 deletions.
3 changes: 2 additions & 1 deletion .prettierrc
Expand Up @@ -3,5 +3,6 @@
"tabWidth": 2,
"singleQuote": true,
"arrowParens": "avoid",
"printWidth": 80
"printWidth": 80,
"proseWrap": "always"
}
218 changes: 54 additions & 164 deletions README.md
Expand Up @@ -6,8 +6,8 @@ Language Pack for building expressions and operations for working with the
## Documentation

View the [docs site](https://openfn.github.io/language-dhis2/) for full
technical documentation. Below, find a samples of the most commonly used helper
functions.
technical documentation and **lots of examples** for how to use the various
helper functions.

## Sample State

Expand All @@ -16,165 +16,21 @@ functions.
"configuration": {
"username": "admin",
"password": "district",
"hostUrl": "https://play.dhis2.org/2.35.1"
"hostUrl": "https://play.dhis2.org/2.36.6"
},
"data": {
"a": 1,
"b": 2
}
"data": { "a": 1, "b": 2 }
}
```

## Analytics API

#### Fetch analytics data for PMTCT data over last 6 months.

```js
fetchAnalytics({
query: {
dimension: ['dx:CYI5LEmm3cG;GDVU1o5rTNF', 'pe:LAST_6_MONTHS'],
filter: 'ou:GHlyx9Pg9mn',
displayProperty: 'NAME',
outputIdScheme: 'UID',
},
});
```

## Tracked Entity API

#### Create a new tracked entity instance and enroll them from a CommCare form submission.

```js
createTEI({
trackedEntityType: 'nEenWmSyUEp',
orgUnit: 'g8upMTyEZGZ',
attributes: [
{
attribute: 'w75KJ2mc4zz',
value: dataValue('form.first_name')(state),
},
{
attribute: 'zDhUuAYrxNC',
value: dataValue('form.last_name')(state),
},
],
enrollments: [
{
orgUnit: 'g8upMTyEZGZ',
program: 'IpHINAT79UW',
enrollmentDate: '2019-04-08',
incidentDate: '2019-04-08',
},
],
});
```

#### Upsert a tracked entity instance from a CommCare form submission.

```js
upsertTEI(
'w75KJ2mc4zz', // match on 'patientID', a custom external ID in dhis2
{
trackedEntityType: 'nEenWmSyUEp',
orgUnit: 'g8upMTyEZGZ',
attributes: [
{
attribute: 'w75KJ2mc4zz',
value: dataValue('form.first_name')(state),
},
{
attribute: 'zDhUuAYrxNC',
value: dataValue('form.last_name')(state),
},
],
}
);
```

## Events API

#### `Events API` expression

```js
event(
fields(
field("program", "eBAyeGv0exc"),
field("orgUnit", "DiszpKrYNg8"),
field("eventDate", dataValue("date")),
field("status", "COMPLETED"),
field("storedBy", "admin"),
field("coordinate", {
"latitude": "59.8",
"longitude": "10.9"
}),
field("dataValues", function(state) {
return [
dataElement("qrur9Dvnyt5", dataValue("prop_a"))(state)
dataElement("oZg33kd9taw", dataValue("prop_b"))(state)
dataElement("msodh3rEMJa", dataValue("prop_c"))(state)
]
})
)
)
```

#### Current `fetchEvents API` expression (Optional `postUrl` for a complete fetch)

```js
fetchEvents({
fields: {
orgUnit: 'DiszpKrYNg8',
program: 'eBAyeGv0exc',
endDate: '2016-01-01',
},
postUrl: 'https://www.openfn.org/inbox/123',
});
```

#### Reference on how to query and read events https://docs.dhis2.org/2.22/en/developer/html/ch01s15.html#d5e1994

## Data Values / Data Value Sets API

#### Current `DataValueSets API` expression

```js
dataValueSet({
dataSet: dataValue('set'),
orgUnit: 'DiszpKrYNg8',
period: '201402',
completeData: '2014-03-03',
dataValues: [
dataElement('f7n9E0hX8qk', dataValue('data[0].site_school_number')),
dataElement('Ix2HsbDMLea', dataValue('age')),
dataElement('eY5ehpbEsB7', 30),
],
});
```

#### Current `fetchData API` expression (Optional `postUrl` for a complete fetch)

```js
fetchData({
fields: {
dataSet: 'pBOMPrpg1QX',
orgUnit: 'DiszpKrYNg8',
period: '201711',
},
postUrl: 'https://www.openfn.org/inbox/123',
});
```

#### Reference on how to read data values https://docs.dhis2.org/2.22/en/developer/html/ch01s13.html#d5e1642

[Docs](docs/index)

## Development

Clone the repo, run `npm install`.
Clone the repo and run `npm install`.

Run tests using `npm run test` or `npm run test:watch`
Run tests using `npm run test` or `npm run test:watch`. (NB: that this repo also
contain integration tests which can be run with `npm run integration-test`.)

NB: There are two types of tests: unit tests and integration tests.
**_Make your changes to the files in `src/` and then use `npm run build` to
generate output files in `lib/`._**

### Unit Tests

Expand All @@ -191,22 +47,56 @@ needs to be added.

### End-to-end integration tests

Integration tests allow us to test the end-to-end behavior of the helper functions
and also to test the examples we provide via inline documentation.
Integration tests allow us to test the end-to-end behavior of the helper
functions and also to test the examples we provide via inline documentation.

For example with integration tests we answer the following question:

> Does `create('events', eventPayload)` actually create a new event in a live
> DHIS2 system?
To run integration tests, execute `npm run integration-test`. These
tests use network I/O and a public connection to a DHIS2 "play" server so their
timing and performance is unpredictable. Consider adding an increased timeout,
and modifying the orgUnit, program, etc., IDs set in `globalState`.

Anytime a new example is added in the documentation of a helper function, a new
integration test should be done.
To run integration tests, execute `npm run integration-test`. These tests use
network I/O and a public connection to a DHIS2 "play" server so their timing and
performance is unpredictable. Consider adding an increased timeout, and
modifying the orgUnit, program, etc., IDs set in `globalState`.

#### Troubleshooting the tests

- Depending on your internet strength please consider changing the **global
timeout** in the `test/mocha.opts` file to avoid faillures related to network
timeouts.

- The behavior of the tests in `test/integration.js` is very unpredictable; they
depend on the **configuration of a target DHIS2 instance**. Currently you need
to have at least one organisation unit with one program, one
trackedEntityInstance and one programStage in it. These components need to be
well configured for the integration tests to work. For example: the
trackedEntityInstance need to be enrolled to the program, which should be
created in that organisation unit and contains at least that programStage. If
the tests fail, you must adjust these attributes in the
[before hook](test/integration.js):

```javascript
before(done => {
fixture.initialState = {
configuration: {
username: 'admin',
password: 'district',
hostUrl: 'https://play.dhis2.org/2.36.6',
},
program: 'IpHINAT79UW',
orgUnit: 'DiszpKrYNg8',
trackedEntityInstance: 'uhubxsfLanV',
programStage: 'eaDHS084uMp',
};
done();
});
```

### Build
- Make sure the `update` and `upsert` integration tests don't affect those
initial organisation units, programs, programStage and trackedEntityInstance
required. Otherwise the create integration tests would be broken again; and
that's an endless faillure loop :(

Build the project using `npm run build`.
Anytime a new example is added in the documentation of a helper function, a new
integration test should be built.

0 comments on commit 56f7b54

Please sign in to comment.