Skip to content

Commit

Permalink
add scaling for MPTAmount
Browse files Browse the repository at this point in the history
  • Loading branch information
shawnxie999 committed Sep 3, 2024
1 parent afdfb2f commit d81784d
Show file tree
Hide file tree
Showing 14 changed files with 206 additions and 56 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import { mount } from 'enzyme'
import { I18nextProvider } from 'react-i18next'
import { MemoryRouter } from 'react-router'
import { QueryClientProvider } from 'react-query'
import i18n from '../../../../../../i18n/testConfig'
import { AMMAccountHeader, AmmDataType } from '../AMMAccountHeader'
import { flushPromises } from '../../../../../test/utils'
import { queryClient } from '../../../../../shared/QueryClient'

describe('AMM Account Header', () => {
const TEST_ACCOUNT_ID = 'rTEST_ACCOUNT'

const createWrapper = (state: AmmDataType) =>
mount(
<I18nextProvider i18n={i18n}>
<MemoryRouter initialEntries={[`accounts/${TEST_ACCOUNT_ID}`]}>
<AMMAccountHeader data={state} />
</MemoryRouter>
</I18nextProvider>,
<QueryClientProvider client={queryClient}>
<I18nextProvider i18n={i18n}>
<MemoryRouter initialEntries={[`accounts/${TEST_ACCOUNT_ID}`]}>
<AMMAccountHeader data={state} />
</MemoryRouter>
</I18nextProvider>
</QueryClientProvider>,
)

it('renders AMM account page', async () => {
Expand Down
9 changes: 5 additions & 4 deletions src/containers/Amendment/Votes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,11 @@ export const Votes = ({ data, validators }: VotesProps) => {

const getYeas = () =>
validators
.filter((validator) =>
data.voted?.validators.some(
(voted) => voted.signing_key === validator.signing_key,
),
.filter(
(validator) =>
data.voted?.validators.some(
(voted) => voted.signing_key === validator.signing_key,
),
)
.sort(compareValidators)

Expand Down
10 changes: 7 additions & 3 deletions src/containers/Transactions/test/Description.test.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import { mount } from 'enzyme'
import { BrowserRouter as Router } from 'react-router-dom'
import { I18nextProvider } from 'react-i18next'
import { QueryClientProvider } from 'react-query'
import i18n from '../../../i18n/testConfigEnglish'
import { TransactionDescription } from '../DetailTab/Description'
import Transaction from './mock_data/Transaction.json'
import OfferCreateTicket from './mock_data/OfferCreateTicket.json'
import EmittedPayment from './mock_data/EmittedPayment.json'
import { queryClient } from '../../shared/QueryClient'

describe('Description container', () => {
const createWrapper = (data = {}) =>
mount(
<Router>
<I18nextProvider i18n={i18n}>
<TransactionDescription data={data} />
</I18nextProvider>
<QueryClientProvider client={queryClient}>
<I18nextProvider i18n={i18n}>
<TransactionDescription data={data} />
</I18nextProvider>
</QueryClientProvider>
</Router>,
)

Expand Down
10 changes: 7 additions & 3 deletions src/containers/Transactions/test/DetailTab.test.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import { mount } from 'enzyme'
import { BrowserRouter as Router } from 'react-router-dom'
import { I18nextProvider } from 'react-i18next'
import { QueryClientProvider } from 'react-query'
import Transaction from '../../shared/components/Transaction/EscrowCreate/test/mock_data/EscrowCreate.json'
import FailedTransaction from '../../shared/components/Transaction/SignerListSet/test/mock_data/SignerListSet.json'
import HookPayment from './mock_data/HookPayment.json'
import EmittedPayment from './mock_data/EmittedPayment.json'
import { DetailTab } from '../DetailTab'
import i18n from '../../../i18n/testConfigEnglish'
import { convertHexToString } from '../../../rippled/lib/utils'
import { queryClient } from '../../shared/QueryClient'

describe('DetailTab container', () => {
const createWrapper = (transaction: any = Transaction) =>
mount(
<Router>
<I18nextProvider i18n={i18n}>
<DetailTab data={transaction} />
</I18nextProvider>
<QueryClientProvider client={queryClient}>
<I18nextProvider i18n={i18n}>
<DetailTab data={transaction} />
</I18nextProvider>
</QueryClientProvider>
</Router>,
)

Expand Down
16 changes: 10 additions & 6 deletions src/containers/Transactions/test/SimpleTab.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,27 @@ import { mount } from 'enzyme'
import { I18nextProvider } from 'react-i18next'
import { BrowserRouter as Router } from 'react-router-dom'

import { QueryClientProvider } from 'react-query'
import EnableAmendment from './mock_data/EnableAmendment.json'
import Payment from '../../shared/components/Transaction/Payment/test/mock_data/Payment.json'
import { SimpleTab } from '../SimpleTab'
import summarize from '../../../rippled/lib/txSummary'
import i18n from '../../../i18n/testConfig'
import { expectSimpleRowText } from '../../shared/components/Transaction/test'
import { queryClient } from '../../shared/QueryClient'

describe('SimpleTab container', () => {
const createWrapper = (tx, width = 1200) =>
mount(
<Router>
<I18nextProvider i18n={i18n}>
<SimpleTab
data={{ processed: tx, summary: summarize(tx, true).details }}
width={width}
/>
</I18nextProvider>
<QueryClientProvider client={queryClient}>
<I18nextProvider i18n={i18n}>
<SimpleTab
data={{ processed: tx, summary: summarize(tx, true).details }}
width={width}
/>
</I18nextProvider>
</QueryClientProvider>
</Router>,
)

Expand Down
49 changes: 42 additions & 7 deletions src/containers/shared/components/Amount.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { useQuery } from 'react-query'
import { useContext } from 'react'
import { CURRENCY_OPTIONS, XRP_BASE } from '../transactionUtils'
import { useLanguage } from '../hooks'
import { localizeNumber } from '../utils'
import { localizeNumber, localizeMPTNumber } from '../utils'
import Currency from './Currency'
import { ExplorerAmount } from '../types'
import { MPTIssuanceFormattedInfo } from '../Interfaces'
import { getMPTIssuance } from '../../../rippled/lib/rippled'
import { formatMPTIssuanceInfo } from '../../../rippled/lib/utils'
import SocketContext from '../SocketContext'
import { useAnalytics } from '../analytics'

export interface AmountProps {
value: ExplorerAmount | string
Expand All @@ -16,20 +23,17 @@ export const Amount = ({
value,
}: AmountProps) => {
const language = useLanguage()
const rippledSocket = useContext(SocketContext)
const { trackException } = useAnalytics()
const issuer = typeof value === 'string' ? undefined : value.issuer
const currency = typeof value === 'string' ? 'XRP' : value.currency
const amount =
typeof value === 'string' ? parseInt(value, 10) / XRP_BASE : value.amount
const isMPT = typeof value === 'string' ? false : value.isMPT

const options = { ...CURRENCY_OPTIONS, currency }
// If it's an MPT, we can use as it is because we don't need decimal
const localizedAmount =
isMPT && typeof value !== 'string'
? value.amount
: localizeNumber(amount, language, options)

return (
const renderAmount = (localizedAmount) => (
<span className="amount">
<span className="amount-localized">
{modifier && <span className="amount-modifier">{modifier}</span>}
Expand All @@ -44,4 +48,35 @@ export const Amount = ({
/>
</span>
)

const mptID = isMPT ? (value as ExplorerAmount).currency : null

// fetch MPTIssuance only if isMPT is true
const { data: mptIssuanceData } =
useQuery<MPTIssuanceFormattedInfo>(
['getMPTIssuanceScale', mptID],
async () => {
const info = await getMPTIssuance(rippledSocket, mptID)
return formatMPTIssuanceInfo(info)
},
{
onError: (e: any) => {
trackException(`mptIssuance ${mptID} --- ${JSON.stringify(e)}`)
},
enabled: isMPT,
},
) || {}

// if amount is MPT type, we need to fetch the scale from the MPTokenIssuance
// object so we can show the scaled amount
if (isMPT && typeof value !== 'string') {
if (mptIssuanceData) {
const scale = mptIssuanceData.assetScale ?? 0
const scaledAmount = parseInt(amount as string, 10) / 10 ** scale
return renderAmount(localizeMPTNumber(scaledAmount))
}
return null
}

return renderAmount(localizeNumber(amount, language, options))
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { useQuery } from 'react-query'
import { createSimpleWrapperFactory, expectSimpleRowText } from '../../test'
import { Simple } from '../Simple'
import transaction from './mock_data/Clawback.json'
import transactionFailure from './mock_data/Clawback_Failure.json'
import transactionMPT from './mock_data/ClawbackMPT.json'
import transactionMPTFailure from './mock_data/ClawbackMPT_Failure.json'

jest.mock('react-query', () => ({
...jest.requireActual('react-query'),
useQuery: jest.fn(),
}))

const createWrapper = createSimpleWrapperFactory(Simple)

describe('Clawback', () => {
Expand All @@ -20,13 +26,22 @@ describe('Clawback', () => {
})

it('handles MPT Clawback simple view ', () => {
const data = {
assetScale: 3,
}

// @ts-ignore
useQuery.mockImplementation(() => ({
data,
}))
const wrapper = createWrapper(transactionMPT)
expectSimpleRowText(wrapper, 'holder', 'rJxiAVBX7B9PqHXb7VmitRZWbFb87wzeb7')
expectSimpleRowText(
wrapper,
'amount',
'200 MPT (00002C8389DF4D75362F45B32EA66F8CF250438A9AD0D555)',
'0.2 MPT (00002C8389DF4D75362F45B32EA66F8CF250438A9AD0D555)',
)

wrapper.unmount()
})

Expand All @@ -42,12 +57,21 @@ describe('Clawback', () => {
})

it('handles failed MPT Clawback simple view ', () => {
const data = {
assetScale: 3,
}

// @ts-ignore
useQuery.mockImplementation(() => ({
data,
}))
const wrapper = createWrapper(transactionMPTFailure)

expectSimpleRowText(wrapper, 'holder', 'rHEudzMb9QwaHgKCT8NREJUQ9wWs8GwpKV')
expectSimpleRowText(
wrapper,
'amount',
'1000 MPT (0000012F2CCA489EAB713F0F099281FE4A9BCC2703560564)',
'1 MPT (0000012F2CCA489EAB713F0F099281FE4A9BCC2703560564)',
)
wrapper.unmount()
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import { BrowserRouter as Router } from 'react-router-dom'
import { mount } from 'enzyme'
import { I18nextProvider } from 'react-i18next'
import { QueryClientProvider } from 'react-query'
import { Simple as NFTokenCancelOffer } from '../Simple'
import transaction from './mock_data/NFTokenCancelOffer.json'
import summarizeTransaction from '../../../../../../rippled/lib/txSummary'
import i18n from '../../../../../../i18n/testConfig'
import { queryClient } from '../../../../QueryClient'

describe('NFTokenCancelOffer', () => {
it.only('handles NFTokenCancelOffer simple view ', () => {
const wrapper = mount(
<I18nextProvider i18n={i18n}>
<Router>
<NFTokenCancelOffer
data={summarizeTransaction(transaction, true).details}
/>
</Router>
</I18nextProvider>,
<QueryClientProvider client={queryClient}>
<I18nextProvider i18n={i18n}>
<Router>
<NFTokenCancelOffer
data={summarizeTransaction(transaction, true).details}
/>
</Router>
</I18nextProvider>
</QueryClientProvider>,
)
expect(wrapper.find('[data-test="token-id"] .value')).toHaveText(
'000800006203F49C21D5D6E022CB16DE3538F248662FC73C258BA1B200000018',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useQuery } from 'react-query'
import {
createSimpleWrapperFactory,
expectSimpleRowLabel,
Expand All @@ -12,6 +13,11 @@ import mockPaymentSendMax from './mock_data/PaymentWithSendMax.json'
import mockPaymentSourceTag from './mock_data/PaymentWithSourceTag.json'
import mockPaymentMPT from './mock_data/PaymentMPT.json'

jest.mock('react-query', () => ({
...jest.requireActual('react-query'),
useQuery: jest.fn(),
}))

const createWrapper = createSimpleWrapperFactory(Simple)

describe('Payment: Simple', () => {
Expand Down Expand Up @@ -117,12 +123,21 @@ describe('Payment: Simple', () => {
})

it('renders direct MPT payment', () => {
const data = {
assetScale: 3,
}

// @ts-ignore
useQuery.mockImplementation(() => ({
data,
}))

const wrapper = createWrapper(mockPaymentMPT)

expectSimpleRowText(
wrapper,
'amount',
`100 MPT (00002DB655677487DE53D3052961F0288A648480EC9E58DD)`,
`0.1 MPT (00002DB655677487DE53D3052961F0288A648480EC9E58DD)`,
)
expectSimpleRowLabel(wrapper, 'amount', `send`)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ export const parser = (tx: SetHook, meta: any): SetHookInstructions => {
(node.ModifiedNode?.LedgerEntryType === 'Hook' &&
!!node.ModifiedNode?.PreviousFields?.Hooks),
)
const hashes = affectedNodes.flatMap((node: any) =>
(node.ModifiedNode?.FinalFields ?? node.CreatedNode?.NewFields)?.Hooks?.map(
(hook: any) => hook.Hook.HookHash,
),
const hashes = affectedNodes.flatMap(
(node: any) =>
(
node.ModifiedNode?.FinalFields ?? node.CreatedNode?.NewFields
)?.Hooks?.map((hook: any) => hook.Hook.HookHash),
)
// TODO: there may be bugs here when a `HookHash` is already specified in a hook
// It's difficult to understand what situation that would be in, so this is left here for now
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { ReactElement } from 'react'
import { I18nextProvider } from 'react-i18next'
import { BrowserRouter } from 'react-router-dom'
import { i18n } from 'i18next'
import { QueryClientProvider } from 'react-query'
import defaultI18nConfig from '../../../../../i18n/testConfig'
import summarizeTransaction from '../../../../../rippled/lib/txSummary'
import {
TransactionDescriptionComponent,
TransactionSimpleComponent,
TransactionTableDetailComponent,
} from '../types'
import { testQueryClient } from '../../../../test/QueryClient'

/**
* Methods that produce createWrapper function for tests
Expand All @@ -22,9 +24,11 @@ export function createWrapper(
i18nConfig?: i18n,
): ReactWrapper {
return mount(
<I18nextProvider i18n={i18nConfig || defaultI18nConfig}>
<BrowserRouter>{TestComponent}</BrowserRouter>
</I18nextProvider>,
<QueryClientProvider client={testQueryClient}>
<I18nextProvider i18n={i18nConfig || defaultI18nConfig}>
<BrowserRouter>{TestComponent}</BrowserRouter>
</I18nextProvider>
</QueryClientProvider>,
)
}

Expand Down
Loading

0 comments on commit d81784d

Please sign in to comment.