Skip to content

Commit

Permalink
refactored integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ypopovych committed May 31, 2024
1 parent 45e5a20 commit 4bef0a2
Show file tree
Hide file tree
Showing 7 changed files with 580 additions and 567 deletions.
68 changes: 32 additions & 36 deletions tests/address-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,45 @@ const { expect } = require('chai')
const { toHex, getApplication, removeMasterNode } = require('./helpers/common');
const { TEST_DATA } = require('./helpers/data');
const { mergePagedScreens } = require("./helpers/screen");
const { AuthTokenFlows } = require('./helpers/flow');
const { authTokenFlows } = require('./helpers/flow');

describe("Address Tests", function () {
context("Address Commands", function () {
new AuthTokenFlows("can derive address", () => { return { address: TEST_DATA.address0 }; }).do(
function () {
return this.test.device.deriveAddress(this.address.path.toString());
},
function (derivedAddress) {
const deriveAddressFlow = [
{ header: null, body: 'Confirm Send Address' },
{ header: 'Path', body: removeMasterNode(this.address.path.toString()) },
{ header: null, body: 'Approve' },
{ header: null, body: 'Reject' }
];
if (this.auth) {
deriveAddressFlow.splice(2, 0, { header: 'Application', body: getApplication(this.test.device) });
authTokenFlows("can derive address")
.init(async ({test, auth}) => {
const address = TEST_DATA.address0;
const flow = [{ header: null, body: 'Confirm Send Address' },
{ header: 'Path', body: removeMasterNode(address.path.toString()) }];
if (auth) {
flow.push({ header: 'Application', body: getApplication(test.device) })
}
expect(this.flows[0]).to.be.deep.equal(deriveAddressFlow);
expect(derivedAddress).to.be.deep.equal({
addressHex: toHex(this.address.toBytes())
flow.push({ header: null, body: 'Approve' }, { header: null, body: 'Reject' });
return { address, flow, flowsCount: 1 };
})
.shouldSucceed(({flow, flows, address}, derived) => {
expect(flows[0]).to.be.deep.equal(flow);
expect(derived).to.be.deep.equal({
addressHex: toHex(address.toBytes())
});
}
);
})
.run(({test, address}) => test.device.deriveAddress(address.path.toString()));

new AuthTokenFlows("can show address", () => { return { address: TEST_DATA.address0 }; }).do(
function () {
return this.test.device.showAddress(this.address.path.toString());
},
function (show) {
const addressFlow = [
{ header: null, body: 'Confirm Address' },
{ header: 'Path', body: removeMasterNode(this.address.path.toString()) },
{ header: 'Address', body: this.address.toBase58() },
{ header: null, body: 'Approve' },
{ header: null, body: 'Reject' }
];
if (this.auth) {
addressFlow.splice(3, 0, { header: 'Application', body: getApplication(this.test.device) });
authTokenFlows("can show address")
.init(async ({test, auth}) => {
const address = TEST_DATA.address0;
const flow = [{ header: null, body: 'Confirm Address' },
{ header: 'Path', body: removeMasterNode(address.path.toString()) },
{ header: 'Address', body: address.toBase58() }];
if (auth) {
flow.push({ header: 'Application', body: getApplication(test.device) })
}
expect(mergePagedScreens(this.flows[0])).to.be.deep.equal(addressFlow);
flow.push({ header: null, body: 'Approve' }, { header: null, body: 'Reject' });
return { address, flow, flowsCount: 1 };
})
.shouldSucceed(({flow, flows}, show) => {
expect(mergePagedScreens(flows[0])).to.be.deep.equal(flow);
expect(show).to.be.true;
}
);
})
.run(({test, address}) => test.device.showAddress(address.path.toString()));
});
});
3 changes: 2 additions & 1 deletion tests/helpers/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ class ExtendedAddress {
this.network = network;
this.address = address;
this.path = DerivationPath.new(path[0], [path[1]]);
this.index = path[1];
this.acc_index = path[0];
this.addr_index = path[1];
}

toBase58() {
Expand Down
106 changes: 67 additions & 39 deletions tests/helpers/flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,55 +14,83 @@ function restorePromiseError(promise) {
}

class AuthTokenFlows {
constructor(name, before, count = [1, 1]) {
this.name = name;
this.before = before;
this.count = count;
constructor(name) {
this._name = name;
this._before = null;
this.shouldSucceed(null);
this.shouldFail(null);
}

do(action, success, failure) {
const count = this.count;
const before = this.before;
init(before) {
this._before = before;
return this;
}

success = success ?? (function (result) {
shouldSucceed(success) {
this._success = success ?? (function (_, result) {
throw new Error(`Success called: ${JSON.stringify(result)}`);
});
failure = failure ?? (function (error) {
return this;
}

shouldFail(failure) {
this._failure = failure ?? (function (_, error) {
throw new Error(`Failure called: ${error}`);
});
return this;
}

const run = auth => {
it(`${this.name}${auth ? ' (with auth token)' : ''}`, async function () {
this.timeout(30_000);
const params = before();
Object.assign(params, { test: this, auth });
this.device.useAuthToken(auth);
this.screens.removeCurrentScreen(); // Wait for new screen in the readFlow
const promise = suppressPomiseError(action.call(params));
const flows = [];
for (let i = 0; i < count[auth]; i++) {
let flow = await this.screens.readFlow();
flows.push(mergePagedScreens(flow));
await this.screens.clickOn('Approve');
if (i != count[auth] - 1 && await this.screens.isReadyMainScreen()) { // we have more flows
this.screens.removeCurrentScreen(); // Wait for new screen in the readFlow
}
}
Object.assign(params, { flows });
let result;
try {
result = await restorePromiseError(promise);
} catch (error) {
failure.call(params, error);
return;
}
success.call(params, result);
});
}
run(action) {
this.__run(false, action);
this.__run(true, action);
}

__run(auth, action) {
const before = this._before;
const success = this._success;
const failure = this._failure;

run(0);
run(1);
it(`${this._name}${auth ? ' (with auth token)' : ''}`, async function() {
this.timeout(30_000);
this.device.useAuthToken(auth);
const params = { test: this, auth };
if (before) {
Object.assign(params, await before(params));
}
const flowsCount = params.flowsCount;
if (typeof flowsCount !== "number") {
throw new Error("flowsCount should be defined and to be a number");
}
this.screens.removeCurrentScreen(); // Wait for new screen in the readFlow
// Call action
const promise = suppressPomiseError(action(params));
// Read flows
const flows = [];
for (let i = 0; i < flowsCount; i++) {
let flow = await this.screens.readFlow();
flows.push(mergePagedScreens(flow));
await this.screens.clickOn('Approve');
if (i != flowsCount - 1 && await this.screens.isReadyMainScreen()) { // we have more flows
this.screens.removeCurrentScreen(); // Wait for new screen in the readFlow
}
}
params.flows = flows;
// Call success or error
let result;
try {
result = await restorePromiseError(promise);
} catch (error) {
failure(params, error);
return;
}
success(params, result);
});
return null;
}
}

exports.authTokenFlows = function(name) {
return new AuthTokenFlows(name);
};

exports.AuthTokenFlows = AuthTokenFlows;
Loading

0 comments on commit 4bef0a2

Please sign in to comment.