project: (init) ussd-e2e
This commit is contained in:
commit
aff3177395
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
node_modules
|
4
.taprc
Normal file
4
.taprc
Normal file
@ -0,0 +1,4 @@
|
||||
reporter: spec
|
||||
comments: false
|
||||
coverage: false
|
||||
check-coverage: false
|
48
README.md
Normal file
48
README.md
Normal file
@ -0,0 +1,48 @@
|
||||
## cic-ussd-e2e
|
||||
|
||||
> Mocking user interaction with cic-ussd
|
||||
|
||||
### Setup
|
||||
|
||||
**Pre-requisites**
|
||||
|
||||
2 accounts each with:
|
||||
|
||||
- Initial pin set
|
||||
- Some SRF Balance
|
||||
|
||||
**Environment**
|
||||
|
||||
- Node.js
|
||||
- Install dependencies with `$ npm i`
|
||||
|
||||
### Running tests
|
||||
|
||||
```bash
|
||||
$ npm run test
|
||||
```
|
||||
|
||||
### Scenarios
|
||||
|
||||
| Test | Description |
|
||||
| ---------------- | ---------------------------- |
|
||||
| 1_initial_menu | Main menu > Help > Exit |
|
||||
| 2_display_sarafu | Main menu > My Sarafu > Exit |
|
||||
|
||||
#### Writing your own scenario
|
||||
|
||||
- Each scenario should exit since this test suite doesn't pass around past session info
|
||||
- Control wait between menus with the `wait(time in ms)` function
|
||||
- Follow any spec
|
||||
- For any traversing through menus, remember to append a `*` and the next input, this is to correctly mock AT webhooks e.g.
|
||||
|
||||
```bash
|
||||
# Initial Main menu, no input
|
||||
""
|
||||
# Input 1
|
||||
"1"
|
||||
# Input 2
|
||||
"1*2"
|
||||
# Input 99
|
||||
"1*2*99"
|
||||
```
|
41
lib.js
Normal file
41
lib.js
Normal file
@ -0,0 +1,41 @@
|
||||
const crypto = require("crypto");
|
||||
const phin = require("phin");
|
||||
|
||||
async function ussdClient(sessionId, input = "") {
|
||||
const requestOptions = {
|
||||
url: "https://ussd.grassecon.net",
|
||||
method: "POST",
|
||||
parse: "string",
|
||||
timeout: 3000,
|
||||
form: {
|
||||
sessionId: sessionId,
|
||||
// Get from a config file, then pass as a param
|
||||
phoneNumber: "254711777734",
|
||||
serviceCode: "*483*061#",
|
||||
text: input,
|
||||
},
|
||||
};
|
||||
|
||||
try {
|
||||
const { body } = await phin(requestOptions);
|
||||
|
||||
if (body.length > 1) {
|
||||
return {
|
||||
code: body.slice(0, 3),
|
||||
text: body.slice(4),
|
||||
};
|
||||
}
|
||||
|
||||
throw new Error("EMPTY_BODY");
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
function newSession() {
|
||||
return crypto.randomBytes(16).toString("hex");
|
||||
}
|
||||
|
||||
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
module.exports = { ussdClient, newSession, wait };
|
17
package.json
Normal file
17
package.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "ussd-e2e",
|
||||
"version": "1.0.0",
|
||||
"description": "e2e tests for cic-ussd",
|
||||
"author": "Mohamed Sohail Azim <sohailazim@pm.me>",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"test": "tap"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tap": "^16.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"phin": "^3.6.1",
|
||||
"rangi": "^1.0.2"
|
||||
}
|
||||
}
|
40
tests/1_initial_menu.test.js
Normal file
40
tests/1_initial_menu.test.js
Normal file
@ -0,0 +1,40 @@
|
||||
const test = require("tap").test;
|
||||
const rangi = require("rangi");
|
||||
|
||||
const lib = require("../lib");
|
||||
|
||||
test("Initial menu, go to help, exit", async (t) => {
|
||||
const sessionId = lib.newSession();
|
||||
|
||||
t.plan(3);
|
||||
|
||||
t.test("Display menu and Sarafu balance", async (t) => {
|
||||
await lib.wait(3000);
|
||||
const r = await lib.ussdClient(sessionId);
|
||||
console.log(rangi.cyan(r.text));
|
||||
|
||||
t.equal(r.code, "CON");
|
||||
t.match(r.text, /Balance/g);
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test("Go to help menu", async (t) => {
|
||||
await lib.wait(3000);
|
||||
const r = await lib.ussdClient(sessionId, "4");
|
||||
console.log(rangi.cyan(r.text));
|
||||
|
||||
t.equal(r.code, "CON");
|
||||
t.match(r.text, /assistance/g);
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test("Exit", async (t) => {
|
||||
await lib.wait(3000);
|
||||
const r = await lib.ussdClient(sessionId, "4*99");
|
||||
console.log(rangi.cyan(r.text));
|
||||
|
||||
t.equal(r.code, "END");
|
||||
t.match(r.text, /Thank/g);
|
||||
t.end();
|
||||
});
|
||||
});
|
40
tests/2_display_sarafu.test.js
Normal file
40
tests/2_display_sarafu.test.js
Normal file
@ -0,0 +1,40 @@
|
||||
const test = require("tap").test;
|
||||
const rangi = require("rangi");
|
||||
|
||||
const lib = require("../lib");
|
||||
|
||||
test("Initial menu, display balances, exit", async (t) => {
|
||||
const sessionId = lib.newSession();
|
||||
|
||||
t.plan(3);
|
||||
|
||||
t.test("Display menu and Sarafu balance", async (t) => {
|
||||
await lib.wait(3000);
|
||||
const r = await lib.ussdClient(sessionId);
|
||||
console.log(rangi.cyan(r.text));
|
||||
|
||||
t.equal(r.code, "CON");
|
||||
t.match(r.text, /Balance/g);
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test("Go to My Sarafu menu", async (t) => {
|
||||
await lib.wait(3000);
|
||||
const r = await lib.ussdClient(sessionId, "2");
|
||||
console.log(rangi.cyan(r.text));
|
||||
|
||||
t.equal(r.code, "CON");
|
||||
t.match(r.text, /SRF/g);
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test("Exit", async (t) => {
|
||||
await lib.wait(3000);
|
||||
const r = await lib.ussdClient(sessionId, "2*00");
|
||||
console.log(rangi.cyan(r.text));
|
||||
|
||||
t.equal(r.code, "END");
|
||||
t.match(r.text, /Thank/g);
|
||||
t.end();
|
||||
});
|
||||
});
|
0
tests/tap-parallel-not-ok
Normal file
0
tests/tap-parallel-not-ok
Normal file
Reference in New Issue
Block a user