Skip to content

Commit

Permalink
Merge branch 'feature/improvingTest' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
ronaldsg20 committed Mar 23, 2021
2 parents c4da5b4 + e1173ca commit 559317e
Show file tree
Hide file tree
Showing 24 changed files with 692 additions and 178 deletions.
288 changes: 155 additions & 133 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"@loopback/rest": "^9.1.1",
"@loopback/rest-explorer": "^3.0.5",
"@loopback/service-proxy": "^3.0.5",
"dotenv": "^8.2.0",
"loopback-connector-kv-redis": "^3.0.3",
"loopback-connector-mongodb": "^5.5.0",
"loopback-connector-redis": "^3.0.0",
Expand Down
8 changes: 3 additions & 5 deletions src/__tests__/acceptance/balance.controller.acceptance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,8 @@ describe('Balance Controller', () => {
],
})
.expect(200);
expect(res.body).to.containEql({
segwit: 0,
nativeSegwit: 49997000,
legacy: 3289478,
});
expect(typeof res.body.segwit).to.eql('number');
expect(typeof res.body.nativeSegwit).to.eql('number');
expect(typeof res.body.legacy).to.eql('number');
});
});
25 changes: 25 additions & 0 deletions src/__tests__/acceptance/broadcast.controller.acceptance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {Client} from '@loopback/testlab';
import {TwpapiApplication} from '../..';
import {setupApplication} from './test-helper';

describe('Broadcast Controller', () => {
let app: TwpapiApplication;
let client: Client;

before('setupApplication', async () => {
({app, client} = await setupApplication());
});

after(async () => {
await app.stop();
});

it('invokes POST /broadcast with value on hex', async () => {
await client
.post('/broadcast')
.send({
data: 'value on hex',
})
.expect(400);
});
});
67 changes: 67 additions & 0 deletions src/__tests__/acceptance/pegin-tx.acceptance.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,71 @@ describe('Pegin Tx Controller', () => {
};
await client.post('/pegin-tx').send(peginTxData).expect(200);
});
it('invokes POST /pegin-tx with bech32 address', async () => {
const peginConf = await client.get('/pegin-configuration').expect(200);
const balance = await client
.post('/balance')
.send({
sessionId: peginConf.body.sessionId,
addressList: [
{
path: [2147483692, 2147483649, 2147483648, 0, 0],
serializedPath: "m/44'/1'/0'/0/0",
address: 'mzMCEHDUAZaKL9BXt9SzasFPUUqM77TqP1',
},
{
path: [2147483692, 2147483649, 2147483648, 1, 0],
serializedPath: "m/44'/1'/0'/1/0",
address: 'mqCjBpQ75Y5sSGzFtJtSQQZqhJze9eaKjV',
},
{
path: [2147483697, 2147483649, 2147483648, 0, 0],
serializedPath: "m/49'/1'/0'/0/0",
address: '2NC4DCae9HdL6vjWMDbQwTkYEAB22MF3TPs',
},
{
path: [2147483697, 2147483649, 2147483648, 1, 0],
serializedPath: "m/49'/1'/0'/1/0",
address: '2NCZ2CNYiz4rrHq3miUHerUMcLyeWU4gw9C',
},
{
path: [2147483732, 2147483649, 2147483648, 0, 0],
serializedPath: "m/84'/1'/0'/0/0",
address: 'tb1qtanvhhl8ve32tcdxkrsamyy6vq5p62ctdv89l0',
},
{
path: [2147483732, 2147483649, 2147483648, 1, 0],
serializedPath: "m/84'/1'/0'/1/0",
address: 'tb1qfuk3j0l4qn4uzstc47uwk68kedmjwuucl7avqr',
},
],
})
.expect(200);
await client
.post('/tx-fee')
.send({
sessionId: peginConf.body.sessionId,
amount: 200,
accountType: constants.BITCOIN_LEGACY_ADDRESS,
})
.expect(200);
const peginTxData = {
sessionId: peginConf.body.sessionId,
amountToTransferInSatoshi: balance.body.legacy,
refundAddress: 'tb1qkfcu7q7q6y7xmfe5glp9amsm45x0um59rwwmsmsmd355g32',
recipient: '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1',
feeLevel: constants.BITCOIN_FAST_FEE_LEVEL,
changeAddress: '2NC4DCae9HdL6vjWMDbQwTkYEAB22MF3TPs',
};
await client
.post('/pegin-tx')
.send(peginTxData)
.expect({
error: {
statusCode: 500,
message: 'Internal Server Error',
},
});
// console.log(res.body);
});
});
118 changes: 117 additions & 1 deletion src/__tests__/helper.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {PeginConfiguration} from '../models';
import {PeginConfiguration, TxInput, Utxo, WalletAddress} from '../models';

export function givenPeginConfiguration(
peginConfiguration?: Partial<PeginConfiguration>,
Expand All @@ -11,3 +11,119 @@ export function givenPeginConfiguration(
);
return new PeginConfiguration(data);
}

export function getLegacyAddressList(): WalletAddress[] {
const addressList = [
{
path: [2147483692, 2147483649, 2147483648, 0, 0],
serializedPath: "m/44'/1'/0'/0/0",
address: 'mzMCEHDUAZaKL9BXt9SzasFPUUqM77TqP1',
},
{
path: [2147483692, 2147483649, 2147483648, 1, 0],
serializedPath: "m/44'/1'/0'/1/0",
address: 'mqCjBpQ75Y5sSGzFtJtSQQZqhJze9eaKjV',
},
];
return addressList as WalletAddress[];
}
export function getSewitAddressList(): WalletAddress[] {
const addressList = [
{
path: [2147483697, 2147483649, 2147483648, 0, 0],
serializedPath: "m/49'/1'/0'/0/0",
address: '2NC4DCae9HdL6vjWMDbQwTkYEAB22MF3TPs',
},
{
path: [2147483697, 2147483649, 2147483648, 1, 0],
serializedPath: "m/49'/1'/0'/1/0",
address: '2NCZ2CNYiz4rrHq3miUHerUMcLyeWU4gw9C',
},
];
return addressList as WalletAddress[];
}

export function getNativeSegwitAddressList(): WalletAddress[] {
const addressList = [
{
path: [2147483732, 2147483649, 2147483648, 0, 0],
serializedPath: "m/84'/1'/0'/0/0",
address: 'tb1qtanvhhl8ve32tcdxkrsamyy6vq5p62ctdv89l0',
},
{
path: [2147483732, 2147483649, 2147483648, 1, 0],
serializedPath: "m/84'/1'/0'/1/0",
address: 'tb1qfuk3j0l4qn4uzstc47uwk68kedmjwuucl7avqr',
},
];
return addressList as WalletAddress[];
}

export function getUtxoList(): Utxo[] {
const utxoList = [
{
address: 'tb1qfuk3j0l4qn4uzstc47uwk68kedmjwuucl7avqr',
txid: 'tx_id',
vout: 2,
amount: '0.00002',
satoshis: 2000,
height: 2,
confirmations: 2,
},
{
address: 'tb1qfuk3j0l4qn4uzstc47uwk68kedmjwuucl7avqr',
txid: 'tx_id2',
vout: 2,
amount: '0.00002',
satoshis: 2000,
height: 2,
confirmations: 2,
},
{
address: 'tb1qfuk3j0l4qn4uzstc47uwk68kedmjwuucl7avqr',
txid: 'tx_id3',
vout: 2,
amount: '0.00002',
satoshis: 2000,
height: 2,
confirmations: 2,
},
];
return utxoList as Utxo[];
}

export function getMockInputs(): TxInput[] {
const txInputs = [
{
// eslint-disable-next-line @typescript-eslint/naming-convention
address_n: [0],
address: 'tb1qfuk3j0l4qn4uzstc47uwk68kedmjwuucl7avqr',
// eslint-disable-next-line @typescript-eslint/naming-convention
prev_hash: 'tx_id',
// eslint-disable-next-line @typescript-eslint/naming-convention
prev_index: 2,
amount: '0.00002',
},
{
// eslint-disable-next-line @typescript-eslint/naming-convention
address_n: [0],
address: 'tb1qfuk3j0l4qn4uzstc47uwk68kedmjwuucl7avqr',
// eslint-disable-next-line @typescript-eslint/naming-convention
prev_hash: 'tx_id2',
// eslint-disable-next-line @typescript-eslint/naming-convention
prev_index: 2,
amount: '0.00002',
},
{
// eslint-disable-next-line @typescript-eslint/naming-convention
address_n: [0],
address: 'tb1qfuk3j0l4qn4uzstc47uwk68kedmjwuucl7avqr',
// eslint-disable-next-line @typescript-eslint/naming-convention
prev_hash: 'tx_id3',
// eslint-disable-next-line @typescript-eslint/naming-convention
prev_index: 2,
amount: '0.00002',
},
];
return txInputs as TxInput[];
}
28 changes: 28 additions & 0 deletions src/__tests__/unit/account-balance.model.unit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {expect} from '@loopback/testlab';
import {AccountBalance} from '../../models';
import {
getLegacyAddressList,
getNativeSegwitAddressList,
getSewitAddressList,
} from '../helper';
import * as constants from '../../constants';

describe('Account Balance Model ', () => {
it('Validate the account type given an address', () => {
getLegacyAddressList().forEach(walletAddress => {
expect(AccountBalance.getAccountType(walletAddress.address)).to.eql(
constants.BITCOIN_LEGACY_ADDRESS,
);
});
getNativeSegwitAddressList().forEach(walletAddress => {
expect(AccountBalance.getAccountType(walletAddress.address)).to.eql(
constants.BITCOIN_NATIVE_SEGWIT_ADDRESS,
);
});
getSewitAddressList().forEach(walletAddress => {
expect(AccountBalance.getAccountType(walletAddress.address)).to.eql(
constants.BITCOIN_SEGWIT_ADDRESS,
);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from '../../repositories';
import {PeginConfiguration} from '../../models';
import {PeginConfigurationController} from '../../controllers';
describe('PeginConfiguration controller', () => {
describe('PeginConfiguration Repository', () => {
let controller: PeginConfigurationController;
let peginConfigurationRepository: StubbedInstanceWithSinonAccessor<PeginConfigurationRepository>;
let sessionRepository: StubbedInstanceWithSinonAccessor<SessionRepository>;
Expand Down
61 changes: 61 additions & 0 deletions src/__tests__/unit/session.repository.unit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import {
createStubInstance,
expect,
StubbedInstanceWithSinonAccessor,
} from '@loopback/testlab';
import {SessionRepository} from '../../repositories';
import {TxFeeController} from '../../controllers';
import {FeeLevel} from '../../services';
import {sinon} from '@loopback/testlab/dist/sinon';
import {getMockInputs, getUtxoList} from '../helper';
import {FeeRequestData} from '../../models';
import * as constants from '../../constants';
import {config} from 'dotenv';

config();

describe('Session Repository', () => {
let controller: TxFeeController;
let feeLevelService: FeeLevel;
let feeProvider: sinon.SinonStub;
let findAccountUtxos: sinon.SinonStub;
let getAccountInputs: sinon.SinonStub;
let sessionRepository: StubbedInstanceWithSinonAccessor<SessionRepository>;
beforeEach(resetRepositories);

function resetRepositories() {
feeLevelService = {feeProvider: sinon.stub()};
feeProvider = feeLevelService.feeProvider as sinon.SinonStub;
sessionRepository = createStubInstance(SessionRepository);
findAccountUtxos = sessionRepository.findAccountUtxos as sinon.SinonStub;
getAccountInputs = sessionRepository.getAccountInputs as sinon.SinonStub;
controller = new TxFeeController(sessionRepository, feeLevelService);
}

it('should return the tx fee given provided utxos', async () => {
const fast: number = process.env.FAST_MINING_BLOCK
? +process.env.FAST_MINING_BLOCK
: 1;
const average: number = process.env.AVERAGE_MINING_BLOCK
? +process.env.AVERAGE_MINING_BLOCK
: 6;
const slow: number = process.env.LOW_MINING_BLOCK
? +process.env.LOW_MINING_BLOCK
: 12;
feeProvider.withArgs(fast).resolves(['0.00003']);
feeProvider.withArgs(average).resolves(['0.00002']);
feeProvider.withArgs(slow).resolves(['0.00001']);
findAccountUtxos.resolves(getUtxoList());
getAccountInputs.resolves(getMockInputs());
const sessionId = 'test_id';
const request = new FeeRequestData({
sessionId,
amount: 0.00004,
accountType: constants.BITCOIN_LEGACY_ADDRESS,
});
const feeAmount = await controller.getTxFee(request);
expect(feeAmount.slow).to.eql(338000.00000000006);
expect(feeAmount.average).to.eql(676000.0000000001);
expect(feeAmount.fast).to.eql(1014000);
});
});
42 changes: 42 additions & 0 deletions src/controllers/broadcast.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {inject} from '@loopback/core';
import {Broadcast} from '../services';
import {post, getModelSchemaRef, requestBody} from '@loopback/rest';
import {BroadcastRequest, BroadcastResponse} from '../models';

export class BroadcastController {
constructor(
@inject('services.Broadcast')
protected broadcastProvider: Broadcast,
) {}

@post('/broadcast', {
responses: {
'201': {
description: 'a Tx Broadcast',
content: {
'application/json': {
schema: getModelSchemaRef(BroadcastResponse),
},
},
},
},
})
sendTx(
@requestBody({schema: getModelSchemaRef(BroadcastRequest)})
req: BroadcastRequest,
): Promise<BroadcastResponse> {
return new Promise<BroadcastResponse>((resolve, reject) => {
this.broadcastProvider
.broadcast(req.data)
.then(([txStatus]) => {
resolve(
new BroadcastResponse({
txId: txStatus.result ?? '',
error: txStatus.error ?? undefined,
}),
);
})
.catch(reject);
});
}
}
1 change: 1 addition & 0 deletions src/controllers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './pegin-configuration.controller';
export * from './balance.controller';
export * from './pegin-tx.controller';
export * from './tx-fee.controller';
export * from './broadcast.controller';
Loading

0 comments on commit 559317e

Please sign in to comment.