Skip to content

Integration tests: simple send-tx, send-tx, create-tokens, mint and melt tokens #152

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 47 commits into from
Mar 17, 2022
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
02d0029
docs: minor changes to jsdocs
tuliomir Mar 3, 2022
7d537a9
perf: wallets starting in parallel instead of serially
tuliomir Mar 3, 2022
1dcdcc9
feat: simple-send-tx tests
tuliomir Mar 3, 2022
02bc015
feat: send-tx tests with single token and automatic inputs
tuliomir Mar 3, 2022
1a35e44
refactor: logging address samples when starting multiple wallets
tuliomir Mar 4, 2022
5dc8a4e
test: sending with filter_address query
tuliomir Mar 4, 2022
894b571
test: sending with single input
tuliomir Mar 4, 2022
9db6c4b
test: sending with multiple inputs
tuliomir Mar 5, 2022
f5a45b8
test: sending a custom token
tuliomir Mar 5, 2022
18e0e1c
test: sending custom tokens with inputs and "body.token" property
tuliomir Mar 7, 2022
98acaac
test: send-tx with multiple tokens
tuliomir Mar 7, 2022
1900c38
refactor: successful transactions changed to use wallet helper
tuliomir Mar 7, 2022
a0a17df
style: applied standardized formatting
tuliomir Mar 8, 2022
d27fed8
test: create-token tests
tuliomir Mar 8, 2022
69e7b4e
test: mint-token tests
tuliomir Mar 8, 2022
9416f88
test: melt-tokens tests
tuliomir Mar 8, 2022
cd5deda
refactor: improving docs and naming for clarity
tuliomir Mar 8, 2022
345132f
style: linting
tuliomir Mar 8, 2022
7df12d8
style: fix wrong linting of expect calls
tuliomir Mar 8, 2022
f493395
docs: minor fixes to comments and jsdocs
tuliomir Mar 8, 2022
4f0f1dd
refactor: wallet validation pooling off by default
tuliomir Mar 10, 2022
ce9a797
perf: transactions no longer pause to wait for websocket response
tuliomir Mar 10, 2022
a0ddc14
docs: jsdocs, comments and variable renaming
tuliomir Mar 10, 2022
0af0a34
feat: new helper functions for wallet txHistory and balance
tuliomir Mar 10, 2022
cf50d7b
refactor: improvements to create-token legibility
tuliomir Mar 10, 2022
aa62ed6
test: testing all input possibilities on create-token
tuliomir Mar 10, 2022
4bfbc4e
test: testing all input possibilities on mint-tokens
tuliomir Mar 10, 2022
ff5a026
test: improving assertions and validations on simple-send-tx
tuliomir Mar 10, 2022
2ae9839
test: improving assertions and validations on melt-tokens
tuliomir Mar 11, 2022
10260cd
test: improving assertions and validations on send-tx
tuliomir Mar 11, 2022
1846a50
test: multi-token, automatic change address test
tuliomir Mar 11, 2022
19eb84f
style: eslint
tuliomir Mar 14, 2022
d9f3e4c
test: create-token field size validations
tuliomir Mar 14, 2022
bca626b
test: new token api tests with a single input and with no inputs
tuliomir Mar 14, 2022
00118d6
refactor: renaming variables for clarity
tuliomir Mar 14, 2022
be1868a
fix: made tests more strict and skipped failing ones
tuliomir Mar 15, 2022
5ed963b
fix: removing unnecessary tests and assertions
tuliomir Mar 15, 2022
b796bbc
test: including assertion for change address on basic create token test
tuliomir Mar 15, 2022
81e7435
style: converted static string templates into single tick strings
tuliomir Mar 15, 2022
5d96d3d
perf: wallet starter now working in parallel
tuliomir Mar 15, 2022
f03d567
refactor: removed irrelevant afterAll() on setupTests-integration
tuliomir Mar 15, 2022
48b06dd
style: typo
tuliomir Mar 15, 2022
6125d91
refactor: websocket update delay period moved to config file
tuliomir Mar 15, 2022
bf92183
feat: timeout protection on multiple wallet initialization.
tuliomir Mar 15, 2022
0a8246f
chore: added new timeout variable to config files
tuliomir Mar 15, 2022
126370d
docs: added todos on pending assertions
tuliomir Mar 15, 2022
02d690b
chore: moved test configurations to separate file
tuliomir Mar 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ config.js
node_modules/

coverage
coverage-integration

.DS_Store
9 changes: 5 additions & 4 deletions __tests__/integration/address-info.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@ describe('address-info routes', () => {
try {
// A random HTR value for the first wallet
wallet1 = new WalletHelper('addinfo-1');
await wallet1.start();
await wallet1.injectFunds(address1balance, 1);

// A fixed custom token amount for the second wallet
wallet2 = new WalletHelper('addinfo-2');
await wallet2.start();

await WalletHelper.startMultipleWalletsForTest([wallet1, wallet2]);
await wallet1.injectFunds(address1balance, 1);
await wallet2.injectFunds(10);
const customToken = await wallet2.createToken({
amount: 500,
Expand All @@ -32,6 +31,8 @@ describe('address-info routes', () => {
});
customTokenHash = customToken.hash;

await TestUtils.pauseForWsUpdate();

/*
* The state here should be:
* wallet1[1] with some value between 100 and 200 HTR
Expand Down
13 changes: 7 additions & 6 deletions __tests__/integration/balance.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,16 @@ describe('balance routes', () => {
try {
// First wallet, no balance
wallet1 = new WalletHelper('balance1');
await wallet1.start();

// Second wallet, random balance
wallet2 = new WalletHelper('balance2');
await wallet2.start();
await wallet2.injectFunds(wallet2Balance);

// Third wallet, balance to be used for custom tokens
wallet3 = new WalletHelper('custom3');
await wallet3.start();

await WalletHelper.startMultipleWalletsForTest([wallet1, wallet2, wallet3]);
await wallet2.injectFunds(wallet2Balance);
await wallet3.injectFunds(100);

await TestUtils.pauseForWsUpdate();
} catch (err) {
TestUtils.logError(err.stack);
}
Expand Down Expand Up @@ -90,6 +89,8 @@ describe('balance routes', () => {
});
const tokenHash = newToken.hash;

await TestUtils.pauseForWsUpdate();

const balanceResult = await TestUtils.request
.get('/wallet/balance')
.query({ token: tokenHash })
Expand Down
290 changes: 290 additions & 0 deletions __tests__/integration/create-token.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,290 @@
import { getRandomInt, TestUtils, WALLET_CONSTANTS } from './utils/test-utils-integration';
import { WalletHelper } from './utils/wallet-helper';

describe('create token', () => {
let wallet1;
let wallet2;

const tokenA = {
name: 'Token A',
symbol: 'TKA',
uid: null
};

beforeAll(async () => {
wallet1 = new WalletHelper('create-token-1');
wallet2 = new WalletHelper('create-token-2');

await WalletHelper.startMultipleWalletsForTest([wallet1, wallet2]);
await wallet1.injectFunds(10, 0);
await wallet1.injectFunds(10, 1);
await wallet2.injectFunds(10, 0);
});

afterAll(async () => {
await wallet1.stop();
await wallet2.stop();
});

// Testing failures first, that do not cause side-effects on the blockchain

it('should reject missing name parameter', async done => {
const response = await TestUtils.request
.post('/wallet/create-token')
.send({
symbol: tokenA.symbol,
amount: 1000
})
.set({ 'x-wallet-id': wallet1.walletId });

expect(response.status).toBe(400);
expect(response.body.success).toBe(false);
done();
});

it('should reject missing symbol parameter', async done => {
const response = await TestUtils.request
.post('/wallet/create-token')
.send({
name: tokenA.name,
amount: 1000
})
.set({ 'x-wallet-id': wallet1.walletId });

expect(response.status).toBe(400);
expect(response.body.success).toBe(false);
done();
});

it('should reject a name with more than 30 characters', async done => {
const response = await TestUtils.request
.post('/wallet/create-token')
.send({
name: 'Name input with more than 30 characters',
symbol: tokenA.symbol,
amount: 1000
})
.set({ 'x-wallet-id': wallet1.walletId });

expect(response.body.success).toBe(false);
expect(response.body.error).toContain('maximum size');
done();
});

// The result is an error with the message "maximum size", but consumes the funds. Must be fixed.
it.skip('should reject a symbol with more than 5 characters', async done => {
const response = await TestUtils.request
.post('/wallet/create-token')
.send({
name: tokenA.name,
symbol: 'TKABCD',
amount: 1000
})
.set({ 'x-wallet-id': wallet1.walletId });

expect(response.body.success).toBe(false);
expect(response.body.error).toContain('maximum size');
done();
});

it('should reject an invalid destination address', async done => {
const response = await TestUtils.request
.post('/wallet/create-token')
.send({
name: tokenA.name,
symbol: tokenA.symbol,
amount: 1000,
address: 'invalidAddress'
})
.set({ 'x-wallet-id': wallet1.walletId });

expect(response.status).toBe(200);
expect(response.body.success).toBe(false);
expect(response.body.error).toContain('base58');
done();
});

it('should reject an invalid change address', async done => {
const response = await TestUtils.request
.post('/wallet/create-token')
.send({
name: tokenA.name,
symbol: tokenA.symbol,
amount: 500,
address: await wallet1.getAddressAt(0),
change_address: 'invalidAddress'
})
.set({ 'x-wallet-id': wallet1.walletId });

expect(response.status).toBe(200);
expect(response.body.success).toBe(false);
expect(response.body.error).toContain('Change address');
done();
});

// The application is incorrectly allowing to create a token for an outside address.
it.skip('should reject creating token for address not in the wallet', async done => {
const response = await TestUtils.request
.post('/wallet/create-token')
.send({
name: tokenA.name,
symbol: tokenA.symbol,
amount: 500,
address: WALLET_CONSTANTS.genesis.addresses[3]
})
.set({ 'x-wallet-id': wallet1.walletId });

expect(response.status).toBe(200);
expect(response.body.success).toBe(false);
done();
});

// The application is incorrectly allowing external addresses to receive the change
it.skip('should reject creating token for change address not in the wallet', async done => {
const response = await TestUtils.request
.post('/wallet/create-token')
.send({
name: tokenA.name,
symbol: tokenA.symbol,
amount: 500,
address: await wallet1.getAddressAt(0),
change_address: WALLET_CONSTANTS.genesis.addresses[3]
})
.set({ 'x-wallet-id': wallet1.walletId });

expect(response.status).toBe(200);
expect(response.body.success).toBe(false);
expect(response.text).toContain('wallet');
done();
});

// Insuficcient funds

it('should reject for insuficcient funds', async done => {
const response = await TestUtils.request
.post('/wallet/create-token')
.send({
name: tokenA.name,
symbol: tokenA.symbol,
amount: 3000
})
.set({ 'x-wallet-id': wallet1.walletId });

expect(response.status).toBe(200);
expect(response.body.success).toBe(false);
expect(response.body.hash).toBeUndefined();
done();
});

it('should not create a token with the reserved HTR symbol', async done => {
const response = await TestUtils.request
.post('/wallet/create-token')
.send({
name: 'Hathor',
symbol: 'HTR',
amount: 100
})
.set({ 'x-wallet-id': wallet1.walletId });

expect(response.status).toBe(200);
expect(response.body.success).toBe(false);
expect(response.body.hash).toBeUndefined();
expect(response.body.error).toContain('Invalid token name');
done();
});

it('should create a token with only required parameters', async done => {
const response = await TestUtils.request
.post('/wallet/create-token')
.send({
name: tokenA.name,
symbol: tokenA.symbol,
amount: 100
})
.set({ 'x-wallet-id': wallet1.walletId });

expect(response.body.success).toBe(true);
expect(response.body.hash).toBeDefined();

await TestUtils.pauseForWsUpdate();

const tkaBalance = await wallet1.getBalance(response.body.hash);
expect(tkaBalance.available).toBe(100);
done();
});

it('should send the created tokens to the correct address', async done => {
const amountTokens = getRandomInt(100, 200);
const response = await TestUtils.request
.post('/wallet/create-token')
.send({
name: 'Token B',
symbol: 'TKB',
amount: amountTokens,
address: await wallet1.getAddressAt(9)
})
.set({ 'x-wallet-id': wallet1.walletId });

const transaction = response.body;
expect(transaction.success).toBe(true);

await TestUtils.pauseForWsUpdate();

const addr9 = await wallet1.getAddressInfo(9, transaction.hash);
expect(addr9.total_amount_received).toBe(amountTokens);
done();
});

it('should send the change to the correct address', async done => {
const response = await TestUtils.request
.post('/wallet/create-token')
.send({
name: 'Token C',
symbol: 'TKC',
amount: 100,
change_address: await wallet2.getAddressAt(5)
})
.set({ 'x-wallet-id': wallet2.walletId });

const transaction = response.body;
expect(transaction.success).toBe(true);

// The only output with token_data equals zero is the one containing the HTR change
const htrOutputIndex = transaction.outputs.findIndex(o => o.token_data === 0);
const htrChange = transaction.outputs[htrOutputIndex].value;

await TestUtils.pauseForWsUpdate();

const addr5 = await wallet2.getAddressInfo(5);
expect(addr5.total_amount_received).toBe(htrChange);
done();
});

it('should create a token with all available inputs', async done => {
const response = await TestUtils.request
.post('/wallet/create-token')
.send({
name: 'Token D',
symbol: 'TKD',
amount: 200,
address: await wallet2.getAddressAt(4),
change_address: await wallet2.getAddressAt(4)
})
.set({ 'x-wallet-id': wallet2.walletId });

const transaction = response.body;
expect(transaction.success).toBe(true);

// The only output with token_data equals zero is the one containing the HTR change
const htrOutputIndex = transaction.outputs.findIndex(o => o.token_data === 0);
const htrChange = transaction.outputs[htrOutputIndex].value;

await TestUtils.pauseForWsUpdate();

const addr4 = await wallet2.getAddressInfo(4);
expect(addr4.total_amount_received).toBe(htrChange);
const addr4C = await wallet2.getAddressInfo(4, transaction.hash);
expect(addr4C.total_amount_available).toBe(200);
done();
});
});
2 changes: 1 addition & 1 deletion __tests__/integration/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ services:
depends_on:
- fullnode
ports:
- "8034:8034" # Not mandatory to keep these ports open, but helpful for developer machine debugging
- "8034:8034" # Not mandatory to keep this port open, but helpful for developer machine debugging
- "8035:8035"
command: [
"http://fullnode:8080",
Expand Down
Loading