From a93ab5191079534d2abbd1c9901702dee4b257dd Mon Sep 17 00:00:00 2001 From: alter-eggo Date: Mon, 26 Feb 2024 15:05:07 +0400 Subject: [PATCH] feat: add prevent tx test --- .../components/broadcast-error.layout.tsx | 8 +++- .../form/btc/btc-send-form-confirmation.tsx | 8 +++- .../bitcoin/transaction/use-check-utxos.ts | 3 +- tests/mocks/mock-ordinalscom-api.ts | 46 +++++++++++++++++++ tests/page-object-models/send.page.ts | 8 ++++ tests/selectors/shared-component.selectors.ts | 4 ++ tests/specs/send/send-btc.spec.ts | 22 +++++++++ 7 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 tests/mocks/mock-ordinalscom-api.ts diff --git a/src/app/pages/send/broadcast-error/components/broadcast-error.layout.tsx b/src/app/pages/send/broadcast-error/components/broadcast-error.layout.tsx index c96c7ed2370..cd9ca5e268e 100644 --- a/src/app/pages/send/broadcast-error/components/broadcast-error.layout.tsx +++ b/src/app/pages/send/broadcast-error/components/broadcast-error.layout.tsx @@ -1,6 +1,7 @@ import { ReactNode } from 'react'; import BroadcastError from '@assets/images/unhappy-face-ui.png'; +import { SharedComponentsSelectors } from '@tests/selectors/shared-component.selectors'; import { Box, Flex, FlexProps, styled } from 'leather-styles/jsx'; interface BroadcastErrorProps extends FlexProps { @@ -23,7 +24,12 @@ export function BroadcastErrorLayout(props: BroadcastErrorProps) { Unhappy user interface cloud - + {title} diff --git a/src/app/pages/send/send-crypto-asset-form/form/btc/btc-send-form-confirmation.tsx b/src/app/pages/send/send-crypto-asset-form/form/btc/btc-send-form-confirmation.tsx index 5511df43143..edce751584e 100644 --- a/src/app/pages/send/send-crypto-asset-form/form/btc/btc-send-form-confirmation.tsx +++ b/src/app/pages/send/send-crypto-asset-form/form/btc/btc-send-form-confirmation.tsx @@ -3,6 +3,7 @@ import { useLocation, useNavigate } from 'react-router-dom'; import { hexToBytes } from '@noble/hashes/utils'; import * as btc from '@scure/btc-signer'; import { SendCryptoAssetSelectors } from '@tests/selectors/send.selectors'; +import { SharedComponentsSelectors } from '@tests/selectors/shared-component.selectors'; import { Stack } from 'leather-styles/jsx'; import get from 'lodash.get'; @@ -157,7 +158,12 @@ export function BtcSendFormConfirmation() { - diff --git a/src/app/query/bitcoin/transaction/use-check-utxos.ts b/src/app/query/bitcoin/transaction/use-check-utxos.ts index 2e0ec64deaa..50721d88235 100644 --- a/src/app/query/bitcoin/transaction/use-check-utxos.ts +++ b/src/app/query/bitcoin/transaction/use-check-utxos.ts @@ -3,6 +3,7 @@ import { useCallback, useState } from 'react'; import * as btc from '@scure/btc-signer'; import { bytesToHex } from '@stacks/common'; +import { IS_TEST_ENV } from '@shared/environment'; import { isUndefined } from '@shared/utils'; import { useAnalytics } from '@app/common/hooks/analytics/use-analytics'; @@ -100,7 +101,7 @@ export function useCheckInscribedUtxos(blockTxAction?: () => void) { try { // no need to check for inscriptions on testnet - if (isTestnet) { + if (isTestnet && !IS_TEST_ENV) { return false; } diff --git a/tests/mocks/mock-ordinalscom-api.ts b/tests/mocks/mock-ordinalscom-api.ts new file mode 100644 index 00000000000..1703e8c39bf --- /dev/null +++ b/tests/mocks/mock-ordinalscom-api.ts @@ -0,0 +1,46 @@ +export const mockOrdinalsComApiHtmlResponse = ` + + + + + + + + + + Output b4c94b7270d8b97c5dc9ecc73176ee7d93e96135b60dfef1b601d661bfd7884b:0 + + + + + + +
+ +
+
+

Output b4c94b7270d8b97c5dc9ecc73176ee7d93e96135b60dfef1b601d661bfd7884b:0

+
+
inscriptions
+
+ +
+
value
1461
+
script pubkey
OP_0 OP_PUSHBYTES_20 20d6ea31e3b6c8b43d1c8d52fd24c1226caa9bd2
+
address
bc1qyrtw5v0rkmytg0gu34f06fxpyfk24x7jevtvx3
+
transaction
b4c94b7270d8b97c5dc9ecc73176ee7d93e96135b60dfef1b601d661bfd7884b
+
+
+ + +`; diff --git a/tests/page-object-models/send.page.ts b/tests/page-object-models/send.page.ts index 8e1a631853f..18030bb1bac 100644 --- a/tests/page-object-models/send.page.ts +++ b/tests/page-object-models/send.page.ts @@ -25,6 +25,8 @@ export class SendPage { readonly memoRow: Locator; readonly feesListItem: Locator; readonly feeToBePaid: Locator; + readonly infoCardButton: Locator; + readonly broadcastErrorTitle: Locator; constructor(page: Page) { this.page = page; @@ -58,6 +60,8 @@ export class SendPage { this.sendMaxButton = page.getByTestId(SendCryptoAssetSelectors.SendMaxBtn); this.feesListItem = page.getByTestId(SharedComponentsSelectors.FeesListItem); this.feeToBePaid = page.getByTestId(SharedComponentsSelectors.FeeToBePaidLabel); + this.infoCardButton = page.getByTestId(SharedComponentsSelectors.InfoCardButton); + this.broadcastErrorTitle = page.getByTestId(SharedComponentsSelectors.BroadcastErrorTitle); } async selectBtcAndGoToSendForm() { @@ -92,4 +96,8 @@ export class SendPage { await this.goBack(); await this.selectStxAndGoToSendForm(); } + + async clickInfoCardButton() { + await this.infoCardButton.click(); + } } diff --git a/tests/selectors/shared-component.selectors.ts b/tests/selectors/shared-component.selectors.ts index c86460c1ba0..1090a4c75f1 100644 --- a/tests/selectors/shared-component.selectors.ts +++ b/tests/selectors/shared-component.selectors.ts @@ -6,6 +6,7 @@ export enum SharedComponentsSelectors { // InfoCard InfoCardAssetValue = 'info-card-asset-value', InfoCardRowValue = 'info-card-row-value', + InfoCardButton = 'info-card-button', // Fees FeeRow = 'fee-row', @@ -20,4 +21,7 @@ export enum SharedComponentsSelectors { // Modal Header ModalHeaderBackBtn = 'modal-header-back-button', + + // Error + BroadcastErrorTitle = 'broadcast-error-title', } diff --git a/tests/specs/send/send-btc.spec.ts b/tests/specs/send/send-btc.spec.ts index 54b3915fdc8..15bba8f9a5e 100644 --- a/tests/specs/send/send-btc.spec.ts +++ b/tests/specs/send/send-btc.spec.ts @@ -1,4 +1,5 @@ import { TEST_TESTNET_ACCOUNT_2_BTC_ADDRESS } from '@tests/mocks/constants'; +import { mockOrdinalsComApiHtmlResponse } from '@tests/mocks/mock-ordinalscom-api'; import { SendCryptoAssetSelectors } from '@tests/selectors/send.selectors'; import { SharedComponentsSelectors } from '@tests/selectors/shared-component.selectors'; import { getDisplayerAddress } from '@tests/utils'; @@ -82,5 +83,26 @@ test.describe('send btc', () => { test.expect(fee).toContain(confirmationFee); }); + + test('that prevents transaction if it contains inscribed utxo', async ({ sendPage }) => { + await sendPage.page.route('**/ordinals-explorer.generative.xyz/**', async route => { + return route.fulfill({ + status: 200, + contentType: 'text/html', + body: mockOrdinalsComApiHtmlResponse, + }); + }); + await sendPage.amountInput.fill('0.00006'); + await sendPage.recipientInput.fill(TEST_TESTNET_ACCOUNT_2_BTC_ADDRESS); + + await sendPage.previewSendTxButton.click(); + await sendPage.feesListItem.filter({ hasText: BtcFeeType.High }).click(); + + await sendPage.clickInfoCardButton(); + + const isErrorPageVisible = await sendPage.broadcastErrorTitle.isVisible(); + + test.expect(isErrorPageVisible).toBeTruthy(); + }); }); });