From 4542f965695f8ec8191bed7467fb91c1b498f25e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Abadesso?= Date: Mon, 12 Aug 2024 10:23:06 -0300 Subject: [PATCH 1/4] tests: added missing tests --- .../__tests__/services/services.test.ts | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/packages/daemon/__tests__/services/services.test.ts b/packages/daemon/__tests__/services/services.test.ts index df228032..1e12bf87 100644 --- a/packages/daemon/__tests__/services/services.test.ts +++ b/packages/daemon/__tests__/services/services.test.ts @@ -20,6 +20,7 @@ import { addOrUpdateTx, getAddressWalletInfo, generateAddresses, + storeTokenInformation, } from '../../src/db'; import { fetchInitialState, @@ -501,6 +502,85 @@ describe('handleVertexAccepted', () => { 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', () => { From d857a4026d2efa26a259c6e9a43dedad47ee3fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Abadesso?= Date: Mon, 12 Aug 2024 11:03:19 -0300 Subject: [PATCH 2/4] tests: added missing tests for nft push --- .../__tests__/services/services.test.ts | 70 +++++++++++++++++++ .../daemon/__tests__/utils/wallet.test.ts | 49 +++++++++++++ packages/daemon/src/services/index.ts | 2 +- packages/daemon/src/utils/index.ts | 1 + 4 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 packages/daemon/__tests__/utils/wallet.test.ts diff --git a/packages/daemon/__tests__/services/services.test.ts b/packages/daemon/__tests__/services/services.test.ts index 1e12bf87..d0baf803 100644 --- a/packages/daemon/__tests__/services/services.test.ts +++ b/packages/daemon/__tests__/services/services.test.ts @@ -37,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', () => ({ @@ -89,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(() => { @@ -503,6 +516,63 @@ describe('handleVertexAccepted', () => { 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'; diff --git a/packages/daemon/__tests__/utils/wallet.test.ts b/packages/daemon/__tests__/utils/wallet.test.ts new file mode 100644 index 00000000..92d19011 --- /dev/null +++ b/packages/daemon/__tests__/utils/wallet.test.ts @@ -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-ignore: 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(); + }); +}); diff --git a/packages/daemon/src/services/index.ts b/packages/daemon/src/services/index.ts index 2a810dec..71a45c42 100644 --- a/packages/daemon/src/services/index.ts +++ b/packages/daemon/src/services/index.ts @@ -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', diff --git a/packages/daemon/src/utils/index.ts b/packages/daemon/src/utils/index.ts index f037423a..c29b6e2d 100644 --- a/packages/daemon/src/utils/index.ts +++ b/packages/daemon/src/utils/index.ts @@ -10,3 +10,4 @@ export * from './cache'; export * from './wallet'; export * from './date'; export * from './helpers'; +export * from './aws'; From abea833c1169e513bee144713c108785af944fcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Abadesso?= Date: Fri, 16 Aug 2024 13:17:57 -0300 Subject: [PATCH 3/4] chore: added docker-compose to flake --- flake.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/flake.nix b/flake.nix index 7d012645..8dc4438b 100644 --- a/flake.nix +++ b/flake.nix @@ -36,6 +36,7 @@ nixpkgs-fmt nodejs_20 yarn + docker-compose ]; }; }); From 32b57c6ccb7c9affb98c880ed3cef6433e407ef2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Abadesso?= Date: Wed, 4 Sep 2024 09:28:23 -0300 Subject: [PATCH 4/4] tests: ts-ignore -> ts-expect-error --- packages/daemon/__tests__/utils/wallet.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/daemon/__tests__/utils/wallet.test.ts b/packages/daemon/__tests__/utils/wallet.test.ts index 92d19011..4d60c86e 100644 --- a/packages/daemon/__tests__/utils/wallet.test.ts +++ b/packages/daemon/__tests__/utils/wallet.test.ts @@ -18,7 +18,7 @@ describe('prepareOutputs', () => { value: 1, token_data: 0, script: 'OmlwZnM6Ly9pcGZzL1FtTlJtNmhRUDN2MlVMclVOZTJQTTY4V1dRb2EyUmVwY1IxejVUVVdWZmd0bzGs', - // @ts-ignore: This type is wrong, we should allow null here in the type + // @ts-expect-error: This type is wrong, we should allow null here in the type decoded: null }, { value: 2116,