Skip to content

Commit

Permalink
Merge pull request #1537 from rodekruis/test.api-tests
Browse files Browse the repository at this point in the history
test: add api test for flash flood, dengue, and malaria
  • Loading branch information
gulfaraz authored Aug 15, 2024
2 parents 29d4317 + 53a7dd3 commit dedca82
Show file tree
Hide file tree
Showing 7 changed files with 335 additions and 0 deletions.
29 changes: 29 additions & 0 deletions services/API-service/test/email/dengue/email-phl-dengue.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { EpidemicsScenario } from '../../../src/scripts/enum/mock-scenario.enum';
import { getAccessToken, resetDB } from '../../helpers/utility.helper';
import { testDengueScenario } from './test-dengue-scenario.helper';

const countryCodeISO3 = 'PHL';
describe('Should send an email for phl dengue', () => {
let accessToken: string;

beforeEach(async () => {
accessToken = await getAccessToken();
await resetDB(accessToken);
});

it('default', async () => {

Check warning on line 14 in services/API-service/test/email/dengue/email-phl-dengue.test.ts

View workflow job for this annotation

GitHub Actions / ibf-api-service (20.x)

Test has no assertions
await testDengueScenario(
EpidemicsScenario.Default,
countryCodeISO3,
accessToken,
);
});

it('no-trigger', async () => {

Check warning on line 22 in services/API-service/test/email/dengue/email-phl-dengue.test.ts

View workflow job for this annotation

GitHub Actions / ibf-api-service (20.x)

Test has no assertions
await testDengueScenario(
EpidemicsScenario.NoTrigger,
countryCodeISO3,
accessToken,
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { JSDOM } from 'jsdom';

import { DisasterType } from '../../../src/api/disaster/disaster-type.enum';
import { EpidemicsScenario } from '../../../src/scripts/enum/mock-scenario.enum';
import {
getEventTitle,
mockEpidemics,
sendNotification,
} from '../../helpers/utility.helper';

export async function testDengueScenario(
scenario: EpidemicsScenario,
countryCodeISO3: string,
accessToken: string,
): Promise<void> {
const eventNames = ['0-month', '1-month', '2-month'];
const disasterTypeLabel = DisasterType.Dengue;

const mockResult = await mockEpidemics(
scenario,
countryCodeISO3,
accessToken,
);
// Act
const response = await sendNotification(
countryCodeISO3,
DisasterType.Dengue,
accessToken,
);
// Assert
// Also checking the status of the mockResult here as I think it also breaks often
expect(mockResult.status).toBe(202);
expect(response.status).toBe(201);

if (scenario === EpidemicsScenario.Default) {
expect(response.body.activeEvents.email).toBeDefined();
} else {
expect(response.body.activeEvents.email).toBeUndefined();
}

expect(response.body.activeEvents.whatsapp).toBeFalsy();
expect(response.body.finishedEvents).toBeFalsy();

// Parse the HTML content
const dom = new JSDOM(response.body.activeEvents.email);
const document = dom.window.document;

// Get all span elements with apiTest="eventName" and their lower case text content
const eventNamesInEmail = Array.from(
document.querySelectorAll('span[apiTest="eventName"]'),
(el) => (el as Element).textContent.toLowerCase(),
).map((el) => el.trim());

if (scenario === EpidemicsScenario.Default) {
expect(eventNamesInEmail.length).toBe(eventNames.length);
} else {
expect(eventNamesInEmail.length).toBe(0);
}

if (scenario === EpidemicsScenario.Default) {
// Check if each expected event name is included in at least one title
for (const eventName of eventNames) {
const eventTitle = getEventTitle(disasterTypeLabel, eventName);
const hasEvent = eventNamesInEmail.some((eventNameInEmail) =>
eventNameInEmail.includes(eventTitle),
);
expect(hasEvent).toBe(true);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { FlashFloodsScenario } from '../../../src/scripts/enum/mock-scenario.enum';
import { getAccessToken, resetDB } from '../../helpers/utility.helper';
import { testFlashFloodScenario } from './test-flash-flood-scenario.helper';

const countryCodeISO3 = 'MWI';
describe('Should send an email for mwi flash flood', () => {
let accessToken: string;

beforeEach(async () => {
accessToken = await getAccessToken();
await resetDB(accessToken);
});

it('default', async () => {

Check warning on line 14 in services/API-service/test/email/flash-flood/email-mwi-flash-flood.test.ts

View workflow job for this annotation

GitHub Actions / ibf-api-service (20.x)

Test has no assertions
await testFlashFloodScenario(
FlashFloodsScenario.Default,
countryCodeISO3,
accessToken,
);
});

it('no-trigger', async () => {

Check warning on line 22 in services/API-service/test/email/flash-flood/email-mwi-flash-flood.test.ts

View workflow job for this annotation

GitHub Actions / ibf-api-service (20.x)

Test has no assertions
await testFlashFloodScenario(
FlashFloodsScenario.NoTrigger,
countryCodeISO3,
accessToken,
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { JSDOM } from 'jsdom';

import { DisasterType } from '../../../src/api/disaster/disaster-type.enum';
import { FlashFloodsScenario } from '../../../src/scripts/enum/mock-scenario.enum';
import {
getEventTitle,
mockFlashFlood,
sendNotification,
} from '../../helpers/utility.helper';

export async function testFlashFloodScenario(
scenario: FlashFloodsScenario,
countryCodeISO3: string,
accessToken: string,
): Promise<void> {
const eventNames = ['Rumphi', 'Rumphi', 'Karonga'];
const disasterTypeLabel = 'Flash Flood'; // DisasterType.FlashFloods does not match

const mockResult = await mockFlashFlood(
scenario,
countryCodeISO3,
accessToken,
);
// Act
const response = await sendNotification(
countryCodeISO3,
DisasterType.FlashFloods,
accessToken,
);
// Assert
// Also checking the status of the mockResult here as I think it also breaks often
expect(mockResult.status).toBe(202);
expect(response.status).toBe(201);

if (scenario === FlashFloodsScenario.Default) {
expect(response.body.activeEvents.email).toBeDefined();
} else {
expect(response.body.activeEvents.email).toBeUndefined();
}

expect(response.body.activeEvents.whatsapp).toBeFalsy();
expect(response.body.finishedEvents).toBeFalsy();

// Parse the HTML content
const dom = new JSDOM(response.body.activeEvents.email);
const document = dom.window.document;

// Get all span elements with apiTest="eventName" and their lower case text content
const eventNamesInEmail = Array.from(
document.querySelectorAll('span[apiTest="eventName"]'),
(el) => (el as Element).textContent.toLowerCase(),
).map((el) => el.trim());

if (scenario === FlashFloodsScenario.Default) {
expect(eventNamesInEmail.length).toBe(eventNames.length);
} else {
expect(eventNamesInEmail.length).toBe(0);
}

if (scenario === FlashFloodsScenario.Default) {
// Check if each expected event name is included in at least one title
for (const eventName of eventNames) {
const eventTitle = getEventTitle(disasterTypeLabel, eventName);
const hasEvent = eventNamesInEmail.some((eventNameInEmail) =>
eventNameInEmail.includes(eventTitle),
);
expect(hasEvent).toBe(true);
}
}
}
29 changes: 29 additions & 0 deletions services/API-service/test/email/malaria/email-eth-malaria.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { EpidemicsScenario } from '../../../src/scripts/enum/mock-scenario.enum';
import { getAccessToken, resetDB } from '../../helpers/utility.helper';
import { testMalariaScenario } from './test-malaria-scenario.helper';

const countryCodeISO3 = 'ETH';
describe('Should send an email for eth malaria', () => {
let accessToken: string;

beforeEach(async () => {
accessToken = await getAccessToken();
await resetDB(accessToken);
});

it('default', async () => {
await testMalariaScenario(
EpidemicsScenario.Default,
countryCodeISO3,
accessToken,
);
});

it('no-trigger', async () => {
await testMalariaScenario(
EpidemicsScenario.NoTrigger,
countryCodeISO3,
accessToken,
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { JSDOM } from 'jsdom';

import { DisasterType } from '../../../src/api/disaster/disaster-type.enum';
import { EpidemicsScenario } from '../../../src/scripts/enum/mock-scenario.enum';
import {
getEventTitle,
mockEpidemics,
sendNotification,
} from '../../helpers/utility.helper';

export async function testMalariaScenario(
scenario: EpidemicsScenario,
countryCodeISO3: string,
accessToken: string,
): Promise<void> {
const eventNames = ['0-month', '1-month', '2-month'];
const disasterTypeLabel = DisasterType.Malaria;

const mockResult = await mockEpidemics(
scenario,
countryCodeISO3,
accessToken,
);
// Act
const response = await sendNotification(
countryCodeISO3,
DisasterType.Malaria,
accessToken,
);
// Assert
// Also checking the status of the mockResult here as I think it also breaks often
expect(mockResult.status).toBe(202);
expect(response.status).toBe(201);

if (scenario === EpidemicsScenario.Default) {
expect(response.body.activeEvents.email).toBeDefined();
} else {
expect(response.body.activeEvents.email).toBeUndefined();
}

expect(response.body.activeEvents.whatsapp).toBeFalsy();
expect(response.body.finishedEvents).toBeFalsy();

// Parse the HTML content
const dom = new JSDOM(response.body.activeEvents.email);
const document = dom.window.document;

// Get all span elements with apiTest="eventName" and their lower case text content
const eventNamesInEmail = Array.from(
document.querySelectorAll('span[apiTest="eventName"]'),
(el) => (el as Element).textContent.toLowerCase(),
).map((el) => el.trim());

if (scenario === EpidemicsScenario.Default) {
expect(eventNamesInEmail.length).toBe(eventNames.length);
} else {
expect(eventNamesInEmail.length).toBe(0);
}

if (scenario === EpidemicsScenario.Default) {
// Check if each expected event name is included in at least one title
for (const eventName of eventNames) {
const eventTitle = getEventTitle(disasterTypeLabel, eventName);
const hasEvent = eventNamesInEmail.some((eventNameInEmail) =>
eventNameInEmail.includes(eventTitle),
);
expect(hasEvent).toBe(true);
}
}
}
38 changes: 38 additions & 0 deletions services/API-service/test/helpers/utility.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import TestAgent from 'supertest/lib/agent';

import { DisasterType } from '../../src/api/disaster/disaster-type.enum';
import {
EpidemicsScenario,
FlashFloodsScenario,
FloodsScenario,
TyphoonScenario,
} from '../../src/scripts/enum/mock-scenario.enum';
Expand Down Expand Up @@ -65,6 +67,42 @@ export function mockFloods(
});
}

export function mockEpidemics(
scenario: EpidemicsScenario,
countryCodeISO3: string,
accessToken: string,
): Promise<request.Response> {
return getServer()
.post('/mock/epidemics')
.set('Authorization', `Bearer ${accessToken}`)
.query({ isApiTest: true })
.send({
scenario,
secret: process.env.RESET_SECRET,
removeEvents: true,
date: new Date(),
countryCodeISO3,
});
}

export function mockFlashFlood(
scenario: FlashFloodsScenario,
countryCodeISO3: string,
accessToken: string,
): Promise<request.Response> {
return getServer()
.post('/mock/flash-floods')
.set('Authorization', `Bearer ${accessToken}`)
.query({ isApiTest: true })
.send({
scenario,
secret: process.env.RESET_SECRET,
removeEvents: true,
date: new Date(),
countryCodeISO3,
});
}

export function mockTyphoon(
scenario: TyphoonScenario,
countryCodeISO3: string,
Expand Down

0 comments on commit dedca82

Please sign in to comment.