From c7b2e7b9985c17f06e50b91d21e144a1fbf430e9 Mon Sep 17 00:00:00 2001 From: Miguel_LZPF Date: Wed, 10 Apr 2024 15:12:10 +0200 Subject: [PATCH 1/4] feat: [cli] backend configuration service test Signed-off-by: Miguel_LZPF --- .../BackendConfigurationService.test.ts | 344 ++++++++++++++++++ .../utilities/UtilitiesService.test.ts | 7 + .../app/service/wizard/WizardService.test.ts | 38 +- cli/package.json | 8 +- .../BackendConfigurationService.ts | 49 ++- cli/src/app/service/wizard/WizardService.ts | 2 +- 6 files changed, 412 insertions(+), 36 deletions(-) create mode 100644 cli/__tests__/app/service/configuration/BackendConfigurationService.test.ts diff --git a/cli/__tests__/app/service/configuration/BackendConfigurationService.test.ts b/cli/__tests__/app/service/configuration/BackendConfigurationService.test.ts new file mode 100644 index 000000000..6db26d317 --- /dev/null +++ b/cli/__tests__/app/service/configuration/BackendConfigurationService.test.ts @@ -0,0 +1,344 @@ +/* + * + * Hedera Stablecoin CLI + * + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { DEFAULT_BACKEND_ENDPOINT } from '../../../../src/core/Constants.js'; +import { + backendConfigurationService, + configurationService, + language, + utilsService, + wizardService, +} from '../../../../src/index.js'; +import { IConfiguration } from '../../../../src/domain/configuration/interfaces/IConfiguration.js'; +import { AccountType } from '../../../../src/domain/configuration/interfaces/AccountType.js'; + +const CONFIG: IConfiguration = { + defaultNetwork: 'testnet', + networks: [ + { + name: 'testnet', + chainId: 1, + consensusNodes: [], + }, + ], + accounts: [ + { + accountId: '0.0.123456', + type: AccountType.SelfCustodial, + selfCustodial: { + privateKey: { + key: '01234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde', + type: 'ED25519', + }, + }, + network: 'testnet', + alias: 'test', + importedTokens: [], + }, + ], + logs: { + path: './logs', + level: 'ERROR', + }, + rpcs: [ + { + name: 'HASHIO', + network: 'testnet', + baseUrl: 'https://testnet.hashio.io/api', + apiKey: '', + headerName: '', + selected: true, + }, + ], + backend: { + endpoint: 'http://test.net:666/api', + }, + factories: [ + { + id: '0.0.13579', + network: 'testnet', + }, + { + id: '0.0.02468', + network: 'previewnet', + }, + ], + mirrors: [ + { + name: 'HEDERA', + network: 'testnet', + baseUrl: 'https://testnet.mirrornode.hedera.com/api/v1/', + apiKey: '', + headerName: '', + selected: true, + }, + ], +}; +describe('Backend Configuration Service', () => { + beforeAll(() => { + // Mock all unwanted outputs + jest.spyOn(utilsService, 'showSpinner').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + }); + afterAll(() => { + jest.resetAllMocks(); + jest.restoreAllMocks(); + }); + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('Configure Backend', () => { + it('should configure backend with parameter', async () => { + //* 🗂️ Arrange + const ENDPOINT = 'http://test.param:1111/api'; + const EXPECTED_CONFIG = { ...CONFIG, backend: { endpoint: ENDPOINT } }; + const mocks = { + getConfiguration: jest + .spyOn(configurationService, 'getConfiguration') + .mockReturnValueOnce(CONFIG), + setConfiguration: jest + .spyOn(configurationService, 'setConfiguration') + .mockReturnValue(), + setCurrentBackend: jest + .spyOn(utilsService, 'setCurrentBackend') + .mockReturnValue(), + }; + //* 🎬 Act + const result = await backendConfigurationService.configureBackend({ + endpoint: ENDPOINT, + }); + + //* 🕵️ Assert + expect(mocks.getConfiguration).toHaveBeenCalledTimes(1); + expect(mocks.setConfiguration).toHaveBeenCalledTimes(1); + expect(mocks.setCurrentBackend).toHaveBeenCalledTimes(1); + expect(mocks.setConfiguration).toHaveBeenCalledWith(EXPECTED_CONFIG); + expect(mocks.setCurrentBackend).toHaveBeenCalledWith( + EXPECTED_CONFIG.backend, + ); + expect(result).not.toBeNull(); + expect(result.endpoint).toBe(ENDPOINT); + }); + + it('should configure backend using terminal', async () => { + //* 🗂️ Arrange + const BAD_ENDPOINT = 'badUrl'; + const ENDPOINT = 'http://test.terminal:2222/api'; + const CONFIG_WITHOUT_BACKEND = { ...CONFIG, backend: undefined }; + const EXPECTED_CONFIG = { ...CONFIG, backend: { endpoint: ENDPOINT } }; + const mocks = { + getConfiguration: jest + .spyOn(configurationService, 'getConfiguration') + .mockReturnValue(CONFIG_WITHOUT_BACKEND), + defaultSingleAsk: jest + .spyOn(utilsService, 'defaultSingleAsk') + .mockReturnValueOnce(Promise.resolve(BAD_ENDPOINT)) + .mockReturnValueOnce(Promise.resolve(ENDPOINT)), + setConfiguration: jest + .spyOn(configurationService, 'setConfiguration') + .mockReturnValue(), + setCurrentBackend: jest + .spyOn(utilsService, 'setCurrentBackend') + .mockReturnValue(), + }; + //* 🎬 Act + const result = await backendConfigurationService.configureBackend(); + + //* 🕵️ Assert + expect(mocks.getConfiguration).toHaveBeenCalledTimes(1); + expect(mocks.defaultSingleAsk).toHaveBeenCalledTimes(2); + expect(mocks.setConfiguration).toHaveBeenCalledTimes(1); + expect(mocks.setCurrentBackend).toHaveBeenCalledTimes(1); + expect(mocks.setConfiguration).toHaveBeenCalledWith(EXPECTED_CONFIG); + expect(mocks.setCurrentBackend).toHaveBeenCalledWith( + EXPECTED_CONFIG.backend, + ); + expect(result).not.toBeNull(); + expect(result.endpoint).toBe(ENDPOINT); + }); + + it('should configure backend using configuration', async () => { + //* 🗂️ Arrange + const BAD_ENDPOINT = 'badUrl'; + const mocks = { + getConfiguration: jest + .spyOn(configurationService, 'getConfiguration') + .mockReturnValue(CONFIG), + defaultSingleAsk: jest + .spyOn(utilsService, 'defaultSingleAsk') + .mockReturnValue(Promise.resolve(BAD_ENDPOINT)), + setConfiguration: jest + .spyOn(configurationService, 'setConfiguration') + .mockReturnValue(), + setCurrentBackend: jest + .spyOn(utilsService, 'setCurrentBackend') + .mockReturnValue(), + }; + //* 🎬 Act + const result = await backendConfigurationService.configureBackend(); + + //* 🕵️ Assert + expect(mocks.getConfiguration).toHaveBeenCalledTimes(1); + expect(mocks.defaultSingleAsk).toHaveBeenCalledTimes(5); + expect(mocks.setConfiguration).toHaveBeenCalledTimes(1); + expect(mocks.setCurrentBackend).toHaveBeenCalledTimes(1); + expect(mocks.setConfiguration).toHaveBeenCalledWith(CONFIG); + expect(mocks.setCurrentBackend).toHaveBeenCalledWith(CONFIG.backend); + expect(result).not.toBeNull(); + expect(result.endpoint).toBe(CONFIG.backend.endpoint); + }); + + it('should configure backend using default', async () => { + //* 🗂️ Arrange + const BAD_ENDPOINT = 'badUrl'; + const EXPECTED_CONFIG = { + ...CONFIG, + backend: { endpoint: DEFAULT_BACKEND_ENDPOINT }, + }; + const CONFIG_WITHOUT_BACKEND = { ...CONFIG, backend: undefined }; + const mocks = { + getConfiguration: jest + .spyOn(configurationService, 'getConfiguration') + .mockReturnValue(CONFIG_WITHOUT_BACKEND), + defaultSingleAsk: jest + .spyOn(utilsService, 'defaultSingleAsk') + .mockReturnValue(Promise.resolve(BAD_ENDPOINT)), + setConfiguration: jest + .spyOn(configurationService, 'setConfiguration') + .mockReturnValue(), + setCurrentBackend: jest + .spyOn(utilsService, 'setCurrentBackend') + .mockReturnValue(), + }; + //* 🎬 Act + const result = await backendConfigurationService.configureBackend(); + + //* 🕵️ Assert + expect(mocks.getConfiguration).toHaveBeenCalledTimes(1); + expect(mocks.defaultSingleAsk).toHaveBeenCalledTimes(5); + expect(mocks.setConfiguration).toHaveBeenCalledTimes(1); + expect(mocks.setCurrentBackend).toHaveBeenCalledTimes(1); + expect(mocks.setConfiguration).toHaveBeenCalledWith(EXPECTED_CONFIG); + expect(mocks.setCurrentBackend).toHaveBeenCalledWith( + EXPECTED_CONFIG.backend, + ); + expect(result).not.toBeNull(); + expect(result.endpoint).toBe(EXPECTED_CONFIG.backend.endpoint); + }); + }); + + describe('Manage Backend Menu', () => { + it('should update backend', async () => { + //* 🗂️ Arrange + const ENDPOINT = 'http://test.menu:3333/api'; + const MENU_OPTIONS = language.getArrayFromObject( + 'wizard.manageBackendOptions', + ); + const mocks = { + cleanAndShowBanner: jest + .spyOn(utilsService, 'cleanAndShowBanner') + .mockReturnValue(Promise.resolve()), + getConfiguration: jest + .spyOn(configurationService, 'getConfiguration') + .mockReturnValue(CONFIG), + defaultMultipleAsk: jest + .spyOn(utilsService, 'defaultMultipleAsk') + .mockReturnValueOnce(Promise.resolve(MENU_OPTIONS[0])), + defaultSingleAsk: jest + .spyOn(utilsService, 'defaultSingleAsk') + .mockReturnValue(Promise.resolve(ENDPOINT)), + setConfiguration: jest + .spyOn(configurationService, 'setConfiguration') + .mockReturnValue(), + setCurrentBackend: jest + .spyOn(utilsService, 'setCurrentBackend') + .mockReturnValue(), + configurationMenu: jest + .spyOn(wizardService, 'configurationMenu') + .mockReturnValue(Promise.resolve()), + }; + //* 🎬 Act + await backendConfigurationService.manageBackendMenu({ + options: { clear: true }, + }); + + //* 🕵️ Assert + expect(mocks.cleanAndShowBanner).toHaveBeenCalledTimes(1); + expect(mocks.getConfiguration).toHaveBeenCalledTimes(2); + expect(mocks.defaultMultipleAsk).toHaveBeenCalledTimes(1); + expect(mocks.defaultSingleAsk).toHaveBeenCalledTimes(1); + expect(mocks.setConfiguration).toHaveBeenCalledTimes(1); + expect(mocks.setCurrentBackend).toHaveBeenCalledTimes(1); + expect(mocks.configurationMenu).toHaveBeenCalledTimes(1); + expect(mocks.setConfiguration).toHaveBeenCalledWith({ + ...CONFIG, + backend: { endpoint: ENDPOINT }, + }); + expect(mocks.setCurrentBackend).toHaveBeenCalledWith({ + endpoint: ENDPOINT, + }); + }); + }); + + it('should remove backend', async () => { + //* 🗂️ Arrange + const MENU_OPTIONS = language.getArrayFromObject( + 'wizard.manageBackendOptions', + ); + const mocks = { + cleanAndShowBanner: jest + .spyOn(utilsService, 'cleanAndShowBanner') + .mockReturnValue(Promise.resolve()), + getConfiguration: jest + .spyOn(configurationService, 'getConfiguration') + .mockReturnValue(CONFIG), + defaultMultipleAsk: jest + .spyOn(utilsService, 'defaultMultipleAsk') + .mockReturnValueOnce(Promise.resolve(MENU_OPTIONS[1])), + setConfiguration: jest + .spyOn(configurationService, 'setConfiguration') + .mockReturnValue(), + setCurrentBackend: jest + .spyOn(utilsService, 'setCurrentBackend') + .mockReturnValue(), + configurationMenu: jest + .spyOn(wizardService, 'configurationMenu') + .mockReturnValue(Promise.resolve()), + }; + //* 🎬 Act + await backendConfigurationService.manageBackendMenu(); + + //* 🕵️ Assert + expect(mocks.cleanAndShowBanner).toHaveBeenCalledTimes(0); + expect(mocks.getConfiguration).toHaveBeenCalledTimes(2); + expect(mocks.defaultMultipleAsk).toHaveBeenCalledTimes(1); + expect(mocks.setConfiguration).toHaveBeenCalledTimes(1); + expect(mocks.setCurrentBackend).toHaveBeenCalledTimes(1); + expect(mocks.configurationMenu).toHaveBeenCalledTimes(1); + expect(mocks.setConfiguration).toHaveBeenCalledWith({ + ...CONFIG, + backend: undefined, + }); + expect(mocks.setCurrentBackend).toHaveBeenCalledWith(undefined); + }); +}); diff --git a/cli/__tests__/app/service/utilities/UtilitiesService.test.ts b/cli/__tests__/app/service/utilities/UtilitiesService.test.ts index d588a6080..e18d50854 100644 --- a/cli/__tests__/app/service/utilities/UtilitiesService.test.ts +++ b/cli/__tests__/app/service/utilities/UtilitiesService.test.ts @@ -59,6 +59,10 @@ describe('UtilitiesService', () => { selected: true, }; + const mockCurrentBackend = { + endpoint: 'http://localhost:3000/path', + }; + const mockLogConfiguration = { level: 'debug', }; @@ -81,6 +85,9 @@ describe('UtilitiesService', () => { .fn() .mockReturnValue(mockCurrentMirror); utilsService.getCurrentRPC = jest.fn().mockReturnValue(mockCurrentRPC); + utilsService.getCurrentBackend = jest + .fn() + .mockReturnValue(mockCurrentBackend); // method call await utilsService.initSDK(); diff --git a/cli/__tests__/app/service/wizard/WizardService.test.ts b/cli/__tests__/app/service/wizard/WizardService.test.ts index 5e729cd25..7087937b3 100644 --- a/cli/__tests__/app/service/wizard/WizardService.test.ts +++ b/cli/__tests__/app/service/wizard/WizardService.test.ts @@ -59,6 +59,13 @@ describe('wizardService', () => { }, }, }, + { + accountId: '0.0.4', + type: AccountType.MultiSignature, + network: 'testnet', + alias: 'aliasmulti-signature', + importedTokens: [{ id: '0.0.58325', symbol: 'TEST' }], + }, { accountId: 'account3', type: AccountType.Dfns, @@ -97,6 +104,9 @@ describe('wizardService', () => { selected: true, }, ], + backend: { + endpoint: 'http://localhost:3000/api/transactions', + }, factories: [ { id: '1', network: 'dev' }, { id: '2', network: 'testnet' }, @@ -244,25 +254,9 @@ describe('wizardService', () => { // verify expect(getConfigurationMock).toHaveBeenCalled(); - expect(setSelectedAccountMock).toHaveBeenCalledWith({ - accountId: 'account3', - type: AccountType.Dfns, - network: 'testnet', - alias: 'alias3', - nonCustodial: { - dfns: { - authorizationToken: 'authorizationToken', - credentialId: 'credentialId', - privateKeyPath: 'privateKeyPath', - appOrigin: 'appOrigin', - appId: 'appId', - testUrl: 'testUrl', - walletId: 'walletId', - hederaAccountPublicKey: 'hederaAccountPublicKey', - hederaAccountKeyType: 'hederaAccountKeyType', - }, - }, - }); + expect(setSelectedAccountMock).toHaveBeenCalledWith( + configurationMock.accounts[configurationMock.accounts.length - 1], + ); }); it('should set the selected account and related configurations', async () => { @@ -282,6 +276,9 @@ describe('wizardService', () => { const setCurrentRPCMock = jest .spyOn(utilsService, 'setCurrentRPC') .mockImplementation(); + const setCurrentBackendMock = jest + .spyOn(utilsService, 'setCurrentBackend') + .mockImplementation(); const setCurrentFactoryMock = jest .spyOn(utilsService, 'setCurrentFactory') .mockImplementation(); @@ -331,6 +328,9 @@ describe('wizardService', () => { headerName: '', selected: true, }); + expect(setCurrentBackendMock).toHaveBeenCalledWith({ + endpoint: configurationMock.backend.endpoint, + }); expect(setCurrentFactoryMock).toHaveBeenCalledWith({ id: '2', network: 'testnet', diff --git a/cli/package.json b/cli/package.json index 7ead4eedb..8317a75ec 100644 --- a/cli/package.json +++ b/cli/package.json @@ -24,14 +24,14 @@ "lint": "eslint --ext .ts --ext .mts .", "license:check": "license-check-and-add check -f src/resources/license-check-and-add.json", "license:add": "license-check-and-add add -f src/resources/license-check-and-add.json", + "prettier": "prettier --config .prettierrc --write .", + "prettierCheck": "prettier --config .prettierrc --check", + "pre-commit": "npm run license:add && npm run prettier && npm run lint", "test": "jest --maxWorkers=50%", "test:watch": "jest --watch --maxWorkers=25%", "test:ci": "jest --runInBand --forceExit", - "cleanCache": "npx jest --clearCache", "test:vm": "NODE_OPTIONS=--experimental-vm-modules npm run test", - "prettier": "prettier --config .prettierrc --write .", - "prettierCheck": "prettier --config .prettierrc --check", - "pre-commit": "npm run license:add && npm run prettier && npm run lint", + "cleanCache": "npx jest --clearCache", "prepack": "npm run build" }, "keywords": [], diff --git a/cli/src/app/service/configuration/BackendConfigurationService.ts b/cli/src/app/service/configuration/BackendConfigurationService.ts index 75b57b91f..55299bac5 100644 --- a/cli/src/app/service/configuration/BackendConfigurationService.ts +++ b/cli/src/app/service/configuration/BackendConfigurationService.ts @@ -29,14 +29,25 @@ import { import IBackendConfig from '../../../domain/configuration/interfaces/BackendConfig'; import Service from '../Service'; +/** + * Service class for managing the backend configuration. + */ export default class BackendConfigurationService extends Service { constructor() { super('Backend Configuration'); } - public async configureBackend(): Promise { - const configuration = configurationService.getConfiguration(); - const endpoint = configuration?.backend?.endpoint; + /** + * Configures the backend with the provided endpoint. + * + * @param options - The options for configuring the backend. + * @param options.endpoint - The endpoint URL or string. + * + * @returns A Promise that resolves to the updated backend configuration. + */ + public async configureBackend({ + endpoint, + }: { endpoint?: URL | string } = {}): Promise { return this._setBackendEndpoint({ endpoint }); } @@ -49,12 +60,12 @@ export default class BackendConfigurationService extends Service { * @returns A Promise that resolves when the backend menu is managed. */ public async manageBackendMenu( - { options }: { options: { clean?: boolean } } = { - options: { clean: false }, + { options }: { options: { clear?: boolean } } = { + options: { clear: false }, }, ): Promise { // Clean the terminal and show the banner - if (options.clean) { + if (options.clear) { await utilsService.cleanAndShowBanner(); } // Get the current account, mirror, rpc to display @@ -99,31 +110,41 @@ export default class BackendConfigurationService extends Service { } } + /** + * Sets the backend endpoint configuration. + * + * @param {Object} options - The options for setting the backend endpoint. + * @param {URL | string} options.endpoint - The endpoint URL or string. + * + * @returns {Promise} The updated backend configuration. + */ private async _setBackendEndpoint({ endpoint, }: { endpoint?: URL | string } = {}): Promise { - // Try to get the endpoint up to 5 times + // Try to get a valid endpoint up to 5 times for (let tries = 0; tries < 5; tries++) { try { + if (endpoint) break; // If we have a valid endpoint, break the loop const answer = await utilsService.defaultSingleAsk( language.getText('configuration.askBackendUrl'), DEFAULT_BACKEND_ENDPOINT, ); endpoint = new URL(answer); - if (endpoint) break; // If we have a valid endpoint, break the loop } catch (error) { utilsService.showError( `${error}\n${language.getText('general.incorrectParam')}`, ); } } - // If we still don't have a valid endpoint, use the default one + // Get the current configuration + const configuration = configurationService.getConfiguration(); + // If we still don't have a valid endpoint, use the actual configured or use the default one if (!endpoint) { - endpoint = new URL(DEFAULT_BACKEND_ENDPOINT); + endpoint = new URL( + configuration.backend?.endpoint || DEFAULT_BACKEND_ENDPOINT, + ); } - // Update the configuration and return it - const configuration = configurationService.getConfiguration(); configuration.backend = { endpoint: endpoint.toString(), } as IBackendConfig; @@ -132,6 +153,10 @@ export default class BackendConfigurationService extends Service { return configuration.backend; } + /** + * Removes the backend configuration from the service. + * This method sets the backend configuration to undefined and updates the current backend. + */ private _removeBackend(): void { const configuration = configurationService.getConfiguration(); configuration.backend = undefined; diff --git a/cli/src/app/service/wizard/WizardService.ts b/cli/src/app/service/wizard/WizardService.ts index 1199c5a61..ecff44ce3 100644 --- a/cli/src/app/service/wizard/WizardService.ts +++ b/cli/src/app/service/wizard/WizardService.ts @@ -228,7 +228,7 @@ export default class WizardService extends Service { case language.getText('wizard.changeOptions.ManageBackend'): await backendConfigurationService.manageBackendMenu({ - options: { clean: true }, + options: { clear: true }, }); break; From aef3af63ed7acd00fe76000d98612b95fe417412 Mon Sep 17 00:00:00 2001 From: Miguel_LZPF Date: Thu, 11 Apr 2024 11:34:39 +0200 Subject: [PATCH 2/4] feat: [cli] list multisig tx service test Signed-off-by: Miguel_LZPF --- .../BackendConfigurationService.test.ts | 79 +++-- .../stablecoin/ListMultiSigTxService.test.ts | 313 ++++++++++++++++++ 2 files changed, 352 insertions(+), 40 deletions(-) create mode 100644 cli/__tests__/app/service/stablecoin/ListMultiSigTxService.test.ts diff --git a/cli/__tests__/app/service/configuration/BackendConfigurationService.test.ts b/cli/__tests__/app/service/configuration/BackendConfigurationService.test.ts index 6db26d317..ef49f08ef 100644 --- a/cli/__tests__/app/service/configuration/BackendConfigurationService.test.ts +++ b/cli/__tests__/app/service/configuration/BackendConfigurationService.test.ts @@ -298,47 +298,46 @@ describe('Backend Configuration Service', () => { endpoint: ENDPOINT, }); }); - }); - - it('should remove backend', async () => { - //* 🗂️ Arrange - const MENU_OPTIONS = language.getArrayFromObject( - 'wizard.manageBackendOptions', - ); - const mocks = { - cleanAndShowBanner: jest - .spyOn(utilsService, 'cleanAndShowBanner') - .mockReturnValue(Promise.resolve()), - getConfiguration: jest - .spyOn(configurationService, 'getConfiguration') - .mockReturnValue(CONFIG), - defaultMultipleAsk: jest - .spyOn(utilsService, 'defaultMultipleAsk') - .mockReturnValueOnce(Promise.resolve(MENU_OPTIONS[1])), - setConfiguration: jest - .spyOn(configurationService, 'setConfiguration') - .mockReturnValue(), - setCurrentBackend: jest - .spyOn(utilsService, 'setCurrentBackend') - .mockReturnValue(), - configurationMenu: jest - .spyOn(wizardService, 'configurationMenu') - .mockReturnValue(Promise.resolve()), - }; - //* 🎬 Act - await backendConfigurationService.manageBackendMenu(); + it('should remove backend', async () => { + //* 🗂️ Arrange + const MENU_OPTIONS = language.getArrayFromObject( + 'wizard.manageBackendOptions', + ); + const mocks = { + cleanAndShowBanner: jest + .spyOn(utilsService, 'cleanAndShowBanner') + .mockReturnValue(Promise.resolve()), + getConfiguration: jest + .spyOn(configurationService, 'getConfiguration') + .mockReturnValue(CONFIG), + defaultMultipleAsk: jest + .spyOn(utilsService, 'defaultMultipleAsk') + .mockReturnValueOnce(Promise.resolve(MENU_OPTIONS[1])), + setConfiguration: jest + .spyOn(configurationService, 'setConfiguration') + .mockReturnValue(), + setCurrentBackend: jest + .spyOn(utilsService, 'setCurrentBackend') + .mockReturnValue(), + configurationMenu: jest + .spyOn(wizardService, 'configurationMenu') + .mockReturnValue(Promise.resolve()), + }; + //* 🎬 Act + await backendConfigurationService.manageBackendMenu(); - //* 🕵️ Assert - expect(mocks.cleanAndShowBanner).toHaveBeenCalledTimes(0); - expect(mocks.getConfiguration).toHaveBeenCalledTimes(2); - expect(mocks.defaultMultipleAsk).toHaveBeenCalledTimes(1); - expect(mocks.setConfiguration).toHaveBeenCalledTimes(1); - expect(mocks.setCurrentBackend).toHaveBeenCalledTimes(1); - expect(mocks.configurationMenu).toHaveBeenCalledTimes(1); - expect(mocks.setConfiguration).toHaveBeenCalledWith({ - ...CONFIG, - backend: undefined, + //* 🕵️ Assert + expect(mocks.cleanAndShowBanner).toHaveBeenCalledTimes(0); + expect(mocks.getConfiguration).toHaveBeenCalledTimes(2); + expect(mocks.defaultMultipleAsk).toHaveBeenCalledTimes(1); + expect(mocks.setConfiguration).toHaveBeenCalledTimes(1); + expect(mocks.setCurrentBackend).toHaveBeenCalledTimes(1); + expect(mocks.configurationMenu).toHaveBeenCalledTimes(1); + expect(mocks.setConfiguration).toHaveBeenCalledWith({ + ...CONFIG, + backend: undefined, + }); + expect(mocks.setCurrentBackend).toHaveBeenCalledWith(undefined); }); - expect(mocks.setCurrentBackend).toHaveBeenCalledWith(undefined); }); }); diff --git a/cli/__tests__/app/service/stablecoin/ListMultiSigTxService.test.ts b/cli/__tests__/app/service/stablecoin/ListMultiSigTxService.test.ts new file mode 100644 index 000000000..0c1ef7e79 --- /dev/null +++ b/cli/__tests__/app/service/stablecoin/ListMultiSigTxService.test.ts @@ -0,0 +1,313 @@ +/* + * + * Hedera Stablecoin CLI + * + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { + Account, + MultiSigTransactionsViewModel, + PublicKey, + StableCoin, +} from '@hashgraph/stablecoin-npm-sdk'; +import { utilsService } from '../../../../src/index.js'; +import ListMultiSigTxService from '../../../../src/app/service/stablecoin/ListMultiSigTxService.js'; +import { Status } from '../../../../src/domain/stablecoin/MultiSigTransaction.js'; +import { AccountType } from '../../../../src/domain/configuration/interfaces/AccountType.js'; +import ListMultiSigTxResponse from '../../../../src/domain/stablecoin/ListMultiSigTxResponse.js'; +import { IAccountConfig } from '../../../../src/domain/configuration/interfaces/IAccountConfig.js'; +import PaginationRequest from '../../../../src/domain/stablecoin/PaginationRequest.js'; + +const TRANSACTIONS = [ + { + id: 'e8fe7d5e-2a94-472c-bab8-e693e4011300', + transaction_message: + '0aef022aec020a350a1a0a0c0892d5c0af0610efaedd950312080800100018c3bf0c180012080800100018c3bf0c1880c2d72f22020878320072020a0012b2020a640a20cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e1a40e120be5fa7fa085c989e69b60b6f80218d8a49751abc84456bc8bd88ba3766101b658d45ebd7e0b742382e9bd8ad98a88f03a9d6118cad42da275531e068a50b0a640a20c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e1a406cf580daa232d279badbd1bc1227531d4c98ab444a2a7ec1851af17400e01c805bf96223ad2cd7a4469f3709c0fb35b77cb217543e4741d8db92175de583cc000a640a200e3c05cf1c2a04db21d0e73f0e608d80d7043851154a4d9516e6b0ee929f7f9f1a40ff79cb99db2d5001835b7ed3c26fa8a980ee541b9a1fb1c3972a6a62dfce1bd05372fed331ee1d672dc41df5ec1c12a38104962d2fb6a80dbf12286375f59c0f', + description: 'This transaction is for the creation of a new StableCoin', + status: Status.Pending, + threshold: 2, + hedera_account_id: '0.0.123456', + key_list: [ + 'cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e', + 'c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e', + '0e3c05cf1c2a04db21d0e73f0e608d80d7043851154a4d9516e6b0ee929f7f9f', + ], + signed_keys: [], + signatures: [], + network: 'testnet', + }, + { + id: 'e8fe7d5e-2a94-472c-bab8-e693e4011301', + transaction_message: + '0aef022aec020a350a1a0a0c0892d5c0af0610efaedd950312080800100018c3bf0c180012080800100018c3bf0c1880c2d72f22020878320072020a0012b2020a640a20cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e1a40e120be5fa7fa085c989e69b60b6f80218d8a49751abc84456bc8bd88ba3766101b658d45ebd7e0b742382e9bd8ad98a88f03a9d6118cad42da275531e068a50b0a640a20c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e1a406cf580daa232d279badbd1bc1227531d4c98ab444a2a7ec1851af17400e01c805bf96223ad2cd7a4469f3709c0fb35b77cb217543e4741d8db92175de583cc000a640a200e3c05cf1c2a04db21d0e73f0e608d80d7043851154a4d9516e6b0ee929f7f9f1a40ff79cb99db2d5001835b7ed3c26fa8a980ee541b9a1fb1c3972a6a62dfce1bd05372fed331ee1d672dc41df5ec1c12a38104962d2fb6a80dbf12286375f59c0f', + description: 'This transaction is for the creation of a new StableCoin', + status: Status.Pending, + threshold: 2, + hedera_account_id: '0.0.123456', + key_list: [ + 'cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e', + 'c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e', + '0e3c05cf1c2a04db21d0e73f0e608d80d7043851154a4d9516e6b0ee929f7f9f', + ], + signed_keys: [ + 'cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e', + ], + signatures: [ + 'e120be5fa7fa085c989e69b60b6f80218d8a49751abc84456bc8bd88ba3766101b658d45ebd7e0b742382e9bd8ad98a88f03a9d6118cad42da275531e068a50b', + ], + network: 'testnet', + }, + { + id: 'e8fe7d5e-2a94-472c-bab8-e693e4011302', + transaction_message: + '0aef022aec020a350a1a0a0c0892d5c0af0610efaedd950312080800100018c3bf0c180012080800100018c3bf0c1880c2d72f22020878320072020a0012b2020a640a20cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e1a40e120be5fa7fa085c989e69b60b6f80218d8a49751abc84456bc8bd88ba3766101b658d45ebd7e0b742382e9bd8ad98a88f03a9d6118cad42da275531e068a50b0a640a20c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e1a406cf580daa232d279badbd1bc1227531d4c98ab444a2a7ec1851af17400e01c805bf96223ad2cd7a4469f3709c0fb35b77cb217543e4741d8db92175de583cc000a640a200e3c05cf1c2a04db21d0e73f0e608d80d7043851154a4d9516e6b0ee929f7f9f1a40ff79cb99db2d5001835b7ed3c26fa8a980ee541b9a1fb1c3972a6a62dfce1bd05372fed331ee1d672dc41df5ec1c12a38104962d2fb6a80dbf12286375f59c0f', + description: 'This transaction is for the creation of a new StableCoin', + status: Status.Signed, + threshold: 2, + hedera_account_id: '0.0.123456', + key_list: [ + 'cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e', + 'c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e', + '0e3c05cf1c2a04db21d0e73f0e608d80d7043851154a4d9516e6b0ee929f7f9f', + ], + signed_keys: [ + 'cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e', + 'c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e', + ], + signatures: [ + 'e120be5fa7fa085c989e69b60b6f80218d8a49751abc84456bc8bd88ba3766101b658d45ebd7e0b742382e9bd8ad98a88f03a9d6118cad42da275531e068a50b', + '6cf580daa232d279badbd1bc1227531d4c98ab444a2a7ec1851af17400e01c805bf96223ad2cd7a4469f3709c0fb35b77cb217543e4741d8db92175de583cc00', + ], + network: 'testnet', + }, + { + id: 'e8fe7d5e-2a94-472c-bab8-e693e4011303', + transaction_message: + '0aef022aec020a350a1a0a0c0892d5c0af0610efaedd950312080800100018c3bf0c180012080800100018c3bf0c1880c2d72f22020878320072020a0012b2020a640a20cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e1a40e120be5fa7fa085c989e69b60b6f80218d8a49751abc84456bc8bd88ba3766101b658d45ebd7e0b742382e9bd8ad98a88f03a9d6118cad42da275531e068a50b0a640a20c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e1a406cf580daa232d279badbd1bc1227531d4c98ab444a2a7ec1851af17400e01c805bf96223ad2cd7a4469f3709c0fb35b77cb217543e4741d8db92175de583cc000a640a200e3c05cf1c2a04db21d0e73f0e608d80d7043851154a4d9516e6b0ee929f7f9f1a40ff79cb99db2d5001835b7ed3c26fa8a980ee541b9a1fb1c3972a6a62dfce1bd05372fed331ee1d672dc41df5ec1c12a38104962d2fb6a80dbf12286375f59c0f', + description: 'This transaction is for the creation of a new StableCoin', + status: Status.Signed, + threshold: 2, + hedera_account_id: '0.0.123456', + key_list: [ + 'cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e', + 'c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e', + '0e3c05cf1c2a04db21d0e73f0e608d80d7043851154a4d9516e6b0ee929f7f9f', + ], + signed_keys: [ + 'cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e', + 'c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e', + '0e3c05cf1c2a04db21d0e73f0e608d80d7043851154a4d9516e6b0ee929f7f9f', + ], + signatures: [ + 'e120be5fa7fa085c989e69b60b6f80218d8a49751abc84456bc8bd88ba3766101b658d45ebd7e0b742382e9bd8ad98a88f03a9d6118cad42da275531e068a50b', + '6cf580daa232d279badbd1bc1227531d4c98ab444a2a7ec1851af17400e01c805bf96223ad2cd7a4469f3709c0fb35b77cb217543e4741d8db92175de583cc00', + 'ff79cb99db2d5001835b7ed3c26fa8a980ee541b9a1fb1c3972a6a62dfce1bd05372fed331ee1d672dc41df5ec1c12a38104962d2fb6a80dbf12286375f59c0f', + ], + network: 'testnet', + }, +]; +const DEFAULT_PAGE = 1; +const DEFAULT_LIMIT = 5; +const DEFAULT_ACCOUNT: IAccountConfig = { + accountId: '0.0.123456', + type: AccountType.SelfCustodial, + network: 'testnet', + alias: 'Test Account', + selfCustodial: { + privateKey: { + key: '0x0123456789abcdefABCDEF', + type: 'ed25519', + }, + }, +}; +const EXAMPLE_PUBLIC_KEY = new PublicKey('0x04123456789abcdefABCDEF'); +const mocks: Record = {}; + +describe('List Multi-Signature Transactions Service', () => { + beforeAll(() => { + // Mock all unwanted outputs + mocks.showSpinner = jest + .spyOn(utilsService, 'showSpinner') + .mockImplementation(); + mocks.log = jest.spyOn(console, 'log').mockImplementation(); + mocks.info = jest.spyOn(console, 'info').mockImplementation(); + mocks.error = jest.spyOn(console, 'error').mockImplementation(); + mocks.drawTable = jest + .spyOn(utilsService, 'drawTableListPendingMultiSig') + .mockImplementation(); + }); + afterAll(() => { + jest.resetAllMocks(); + jest.restoreAllMocks(); + }); + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('Get list', () => { + beforeAll(() => { + // Mock expected function behavior + // At any given account, return a fixed example public key + mocks.getPublicKey = jest + .spyOn(Account, 'getPublicKey') + .mockImplementation((request) => { + if (request.account.accountId.includes('0.0.')) { + return Promise.resolve(EXAMPLE_PUBLIC_KEY); + } + return undefined; + }); + // Return a fixed list of transactions based on status and pagination + mocks.getTransactions = jest + .spyOn(StableCoin, 'getTransactions') + .mockImplementation( + ({ status, page = DEFAULT_PAGE, limit = DEFAULT_LIMIT }) => { + const filteredTransactions = TRANSACTIONS.filter( + (tx) => tx.status === status, + ); + const paginatedTransactions = filteredTransactions.slice( + (page - 1) * limit, + page * limit, + ); + const totalItems = paginatedTransactions.length; + const paginationRes: MultiSigTransactionsViewModel['pagination'] = { + currentPage: page, + itemsPerPage: limit, + totalItems: totalItems, + totalPages: Math.ceil(totalItems / limit), + itemCount: paginatedTransactions.length, + }; + return Promise.resolve({ + transactions: paginatedTransactions, + pagination: paginationRes, + } as MultiSigTransactionsViewModel); + }, + ); + }); + + it('should get Tx list without parameters, from multisig account', async () => { + //* 🗂️ Arrange + const CURRENT_ACCOUNT: IAccountConfig = { + ...DEFAULT_ACCOUNT, + type: AccountType.MultiSignature, + selfCustodial: undefined, + }; + mocks.getCurrentAccount = jest + .spyOn(utilsService, 'getCurrentAccount') + .mockReturnValue(CURRENT_ACCOUNT); + //* 🎬 Act + const result = await new ListMultiSigTxService().get(); + + //* 🕵️ Assert + expect(mocks.getCurrentAccount).toHaveBeenCalledTimes(1); + expect(mocks.getPublicKey).toHaveBeenCalledTimes(0); // Account type == MultiSig + expect(mocks.getTransactions).toHaveBeenCalledTimes(1); + expect(mocks.drawTable).toHaveBeenCalledTimes(0); + expect(mocks.getTransactions).toHaveBeenCalledWith( + expect.objectContaining({ + account: CURRENT_ACCOUNT.accountId, + publicKey: undefined, + status: Status.Pending, + page: DEFAULT_PAGE, + limit: DEFAULT_LIMIT, + }), + ); + expect(result).toBeInstanceOf(ListMultiSigTxResponse); + expect(result.multiSigTxList).toHaveLength(2); + expect(result.multiSigTxList[0].status).toBe(Status.Pending); + expect(result.pagination.currentPage).toBeGreaterThan(0); + expect(result.pagination.totalItems).toBe(2); + }); + it('should get Tx list with status = signed and draw, from self-custodial', async () => { + //* 🗂️ Arrange + mocks.getCurrentAccount = jest + .spyOn(utilsService, 'getCurrentAccount') + .mockReturnValue(DEFAULT_ACCOUNT); + + //* 🎬 Act + const result = await new ListMultiSigTxService().get({ + status: Status.Signed, + draw: true, + }); + + //* 🕵️ Assert + expect(mocks.getCurrentAccount).toHaveBeenCalledTimes(1); + expect(mocks.getPublicKey).toHaveBeenCalledTimes(1); // Account type == self-custodial + expect(mocks.getTransactions).toHaveBeenCalledTimes(1); + expect(mocks.drawTable).toHaveBeenCalledTimes(1); + expect(mocks.getPublicKey).toHaveBeenCalledWith( + expect.objectContaining({ + account: { accountId: DEFAULT_ACCOUNT.accountId }, + }), + ); + expect(mocks.getTransactions).toHaveBeenCalledWith( + expect.objectContaining({ + account: undefined, + publicKey: EXAMPLE_PUBLIC_KEY, + status: Status.Signed, + page: DEFAULT_PAGE, + limit: DEFAULT_LIMIT, + }), + ); + expect(result).toBeInstanceOf(ListMultiSigTxResponse); + expect(result.multiSigTxList).toHaveLength(2); + expect(result.multiSigTxList[0].status).toBe(Status.Signed); + expect(result.pagination.currentPage).toBeGreaterThan(0); + expect(result.pagination.totalItems).toBe(2); + }); + + it('should get Tx list with custom pagination', async () => { + //* 🗂️ Arrange + const PAGINATION = new PaginationRequest({ page: 1, limit: 1 }); + mocks.getCurrentAccount = jest + .spyOn(utilsService, 'getCurrentAccount') + .mockReturnValue(DEFAULT_ACCOUNT); + + //* 🎬 Act + const result = await new ListMultiSigTxService().get({ + status: Status.Pending, + pagination: PAGINATION, + draw: false, + }); + + //* 🕵️ Assert + expect(mocks.getCurrentAccount).toHaveBeenCalledTimes(1); + expect(mocks.getPublicKey).toHaveBeenCalledTimes(1); // Account type == self-custodial + expect(mocks.getTransactions).toHaveBeenCalledTimes(1); + expect(mocks.drawTable).toHaveBeenCalledTimes(0); + expect(mocks.getPublicKey).toHaveBeenCalledWith( + expect.objectContaining({ + account: { accountId: DEFAULT_ACCOUNT.accountId }, + }), + ); + expect(mocks.getTransactions).toHaveBeenCalledWith( + expect.objectContaining({ + account: undefined, + publicKey: EXAMPLE_PUBLIC_KEY, + status: Status.Pending, + page: PAGINATION.page, + limit: PAGINATION.limit, + }), + ); + expect(result).toBeInstanceOf(ListMultiSigTxResponse); + expect(result.multiSigTxList).toHaveLength(PAGINATION.limit); + expect(result.multiSigTxList[0].status).toBe(Status.Pending); + expect(result.pagination.currentPage).toBeGreaterThan(0); + expect(result.pagination.currentPage).toBe(PAGINATION.page); + expect(result.pagination.totalItems).toBe(PAGINATION.limit); + }); + }); +}); From 0cd9f35b478f0dadfbae574635c906ccb46f920a Mon Sep 17 00:00:00 2001 From: Miguel_LZPF Date: Thu, 11 Apr 2024 13:05:36 +0200 Subject: [PATCH 3/4] feat: [cli] manage multisig tx service test (not all cases) Signed-off-by: Miguel_LZPF --- .../ManageMultiSigTxService.test.ts | 243 ++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 cli/__tests__/app/service/stablecoin/ManageMultiSigTxService.test.ts diff --git a/cli/__tests__/app/service/stablecoin/ManageMultiSigTxService.test.ts b/cli/__tests__/app/service/stablecoin/ManageMultiSigTxService.test.ts new file mode 100644 index 000000000..b51f7e300 --- /dev/null +++ b/cli/__tests__/app/service/stablecoin/ManageMultiSigTxService.test.ts @@ -0,0 +1,243 @@ +/* + * + * Hedera Stablecoin CLI + * + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { + Account, + MultiSigTransactionsViewModel, + PublicKey, +} from '@hashgraph/stablecoin-npm-sdk'; +import { + language, + utilsService, + wizardService, +} from '../../../../src/index.js'; +import ListMultiSigTxService from '../../../../src/app/service/stablecoin/ListMultiSigTxService.js'; +import { Status } from '../../../../src/domain/stablecoin/MultiSigTransaction.js'; +import ListMultiSigTxResponse from '../../../../src/domain/stablecoin/ListMultiSigTxResponse.js'; +import PaginationRequest from '../../../../src/domain/stablecoin/PaginationRequest.js'; +import ManageMultiSigTxService from '../../../../src/app/service/stablecoin/ManageMultiSigTxService.js'; + +const TRANSACTIONS = [ + { + id: 'e8fe7d5e-2a94-472c-bab8-e693e4011300', + transaction_message: + '0aef022aec020a350a1a0a0c0892d5c0af0610efaedd950312080800100018c3bf0c180012080800100018c3bf0c1880c2d72f22020878320072020a0012b2020a640a20cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e1a40e120be5fa7fa085c989e69b60b6f80218d8a49751abc84456bc8bd88ba3766101b658d45ebd7e0b742382e9bd8ad98a88f03a9d6118cad42da275531e068a50b0a640a20c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e1a406cf580daa232d279badbd1bc1227531d4c98ab444a2a7ec1851af17400e01c805bf96223ad2cd7a4469f3709c0fb35b77cb217543e4741d8db92175de583cc000a640a200e3c05cf1c2a04db21d0e73f0e608d80d7043851154a4d9516e6b0ee929f7f9f1a40ff79cb99db2d5001835b7ed3c26fa8a980ee541b9a1fb1c3972a6a62dfce1bd05372fed331ee1d672dc41df5ec1c12a38104962d2fb6a80dbf12286375f59c0f', + description: 'This transaction is for the creation of a new StableCoin', + status: Status.Pending, + threshold: 2, + hedera_account_id: '0.0.123456', + key_list: [ + 'cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e', + 'c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e', + '0e3c05cf1c2a04db21d0e73f0e608d80d7043851154a4d9516e6b0ee929f7f9f', + ], + signed_keys: [], + signatures: [], + network: 'testnet', + }, + { + id: 'e8fe7d5e-2a94-472c-bab8-e693e4011301', + transaction_message: + '0aef022aec020a350a1a0a0c0892d5c0af0610efaedd950312080800100018c3bf0c180012080800100018c3bf0c1880c2d72f22020878320072020a0012b2020a640a20cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e1a40e120be5fa7fa085c989e69b60b6f80218d8a49751abc84456bc8bd88ba3766101b658d45ebd7e0b742382e9bd8ad98a88f03a9d6118cad42da275531e068a50b0a640a20c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e1a406cf580daa232d279badbd1bc1227531d4c98ab444a2a7ec1851af17400e01c805bf96223ad2cd7a4469f3709c0fb35b77cb217543e4741d8db92175de583cc000a640a200e3c05cf1c2a04db21d0e73f0e608d80d7043851154a4d9516e6b0ee929f7f9f1a40ff79cb99db2d5001835b7ed3c26fa8a980ee541b9a1fb1c3972a6a62dfce1bd05372fed331ee1d672dc41df5ec1c12a38104962d2fb6a80dbf12286375f59c0f', + description: 'This transaction is for the creation of a new StableCoin', + status: Status.Pending, + threshold: 2, + hedera_account_id: '0.0.123456', + key_list: [ + 'cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e', + 'c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e', + '0e3c05cf1c2a04db21d0e73f0e608d80d7043851154a4d9516e6b0ee929f7f9f', + ], + signed_keys: [ + 'cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e', + ], + signatures: [ + 'e120be5fa7fa085c989e69b60b6f80218d8a49751abc84456bc8bd88ba3766101b658d45ebd7e0b742382e9bd8ad98a88f03a9d6118cad42da275531e068a50b', + ], + network: 'testnet', + }, + { + id: 'e8fe7d5e-2a94-472c-bab8-e693e4011302', + transaction_message: + '0aef022aec020a350a1a0a0c0892d5c0af0610efaedd950312080800100018c3bf0c180012080800100018c3bf0c1880c2d72f22020878320072020a0012b2020a640a20cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e1a40e120be5fa7fa085c989e69b60b6f80218d8a49751abc84456bc8bd88ba3766101b658d45ebd7e0b742382e9bd8ad98a88f03a9d6118cad42da275531e068a50b0a640a20c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e1a406cf580daa232d279badbd1bc1227531d4c98ab444a2a7ec1851af17400e01c805bf96223ad2cd7a4469f3709c0fb35b77cb217543e4741d8db92175de583cc000a640a200e3c05cf1c2a04db21d0e73f0e608d80d7043851154a4d9516e6b0ee929f7f9f1a40ff79cb99db2d5001835b7ed3c26fa8a980ee541b9a1fb1c3972a6a62dfce1bd05372fed331ee1d672dc41df5ec1c12a38104962d2fb6a80dbf12286375f59c0f', + description: 'This transaction is for the creation of a new StableCoin', + status: Status.Signed, + threshold: 2, + hedera_account_id: '0.0.123456', + key_list: [ + 'cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e', + 'c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e', + '0e3c05cf1c2a04db21d0e73f0e608d80d7043851154a4d9516e6b0ee929f7f9f', + ], + signed_keys: [ + 'cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e', + 'c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e', + ], + signatures: [ + 'e120be5fa7fa085c989e69b60b6f80218d8a49751abc84456bc8bd88ba3766101b658d45ebd7e0b742382e9bd8ad98a88f03a9d6118cad42da275531e068a50b', + '6cf580daa232d279badbd1bc1227531d4c98ab444a2a7ec1851af17400e01c805bf96223ad2cd7a4469f3709c0fb35b77cb217543e4741d8db92175de583cc00', + ], + network: 'testnet', + }, + { + id: 'e8fe7d5e-2a94-472c-bab8-e693e4011303', + transaction_message: + '0aef022aec020a350a1a0a0c0892d5c0af0610efaedd950312080800100018c3bf0c180012080800100018c3bf0c1880c2d72f22020878320072020a0012b2020a640a20cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e1a40e120be5fa7fa085c989e69b60b6f80218d8a49751abc84456bc8bd88ba3766101b658d45ebd7e0b742382e9bd8ad98a88f03a9d6118cad42da275531e068a50b0a640a20c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e1a406cf580daa232d279badbd1bc1227531d4c98ab444a2a7ec1851af17400e01c805bf96223ad2cd7a4469f3709c0fb35b77cb217543e4741d8db92175de583cc000a640a200e3c05cf1c2a04db21d0e73f0e608d80d7043851154a4d9516e6b0ee929f7f9f1a40ff79cb99db2d5001835b7ed3c26fa8a980ee541b9a1fb1c3972a6a62dfce1bd05372fed331ee1d672dc41df5ec1c12a38104962d2fb6a80dbf12286375f59c0f', + description: 'This transaction is for the creation of a new StableCoin', + status: Status.Signed, + threshold: 2, + hedera_account_id: '0.0.123456', + key_list: [ + 'cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e', + 'c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e', + '0e3c05cf1c2a04db21d0e73f0e608d80d7043851154a4d9516e6b0ee929f7f9f', + ], + signed_keys: [ + 'cf8c984270cd7cd25e1bd6df1a3a22ee2d1cd53a0f7bbfdf917a8bd881b11b5e', + 'c539f0f94cd937b721f9bd4c0b965164622798cf8ddea6169d2cb734f70baf8e', + '0e3c05cf1c2a04db21d0e73f0e608d80d7043851154a4d9516e6b0ee929f7f9f', + ], + signatures: [ + 'e120be5fa7fa085c989e69b60b6f80218d8a49751abc84456bc8bd88ba3766101b658d45ebd7e0b742382e9bd8ad98a88f03a9d6118cad42da275531e068a50b', + '6cf580daa232d279badbd1bc1227531d4c98ab444a2a7ec1851af17400e01c805bf96223ad2cd7a4469f3709c0fb35b77cb217543e4741d8db92175de583cc00', + 'ff79cb99db2d5001835b7ed3c26fa8a980ee541b9a1fb1c3972a6a62dfce1bd05372fed331ee1d672dc41df5ec1c12a38104962d2fb6a80dbf12286375f59c0f', + ], + network: 'testnet', + }, +]; +const DEFAULT_PAGE = 1; +const DEFAULT_LIMIT = 5; +const EXAMPLE_PUBLIC_KEY = new PublicKey('0x04123456789abcdefABCDEF'); +const mocks: Record = {}; + +describe('Manage Multi-Signature Transactions Service', () => { + beforeAll(() => { + // Mock all unwanted outputs + mocks.showSpinner = jest + .spyOn(utilsService, 'showSpinner') + .mockImplementation(); + mocks.log = jest.spyOn(console, 'log').mockImplementation(); + mocks.info = jest.spyOn(console, 'info').mockImplementation(); + mocks.error = jest.spyOn(console, 'error').mockImplementation(); + mocks.cleanAndShowBanner = jest + .spyOn(utilsService, 'cleanAndShowBanner') + .mockImplementation(); + mocks.mainMenu = jest.spyOn(wizardService, 'mainMenu').mockResolvedValue(); + }); + afterAll(() => { + jest.resetAllMocks(); + jest.restoreAllMocks(); + }); + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('Start', () => { + beforeAll(() => { + // Mock expected function behavior + // At any given account, return a fixed example public key + mocks.getPublicKey = jest + .spyOn(Account, 'getPublicKey') + .mockImplementation((request) => { + if (request.account.accountId.includes('0.0.')) { + return Promise.resolve(EXAMPLE_PUBLIC_KEY); + } + return undefined; + }); + // Return a fixed list of transactions based on status and pagination + mocks.getTransactions = jest + .spyOn(ListMultiSigTxService.prototype, 'get') + .mockImplementation(({ status = Status.Pending }) => { + const filteredTransactions = TRANSACTIONS.filter( + (tx) => tx.status === status, + ); + const totalItems = filteredTransactions.length; + const paginationRes: MultiSigTransactionsViewModel['pagination'] = { + totalItems, + currentPage: DEFAULT_PAGE, + itemsPerPage: DEFAULT_LIMIT, + totalPages: Math.ceil(totalItems / DEFAULT_LIMIT), + itemCount: totalItems, + }; + return Promise.resolve( + ListMultiSigTxResponse.fromRawMultiSigTxList({ + multiSigTxListRaw: filteredTransactions, + paginationResRaw: paginationRes, + }), + ); + }); + mocks.multiSigTxActions = jest + .spyOn(ManageMultiSigTxService.prototype, 'multiSigTxActions') + .mockResolvedValue(); + }); + + it('should start without parameters', async () => { + //* 🗂️ Arrange + const expectedOptions = [ + ...TRANSACTIONS.map((tx) => { + return tx.status === Status.Pending ? tx.id : undefined; + }), + ]; + const expectedMultiSigTx = TRANSACTIONS.find( + (tx) => tx.id === expectedOptions[0], + ); + mocks.defaultMultipleAsk = jest + .spyOn(utilsService, 'defaultMultipleAsk') + .mockResolvedValue(expectedOptions[0]); // default switch case + //* 🎬 Act + await new ManageMultiSigTxService().start(); + + //* 🕵️ Assert + expect(mocks.cleanAndShowBanner).toHaveBeenCalledTimes(1); + expect(mocks.getTransactions).toHaveBeenCalledTimes(1); + expect(mocks.defaultMultipleAsk).toHaveBeenCalledTimes(1); + expect(mocks.multiSigTxActions).toHaveBeenCalledTimes(1); + expect(mocks.getTransactions).toHaveBeenCalledWith( + expect.objectContaining({ + status: undefined, + draw: true, + pagination: new PaginationRequest(), + }), + ); + expect(mocks.defaultMultipleAsk).toHaveBeenCalledWith( + language.getText('wizard.multiSig.listMenuTitle'), + expectedOptions, + true, + ); + expect(mocks.multiSigTxActions).toHaveBeenCalledWith( + expect.objectContaining({ + multiSigTx: { + description: expectedMultiSigTx.description, + hederaAccountId: expectedMultiSigTx.hedera_account_id, + id: expectedMultiSigTx.id, + keyList: expectedMultiSigTx.key_list, + message: expectedMultiSigTx.transaction_message, + signatures: expectedMultiSigTx.signatures, + signedKeys: expectedMultiSigTx.signed_keys, + status: expectedMultiSigTx.status, + threshold: expectedMultiSigTx.threshold, + }, + publicKey: undefined, + }), + ); + }); + // TODO: add more test cases + }); +}); From 041a942fb86dace204fdc64a240a40d3ce2e0184 Mon Sep 17 00:00:00 2001 From: Miguel_LZPF Date: Thu, 11 Apr 2024 14:11:44 +0200 Subject: [PATCH 4/4] fix: [cli] remove consoles and other unwanted logs from tests Signed-off-by: Miguel_LZPF --- .../configuration/ConfigurationService.test.ts | 8 ++++++++ .../configuration/SetConfigurationService.test.ts | 14 +++++++++----- .../configuration/SetFactoryService.test.ts | 9 +++++++-- .../configuration/SetMirrorNodeService.test.ts | 9 +++++++-- .../service/configuration/SetRPCService.test.ts | 9 +++++++-- .../ImplementationFactoryProxyService.test.ts | 6 ++++++ .../factoryProxy/OwnerFactoryProxyService.test.ts | 6 ++++++ .../proxy/ImplementationProxyService.test.ts | 6 ++++++ .../app/service/proxy/OwnerFactoryService.test.ts | 6 ++++++ .../stablecoin/AssociateStableCoinService.test.ts | 6 ++++++ .../stablecoin/BalanceOfStableCoinService.test.ts | 6 ++++++ .../stablecoin/BurnStableCoinService.test.ts | 7 ++++++- .../stablecoin/CashInStableCoinService.test.ts | 7 ++++++- .../stablecoin/DeleteStableCoinService.test.ts | 7 ++++++- .../stablecoin/DetailsStableCoinService.test.ts | 6 ++++++ .../stablecoin/FeeStableCoinService.test.ts | 7 ++++++- .../stablecoin/FreezeStableCoinService.test.ts | 9 +++++++-- .../stablecoin/KYCStableCoinService.test.ts | 9 +++++++-- .../stablecoin/ListStableCoinService.test.ts | 6 ++++++ .../stablecoin/OperationStableCoinService.test.ts | 7 ++++++- .../stablecoin/RoleStableCoinService.test.ts | 7 ++++++- 21 files changed, 136 insertions(+), 21 deletions(-) diff --git a/cli/__tests__/app/service/configuration/ConfigurationService.test.ts b/cli/__tests__/app/service/configuration/ConfigurationService.test.ts index eecad2fec..313e01855 100644 --- a/cli/__tests__/app/service/configuration/ConfigurationService.test.ts +++ b/cli/__tests__/app/service/configuration/ConfigurationService.test.ts @@ -144,6 +144,14 @@ describe('configurationService', () => { ], }; + beforeAll(() => { + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); + }); + it('should init configuration with no initial configuration or a file path', async () => { const defaultSingleAskMock = jest .spyOn(utilsService, 'defaultSingleAsk') diff --git a/cli/__tests__/app/service/configuration/SetConfigurationService.test.ts b/cli/__tests__/app/service/configuration/SetConfigurationService.test.ts index 1ba479712..34df07532 100644 --- a/cli/__tests__/app/service/configuration/SetConfigurationService.test.ts +++ b/cli/__tests__/app/service/configuration/SetConfigurationService.test.ts @@ -101,7 +101,12 @@ describe('setConfigurationService', () => { .spyOn(configurationService, 'getConfiguration') .mockReturnValue(configurationMock); jest.spyOn(utilsService, 'showSpinner').mockImplementation(); - jest.spyOn(console, 'log'); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); }); it('should init configuration with no file path nor network', async () => { @@ -128,18 +133,16 @@ describe('setConfigurationService', () => { switch (question) { case language.getText('configuration.askCreateConfig'): return Promise.resolve(true); - case language.getText('configuration.askMoreAccounts'): return Promise.resolve(false); - case language.getText('configuration.askConfigurateFactories'): return Promise.resolve(false); - case language.getText( 'configuration.askConfigurateDefaultMirrorsAndRPCs', ): return Promise.resolve(true); - + case language.getText('configuration.askConfigurateBackend'): + return Promise.resolve(false); default: return Promise.resolve(false); } @@ -148,6 +151,7 @@ describe('setConfigurationService', () => { const defaultMultipleAskMock = jest .spyOn(utilsService, 'defaultMultipleAsk') .mockImplementationOnce(() => Promise.resolve('testnet')) + // .mockImplementationOnce(() => Promise.resolve('SELF-CUSTODIAL')) .mockImplementationOnce(() => Promise.resolve('ED25519')) .mockImplementationOnce(() => Promise.resolve('ED25519')) .mockImplementationOnce(() => Promise.resolve('testnet')); diff --git a/cli/__tests__/app/service/configuration/SetFactoryService.test.ts b/cli/__tests__/app/service/configuration/SetFactoryService.test.ts index b52eb825a..7d53fa533 100644 --- a/cli/__tests__/app/service/configuration/SetFactoryService.test.ts +++ b/cli/__tests__/app/service/configuration/SetFactoryService.test.ts @@ -46,9 +46,14 @@ fs.openSync(configFilePath, 'w'); describe('setFactoryService', () => { beforeEach(() => { jest.spyOn(utilsService, 'showSpinner').mockImplementation(); - // mocks - jest.spyOn(console, 'log'); + jest.spyOn(utilsService, 'showSpinner').mockImplementation(); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); jest .spyOn(configurationService, 'getDefaultConfigurationPath') diff --git a/cli/__tests__/app/service/configuration/SetMirrorNodeService.test.ts b/cli/__tests__/app/service/configuration/SetMirrorNodeService.test.ts index ee21a4319..dc66da59f 100644 --- a/cli/__tests__/app/service/configuration/SetMirrorNodeService.test.ts +++ b/cli/__tests__/app/service/configuration/SetMirrorNodeService.test.ts @@ -99,11 +99,16 @@ describe('setMirrorNodeService', () => { }; beforeAll(() => { - jest.spyOn(utilsService, 'showSpinner').mockImplementation(); jest .spyOn(configurationService, 'getDefaultConfigurationPath') .mockReturnValue(configFilePath); - jest.spyOn(console, 'log'); + jest.spyOn(utilsService, 'showSpinner').mockImplementation(); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); }); it('should configure mirror node', async () => { diff --git a/cli/__tests__/app/service/configuration/SetRPCService.test.ts b/cli/__tests__/app/service/configuration/SetRPCService.test.ts index c52900cf5..5ad2059af 100644 --- a/cli/__tests__/app/service/configuration/SetRPCService.test.ts +++ b/cli/__tests__/app/service/configuration/SetRPCService.test.ts @@ -99,11 +99,16 @@ describe('setRPCNodeService', () => { }; beforeAll(() => { - jest.spyOn(utilsService, 'showSpinner').mockImplementation(); jest .spyOn(configurationService, 'getDefaultConfigurationPath') .mockReturnValue(configFilePath); - jest.spyOn(console, 'log'); + jest.spyOn(utilsService, 'showSpinner').mockImplementation(); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); }); it('should configure rpc service', async () => { diff --git a/cli/__tests__/app/service/factoryProxy/ImplementationFactoryProxyService.test.ts b/cli/__tests__/app/service/factoryProxy/ImplementationFactoryProxyService.test.ts index 49c946d56..042f359ea 100644 --- a/cli/__tests__/app/service/factoryProxy/ImplementationFactoryProxyService.test.ts +++ b/cli/__tests__/app/service/factoryProxy/ImplementationFactoryProxyService.test.ts @@ -31,6 +31,12 @@ const language: Language = new Language(); describe('implementationFactoryProxyService', () => { beforeEach(() => { jest.spyOn(utilsService, 'showSpinner').mockImplementation(); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); }); afterEach(() => { jest.restoreAllMocks(); diff --git a/cli/__tests__/app/service/factoryProxy/OwnerFactoryProxyService.test.ts b/cli/__tests__/app/service/factoryProxy/OwnerFactoryProxyService.test.ts index 5f7fd78db..76f8450eb 100644 --- a/cli/__tests__/app/service/factoryProxy/OwnerFactoryProxyService.test.ts +++ b/cli/__tests__/app/service/factoryProxy/OwnerFactoryProxyService.test.ts @@ -31,6 +31,12 @@ const language: Language = new Language(); describe('ownerFactoryProxyService', () => { beforeEach(() => { jest.spyOn(utilsService, 'showSpinner').mockImplementation(); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); }); afterEach(() => { jest.restoreAllMocks(); diff --git a/cli/__tests__/app/service/proxy/ImplementationProxyService.test.ts b/cli/__tests__/app/service/proxy/ImplementationProxyService.test.ts index 8ca3a2d22..7b17393ac 100644 --- a/cli/__tests__/app/service/proxy/ImplementationProxyService.test.ts +++ b/cli/__tests__/app/service/proxy/ImplementationProxyService.test.ts @@ -34,6 +34,12 @@ const language: Language = new Language(); describe('implementationProxyService', () => { beforeEach(() => { jest.spyOn(utilsService, 'showSpinner').mockImplementation(); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); }); afterEach(() => { jest.restoreAllMocks(); diff --git a/cli/__tests__/app/service/proxy/OwnerFactoryService.test.ts b/cli/__tests__/app/service/proxy/OwnerFactoryService.test.ts index 68e2f5bb8..488cf07c9 100644 --- a/cli/__tests__/app/service/proxy/OwnerFactoryService.test.ts +++ b/cli/__tests__/app/service/proxy/OwnerFactoryService.test.ts @@ -28,6 +28,12 @@ const language: Language = new Language(); describe('changeProxyOwner', () => { beforeEach(() => { jest.spyOn(utilsService, 'showSpinner').mockImplementation(); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); }); afterEach(() => { jest.restoreAllMocks(); diff --git a/cli/__tests__/app/service/stablecoin/AssociateStableCoinService.test.ts b/cli/__tests__/app/service/stablecoin/AssociateStableCoinService.test.ts index 308e99479..1fe168faa 100644 --- a/cli/__tests__/app/service/stablecoin/AssociateStableCoinService.test.ts +++ b/cli/__tests__/app/service/stablecoin/AssociateStableCoinService.test.ts @@ -27,6 +27,12 @@ const service = new AssociateStableCoinService(); describe(`Testing AssociateStableCoinService class`, () => { beforeEach(() => { jest.spyOn(utilsService, 'showSpinner').mockImplementation(); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); jest.spyOn(StableCoin, 'associate').mockImplementation(); }); afterEach(() => { diff --git a/cli/__tests__/app/service/stablecoin/BalanceOfStableCoinService.test.ts b/cli/__tests__/app/service/stablecoin/BalanceOfStableCoinService.test.ts index d6875b163..a66ba95a9 100644 --- a/cli/__tests__/app/service/stablecoin/BalanceOfStableCoinService.test.ts +++ b/cli/__tests__/app/service/stablecoin/BalanceOfStableCoinService.test.ts @@ -36,6 +36,12 @@ const request = new GetAccountBalanceRequest({ describe(`Testing BalanceOfStableCoinService class`, () => { beforeEach(() => { jest.spyOn(utilsService, 'showSpinner').mockImplementation(); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); jest .spyOn(StableCoin, 'getBalanceOf') .mockResolvedValue(new Balance(new BigDecimal('10'))); diff --git a/cli/__tests__/app/service/stablecoin/BurnStableCoinService.test.ts b/cli/__tests__/app/service/stablecoin/BurnStableCoinService.test.ts index 0f3502b8d..b6344dd87 100644 --- a/cli/__tests__/app/service/stablecoin/BurnStableCoinService.test.ts +++ b/cli/__tests__/app/service/stablecoin/BurnStableCoinService.test.ts @@ -33,8 +33,13 @@ const request = new BurnRequest({ describe(`Testing BurnStableCoinService class`, () => { beforeEach(() => { jest.spyOn(utilsService, 'showSpinner').mockImplementation(); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); jest.spyOn(StableCoin, 'burn').mockImplementation(); - jest.spyOn(console, 'log'); }); afterEach(() => { jest.restoreAllMocks(); diff --git a/cli/__tests__/app/service/stablecoin/CashInStableCoinService.test.ts b/cli/__tests__/app/service/stablecoin/CashInStableCoinService.test.ts index fc0115c22..c9d00bcaf 100644 --- a/cli/__tests__/app/service/stablecoin/CashInStableCoinService.test.ts +++ b/cli/__tests__/app/service/stablecoin/CashInStableCoinService.test.ts @@ -34,8 +34,13 @@ const request = new CashInRequest({ describe(`Testing CashInStableCoinService class`, () => { beforeEach(() => { jest.spyOn(utilsService, 'showSpinner').mockImplementation(); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); jest.spyOn(StableCoin, 'cashIn').mockImplementation(); - jest.spyOn(console, 'log'); }); afterEach(() => { jest.restoreAllMocks(); diff --git a/cli/__tests__/app/service/stablecoin/DeleteStableCoinService.test.ts b/cli/__tests__/app/service/stablecoin/DeleteStableCoinService.test.ts index c665d7bb0..c51a0faa1 100644 --- a/cli/__tests__/app/service/stablecoin/DeleteStableCoinService.test.ts +++ b/cli/__tests__/app/service/stablecoin/DeleteStableCoinService.test.ts @@ -30,8 +30,13 @@ const request = new DeleteRequest({ tokenId: '' }); describe(`Testing DeleteStableCoinService class`, () => { beforeEach(() => { jest.spyOn(utilsService, 'showSpinner').mockImplementation(); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); jest.spyOn(StableCoin, 'delete').mockImplementation(); - jest.spyOn(console, 'log'); }); afterEach(() => { jest.restoreAllMocks(); diff --git a/cli/__tests__/app/service/stablecoin/DetailsStableCoinService.test.ts b/cli/__tests__/app/service/stablecoin/DetailsStableCoinService.test.ts index 9e444f753..fc8b7146c 100644 --- a/cli/__tests__/app/service/stablecoin/DetailsStableCoinService.test.ts +++ b/cli/__tests__/app/service/stablecoin/DetailsStableCoinService.test.ts @@ -76,6 +76,12 @@ const mockedSelectedStableCoin = { describe(`Testing DetailsStableCoinService class`, () => { beforeEach(() => { jest.spyOn(utilsService, 'showSpinner').mockImplementation(); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); jest .spyOn(StableCoin, 'getInfo') .mockResolvedValue(mockedSelectedStableCoin); diff --git a/cli/__tests__/app/service/stablecoin/FeeStableCoinService.test.ts b/cli/__tests__/app/service/stablecoin/FeeStableCoinService.test.ts index 1758510c3..e6cdda6bf 100644 --- a/cli/__tests__/app/service/stablecoin/FeeStableCoinService.test.ts +++ b/cli/__tests__/app/service/stablecoin/FeeStableCoinService.test.ts @@ -36,7 +36,12 @@ const language: Language = new Language(); describe(`Testing FeeStableCoinService class`, () => { beforeEach(() => { jest.spyOn(utilsService, 'showSpinner').mockImplementation(); - jest.spyOn(console, 'log'); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); }); afterEach(() => { jest.restoreAllMocks(); diff --git a/cli/__tests__/app/service/stablecoin/FreezeStableCoinService.test.ts b/cli/__tests__/app/service/stablecoin/FreezeStableCoinService.test.ts index be93442fd..00745ce85 100644 --- a/cli/__tests__/app/service/stablecoin/FreezeStableCoinService.test.ts +++ b/cli/__tests__/app/service/stablecoin/FreezeStableCoinService.test.ts @@ -36,10 +36,15 @@ const request = new FreezeAccountRequest({ describe(`Testing FreezeStableCoinService class`, () => { beforeEach(() => { - jest.spyOn(utilsService, 'showSpinner').mockImplementation(); jest.spyOn(StableCoin, 'freeze').mockImplementation(); jest.spyOn(StableCoin, 'unFreeze').mockImplementation(); - jest.spyOn(console, 'log'); + jest.spyOn(utilsService, 'showSpinner').mockImplementation(); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); }); afterEach(() => { jest.restoreAllMocks(); diff --git a/cli/__tests__/app/service/stablecoin/KYCStableCoinService.test.ts b/cli/__tests__/app/service/stablecoin/KYCStableCoinService.test.ts index f3f8faff7..a012a15fc 100644 --- a/cli/__tests__/app/service/stablecoin/KYCStableCoinService.test.ts +++ b/cli/__tests__/app/service/stablecoin/KYCStableCoinService.test.ts @@ -33,10 +33,15 @@ const request = new KYCRequest({ describe(`Testing KYCStableCoinService class`, () => { beforeEach(() => { - jest.spyOn(utilsService, 'showSpinner').mockImplementation(); jest.spyOn(StableCoin, 'grantKyc').mockImplementation(); jest.spyOn(StableCoin, 'revokeKyc').mockImplementation(); - jest.spyOn(console, 'log'); + jest.spyOn(utilsService, 'showSpinner').mockImplementation(); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); }); afterEach(() => { jest.restoreAllMocks(); diff --git a/cli/__tests__/app/service/stablecoin/ListStableCoinService.test.ts b/cli/__tests__/app/service/stablecoin/ListStableCoinService.test.ts index 652c18ce6..839ff8f84 100644 --- a/cli/__tests__/app/service/stablecoin/ListStableCoinService.test.ts +++ b/cli/__tests__/app/service/stablecoin/ListStableCoinService.test.ts @@ -48,6 +48,12 @@ const listStableCoins = { describe(`Testing ListStableCoinService class`, () => { beforeEach(() => { jest.spyOn(utilsService, 'showSpinner').mockImplementation(); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); jest .spyOn(utilsService, 'getCurrentAccount') .mockReturnValue(currentAccount); diff --git a/cli/__tests__/app/service/stablecoin/OperationStableCoinService.test.ts b/cli/__tests__/app/service/stablecoin/OperationStableCoinService.test.ts index 6b7e5fafe..f1edfea09 100644 --- a/cli/__tests__/app/service/stablecoin/OperationStableCoinService.test.ts +++ b/cli/__tests__/app/service/stablecoin/OperationStableCoinService.test.ts @@ -143,6 +143,12 @@ const roles = [ describe(`Testing OperationStableCoinService class`, () => { beforeEach(() => { jest.spyOn(utilsService, 'showSpinner').mockImplementation(); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); jest.spyOn(utilsService, 'cleanAndShowBanner').mockImplementation(); jest .spyOn(utilsService, 'getCurrentAccount') @@ -170,7 +176,6 @@ describe(`Testing OperationStableCoinService class`, () => { .mockResolvedValue(roles); jest.spyOn(utilsService, 'displayCurrentUserInfo').mockImplementation(); jest.spyOn(wizardService, 'mainMenu').mockImplementation(); - jest.spyOn(console, 'log').mockImplementation(); const keep = (OperationStableCoinService.prototype as any) .operationsStableCoin; diff --git a/cli/__tests__/app/service/stablecoin/RoleStableCoinService.test.ts b/cli/__tests__/app/service/stablecoin/RoleStableCoinService.test.ts index 3119c0ddd..ff2091919 100644 --- a/cli/__tests__/app/service/stablecoin/RoleStableCoinService.test.ts +++ b/cli/__tests__/app/service/stablecoin/RoleStableCoinService.test.ts @@ -48,7 +48,12 @@ const language: Language = new Language(); describe(`Testing RoleStableCoinService class`, () => { beforeEach(() => { jest.spyOn(utilsService, 'showSpinner').mockImplementation(); - jest.spyOn(console, 'log'); + jest.spyOn(utilsService, 'showMessage').mockImplementation(); + jest.spyOn(console, 'log').mockImplementation(); + jest.spyOn(console, 'info').mockImplementation(); + jest.spyOn(console, 'warn').mockImplementation(); + jest.spyOn(console, 'error').mockImplementation(); + jest.spyOn(console, 'dir').mockImplementation(); }); afterEach(() => { jest.restoreAllMocks();