Skip to content

Commit

Permalink
tests: missing tests [part 1/2] (#183)
Browse files Browse the repository at this point in the history
* tests: added missing tests

* tests: added missing tests for nft push

* chore: added docker-compose to flake

* tests: ts-ignore -> ts-expect-error
  • Loading branch information
andreabadesso authored Sep 4, 2024
1 parent 9e8959d commit b9e6d6f
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 1 deletion.
1 change: 1 addition & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
nixpkgs-fmt
nodejs_20
yarn
docker-compose
];
};
});
Expand Down
150 changes: 150 additions & 0 deletions packages/daemon/__tests__/services/services.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
addOrUpdateTx,
getAddressWalletInfo,
generateAddresses,
storeTokenInformation,
} from '../../src/db';
import {
fetchInitialState,
Expand All @@ -36,7 +37,17 @@ import {
prepareOutputs,
hashTxData,
getFullnodeHttpUrl,
invokeOnTxPushNotificationRequestedLambda,
getWalletBalancesForTx,
} from '../../src/utils';
import getConfig from '../../src/config';

jest.mock('../../src/config', () => {
return {
__esModule: true, // This property is needed for mocking a default export
default: jest.fn(() => ({})),
};
});

jest.mock('@hathor/wallet-lib');
jest.mock('../../src/logger', () => ({
Expand Down Expand Up @@ -88,6 +99,9 @@ jest.mock('../../src/utils', () => ({
getUnixTimestamp: jest.fn(),
unlockUtxos: jest.fn(),
getFullnodeHttpUrl: jest.fn(),
invokeOnTxPushNotificationRequestedLambda: jest.fn(),
sendMessageSQS: jest.fn(),
getWalletBalancesForTx: jest.fn(),
}));

beforeEach(() => {
Expand Down Expand Up @@ -501,6 +515,142 @@ describe('handleVertexAccepted', () => {
expect(mockDb.commit).toHaveBeenCalled();
expect(mockDb.destroy).toHaveBeenCalled();
});

it('should handle call the push notification lambda if PUSH_NOTIFICATION_ENABLED is true', async () => {
const context = {
event: {
event: {
data: {
hash: 'hashValue',
metadata: {
height: 123,
first_block: true,
voided_by: [],
},
timestamp: new Date().getTime(),
version: 1,
weight: 17.17,
outputs: [],
inputs: [1],
tokens: [],
},
id: 'idValue',
},
},
rewardMinBlocks: 300,
txCache: {
get: jest.fn(),
set: jest.fn(),
},
};

(getConfig as jest.Mock).mockReturnValue({
PUSH_NOTIFICATION_ENABLED: true,
NEW_TX_SQS: 'http://nowhere.com',
});

(addOrUpdateTx as jest.Mock).mockReturnValue(Promise.resolve());
(getTransactionById as jest.Mock).mockResolvedValue(null); // Transaction is not in the database
(prepareOutputs as jest.Mock).mockReturnValue([]);
(prepareInputs as jest.Mock).mockReturnValue([]);
(getAddressBalanceMap as jest.Mock).mockReturnValue({});
(getUtxosLockedAtHeight as jest.Mock).mockResolvedValue([]);
(hashTxData as jest.Mock).mockReturnValue('hashedData');
(getAddressWalletInfo as jest.Mock).mockResolvedValue({
'address1': {
walletId: 'wallet1',
xpubkey: 'xpubkey1',
maxGap: 10
},
});
(getWalletBalancesForTx as jest.Mock).mockResolvedValue({ 'mockWallet': {} });
(invokeOnTxPushNotificationRequestedLambda as jest.Mock).mockResolvedValue(undefined);

await handleVertexAccepted(context as any, {} as any);

expect(invokeOnTxPushNotificationRequestedLambda).toHaveBeenCalled();
expect(mockDb.commit).toHaveBeenCalled();
expect(mockDb.destroy).toHaveBeenCalled();
});

it('should handle add tokens to database on token creation tx', async () => {
const tokenName = 'TEST_TOKEN';
const tokenSymbol = 'TST_TKN';
const hash = '000013f562dc216890f247688028754a49d21dbb2b1f7731f840dc65585b1d57';
const context = {
event: {
event: {
data: {
hash,
metadata: {
height: 123,
first_block: true,
voided_by: [],
},
timestamp: 'timestampValue',
version: 2,
weight: 70,
outputs: [],
inputs: [],
tokens: [],
token_name: tokenName,
token_symbol: tokenSymbol,
},
id: 5
},
},
rewardMinBlocks: 300,
txCache: {
get: jest.fn(),
set: jest.fn(),
},
};

(addOrUpdateTx as jest.Mock).mockReturnValue(Promise.resolve());
(getTransactionById as jest.Mock).mockResolvedValue(null); // Transaction is not in the database
(prepareOutputs as jest.Mock).mockReturnValue([]);
(prepareInputs as jest.Mock).mockReturnValue([]);
(getAddressBalanceMap as jest.Mock).mockReturnValue({});
(getUtxosLockedAtHeight as jest.Mock).mockResolvedValue([]);
(hashTxData as jest.Mock).mockReturnValue('hashedData');
(getAddressWalletInfo as jest.Mock).mockResolvedValue({
'address1': {
walletId: 'wallet1',
xpubkey: 'xpubkey1',
maxGap: 10
},
});

await handleVertexAccepted(context as any, {} as any);

expect(storeTokenInformation).toHaveBeenCalledWith(mockDb, hash, tokenName, tokenSymbol);
expect(mockDb.commit).toHaveBeenCalled();
expect(mockDb.destroy).toHaveBeenCalled();
});

it('should rollback on error and rethrow', async () => {
(getTransactionById as jest.Mock).mockRejectedValue(new Error('Test error'));

const context = {
rewardMinBlocks: 5,
event: {
event: {
data: {
hash: 'hashValue',
outputs: 'outputsValue',
inputs: 'inputsValue',
tokens: 'tokensValue',
},
id: 'idValue',
},
},
};

await expect(handleVertexAccepted(context as any, {} as any)).rejects.toThrow('Test error');
expect(mockDb.beginTransaction).toHaveBeenCalled();
expect(mockDb.rollback).toHaveBeenCalled();
expect(mockDb.destroy).toHaveBeenCalled();
});
});

describe('metadataDiff', () => {
Expand Down
49 changes: 49 additions & 0 deletions packages/daemon/__tests__/utils/wallet.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* Copyright (c) Hathor Labs and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import { EventTxOutput } from '../../src/types';
import { prepareOutputs } from '../../src/utils';

/**
* @jest-environment node
*/

describe('prepareOutputs', () => {
it('should ignore NFT outputs', () => {
const nftOutputs: EventTxOutput[] = [{
value: 1,
token_data: 0,
script: 'OmlwZnM6Ly9pcGZzL1FtTlJtNmhRUDN2MlVMclVOZTJQTTY4V1dRb2EyUmVwY1IxejVUVVdWZmd0bzGs',
// @ts-expect-error: This type is wrong, we should allow null here in the type
decoded: null
}, {
value: 2116,
token_data: 0,
script: 'dqkUCU1EY3YLi8WURhDOEsspok4Y0XiIrA==',
decoded: {
type: 'P2PKH',
address: 'H7NK2gjt5oaHzBEPoiH7y3d1NcPQi3Tr2F',
timelock: null,
}
}, {
value: 1,
token_data: 1,
script: 'dqkUXO7BFkikXo2qwldGMeJlzyPSbtKIrA==',
decoded: {
type: 'P2PKH',
address: 'HEzWZvoxDkZFnbmnK6BkQ8yw9xTyPXefGn',
timelock: null,
}
}];

const tokens = ['000013f562dc216890f247688028754a49d21dbb2b1f7731f840dc65585b1d57'];
const preparedOutputs = prepareOutputs(nftOutputs, tokens);

expect(preparedOutputs).toHaveLength(2);
expect(preparedOutputs.find((output) => output.script === nftOutputs[0].script)).toBeUndefined();
});
});
2 changes: 1 addition & 1 deletion packages/daemon/src/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ import {
} from '../db';
import getConfig from '../config';
import logger from '../logger';
import { invokeOnTxPushNotificationRequestedLambda, sendMessageSQS } from '../utils/aws';
import { invokeOnTxPushNotificationRequestedLambda, sendMessageSQS } from '../utils';

export const METADATA_DIFF_EVENT_TYPES = {
IGNORE: 'IGNORE',
Expand Down
1 change: 1 addition & 0 deletions packages/daemon/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export * from './cache';
export * from './wallet';
export * from './date';
export * from './helpers';
export * from './aws';

0 comments on commit b9e6d6f

Please sign in to comment.