Skip to content

Commit 5f65668

Browse files
authored
chore: add e2e test for fetching forms from Google Drive (#796)
1 parent 4d34f7b commit 5f65668

File tree

3 files changed

+74
-1
lines changed

3 files changed

+74
-1
lines changed

.github/workflows/build.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ jobs:
3535
e2e:
3636
name: E2E tests
3737
runs-on: ubuntu-22.04
38+
env:
39+
GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }}
40+
GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }}
41+
GOOGLE_REDIRECT_URI: "http://localhost"
42+
GOOGLE_TOKEN_SCOPE: 'https://www.googleapis.com/auth/drive.readonly'
3843

3944
steps:
4045
- uses: actions/checkout@v4
@@ -48,5 +53,20 @@ jobs:
4853
- name: Hard code local-ip IP in /etc/hosts per https://github.com/medic/medic-infrastructure/issues/571#issuecomment-2209120441
4954
run: |
5055
echo "15.188.129.97 local-ip.medicmobile.org" | sudo tee -a /etc/hosts
56+
- id: auth
57+
uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093
58+
with:
59+
service_account: ${{ env.GOOGLE_SERVICE_ACCT }}
60+
credentials_json: ${{ secrets.GOOGLE_CREDENTIALS }}
61+
token_format: access_token
62+
access_token_scopes: ${{ env.GOOGLE_TOKEN_SCOPE }}
63+
- name: Write access_token to .gdrive.session.json
64+
run: |
65+
echo '{
66+
"access_token": "${{ steps.auth.outputs.access_token }}",
67+
"scope": "${{ env.GOOGLE_TOKEN_SCOPE }}",
68+
"token_type": "Bearer",
69+
"expiry_date": "9999999999999"
70+
}' > .gdrive.session.json
5171
- name: Run E2E tests
5272
run: npm run test-e2e

test/e2e/.mocharc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module.exports = {
44
...rootConfig,
55
captureFile: 'test/e2e/results.txt',
66
checkLeaks: true,
7-
exclude: [],
7+
exclude: process.env.CI ? [] : ['test/e2e/fetch-forms-from-google-drive.spec.js'], // Do not run Google tests locally by default
88
file: 'test/e2e/hooks.js',
99
spec: 'test/e2e/**/*.spec.js',
1010
timeout: 120_000, // spinning up a CHT instance takes a little long
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
const { expect } = require('chai');
2+
const fs = require('node:fs');
3+
const {
4+
cleanupProject,
5+
initProject,
6+
runChtConf,
7+
getProjectDirectory
8+
} = require('./cht-conf-utils');
9+
const path = require('path');
10+
11+
const FORMS = {
12+
'app/death_report.xlsx': '1azFHCMTMehxuSg_LWOgsJZxrJo0yhseLp9FK4gTT38M',
13+
'contact/person-create.xlsx': '1VhOPphx4IXyZiGbcevVZwvsvap8WPKHmUjOp8NuWJW8'
14+
};
15+
16+
/**
17+
* Running this test locally requires OAuth desktop client credentials for a Google Cloud Project.
18+
* https://docs.communityhealthtoolkit.org/apps/guides/forms/google-drive/
19+
* Once you have created the OAuth client, configure the following environment variables in your current shell:
20+
* `CI=true`, `GOOGLE_REDIRECT_URI=http://localhost`, and `GOOGLE_CLIENT_ID=<client_id from OAuth client>`,
21+
* `GOOGLE_CLIENT_SECRET=<>`. Next, generate a `.gdrive.session.json` file with a valid access token by manually
22+
* running `cht fetch-forms-from-google-drive`. Copy the `.gdrive.session.json` file to the root of the cht-conf repo.
23+
* Then you should be able to successfully run `npm test-e2e`.
24+
*
25+
* On CI, this test runs with a configured Service Account by preemptively getting an access token and setting it in
26+
* the `.gdrive.session.json` file. Unfortunately, this means these tests cannot cover the login portion of the
27+
* functionality, but it does to cover the actual fetching and file writing logic.
28+
*/
29+
describe('fetch-forms-from-google-drive', () => {
30+
before(initProject);
31+
after(cleanupProject);
32+
33+
it('downloads configured forms from Google Drive', async () => {
34+
const projectDir = getProjectDirectory();
35+
await fs.promises.writeFile(
36+
path.join(projectDir, 'forms-on-google-drive.json'),
37+
JSON.stringify(FORMS, null, 2),
38+
);
39+
40+
const sessionJsonSrcPath = path.resolve(__dirname, '../../.gdrive.session.json');
41+
const sessionJsonDestPath = path.resolve(projectDir, '.gdrive.session.json');
42+
await fs.promises.copyFile(sessionJsonSrcPath, sessionJsonDestPath);
43+
44+
await runChtConf('fetch-forms-from-google-drive');
45+
46+
const formFilePaths = Object
47+
.keys(FORMS)
48+
.map(formPath => path.join(projectDir, 'forms', formPath));
49+
formFilePaths.forEach(formPath => {
50+
expect(fs.existsSync(formPath)).to.be.true;
51+
});
52+
});
53+
});

0 commit comments

Comments
 (0)