Skip to content

Commit

Permalink
Merge branch 'main' into STAKE-899--fe-add-earn-token-selector
Browse files Browse the repository at this point in the history
  • Loading branch information
amitabh94 committed Feb 19, 2025
2 parents f1a548e + e3c59ba commit 435b72f
Show file tree
Hide file tree
Showing 56 changed files with 1,040 additions and 218 deletions.
13 changes: 5 additions & 8 deletions app/components/UI/AssetOverview/Balance/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import configureMockStore from 'redux-mock-store';
import { backgroundState } from '../../../../util/test/initial-root-state';
import { NetworkBadgeSource } from './Balance';
import { isPortfolioViewEnabled } from '../../../../util/networks';
import { MOCK_VAULT_APY_AVERAGES } from '../../Stake/components/PoolStakingLearnMoreModal/mockVaultRewards';

jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
Expand Down Expand Up @@ -100,16 +101,12 @@ jest.mock('../../Stake/hooks/usePooledStakes', () => ({
}),
}));

jest.mock('../../Stake/hooks/useVaultData', () => ({
jest.mock('../../Stake/hooks/useVaultApyAverages', () => ({
__esModule: true,
default: () => ({
vaultData: {
apy: '2.437033146840025387168141592920355',
capacity: '1000000000000000000000000000000000000000000000000000000000000',
feePercent: 1500,
totalAssets: '10000000000000000000000',
vaultAddress: '0xdef',
},
vaultApyAverages: MOCK_VAULT_APY_AVERAGES,
isLoadingVaultApyAverages: false,
refreshVaultApyAverages: jest.fn(),
}),
}));

Expand Down
39 changes: 29 additions & 10 deletions app/components/UI/Name/Name.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
/* eslint-disable react/prop-types */
import React from 'react';
import { TextProps, View, ViewStyle } from 'react-native';

import { useStyles } from '../../../component-library/hooks';
import Text, {
TextVariant,
} from '../../../component-library/components/Texts/Text';
import { AvatarSize } from '../../../component-library/components/Avatars/Avatar';
import Badge, { BadgeVariant } from '../../../component-library/components/Badges/Badge';
import Icon, {
IconName,
} from '../../../component-library/components/Icons/Icon';
import Text, {
TextVariant,
} from '../../../component-library/components/Texts/Text';
import { useStyles } from '../../../component-library/hooks';
import images from '../../../images/image-icons';
import { renderShortAddress } from '../../../util/address';
import useDisplayName, {
DisplayNameVariant,
} from '../../hooks/DisplayName/useDisplayName';
import Identicon from '../Identicon';
import { NameProperties, NameType } from './Name.types';
import styleSheet from './Name.styles';
import { NameProperties, NameType } from './Name.types';

const NameLabel: React.FC<{
displayNameVariant: DisplayNameVariant;
Expand Down Expand Up @@ -59,7 +61,7 @@ const Name: React.FC<NameProperties> = ({
throw new Error('Unsupported NameType: ' + type);
}

const { image, name, variant } = useDisplayName({
const { image, name, variant, isFirstPartyContractName } = useDisplayName({
preferContractSymbol,
type,
value,
Expand All @@ -74,16 +76,33 @@ const Name: React.FC<NameProperties> = ({
return <UnknownEthereumAddress address={value} style={style} />;
}

const MAX_CHAR_LENGTH = 21;
const MIDDLE_SECTION_ELLIPSIS = '...';
const truncatedName =
name && name.length > MAX_CHAR_LENGTH
? `${name.slice(0, (MAX_CHAR_LENGTH - MIDDLE_SECTION_ELLIPSIS.length) / 2)}${MIDDLE_SECTION_ELLIPSIS}${name.slice(-(MAX_CHAR_LENGTH - MIDDLE_SECTION_ELLIPSIS.length) / 2)}`
: name;


return (
<View style={[styles.base, style]}>
<Identicon
{isFirstPartyContractName ? (
<Badge
size={AvatarSize.Xs}
imageSource={images.FOX_LOGO}
variant={BadgeVariant.Network}
isScaled={false}
/>
) : (
<Identicon
address={value}
diameter={16}
imageUri={image}
customStyle={styles.image}
/>
/>
)}
<NameLabel displayNameVariant={variant} ellipsizeMode="tail">
{name}
{truncatedName}
</NameLabel>
</View>
);
Expand Down
6 changes: 6 additions & 0 deletions app/components/UI/Ramp/components/Quote/Quote.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ const styleSheet = (params: { theme: Theme }) => {
const { theme } = params;
const { colors } = theme;
return StyleSheet.create({
tags: {
display: 'flex',
flexDirection: 'row',
gap: 8,
marginBottom: 8,
},
fee: {
marginLeft: 8,
},
Expand Down
152 changes: 152 additions & 0 deletions app/components/UI/Ramp/components/Quote/Quote.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import React from 'react';
import { fireEvent } from '@testing-library/react-native';
import Quote from './Quote';
import {
CryptoCurrency,
FiatCurrency,
Provider,
QuoteResponse,
SellQuoteResponse,
} from '@consensys/on-ramp-sdk';
import { RampType } from '../../types';
import { QuoteTags } from '@consensys/on-ramp-sdk/dist/API';
import renderWithProvider from '../../../../../util/test/renderWithProvider';
import { selectIpfsGateway } from '../../../../../selectors/preferencesController';

// Mock the selectIpfsGateway selector
jest.mock('../../../../../selectors/preferencesController', () => ({
...jest.requireActual('../../../../../selectors/preferencesController'),
selectIpfsGateway: jest.fn(),
}));

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
(selectIpfsGateway as unknown as jest.Mock).mockReturnValue(
'https://mock-ipfs-gateway.com',
);

const mockQuote: QuoteResponse = {
networkFee: 1,
providerFee: 1,
amountIn: 100,
amountOut: 0.005,
fiat: {
symbol: 'USD',
denomSymbol: '$',
decimals: 2,
} as FiatCurrency,
provider: {
name: 'Mock Provider',
logos: { light: 'logo-url', dark: 'logo-url-dark', width: 50, height: 50 },
} as Provider,
crypto: { symbol: 'ETH', decimals: 18 } as CryptoCurrency,
tags: { isBestRate: true } as QuoteTags,
amountOutInFiat: 98,
isNativeApplePay: false,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
buy: () => undefined,
};

const mockSellQuote: SellQuoteResponse = {
...mockQuote,
provider: {
...mockQuote.provider,
name: 'Mock Sell Provider',
},
amountIn: 0.005,
amountOut: 100,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
sell: () => undefined,
};

describe('Quote Component', () => {
it('renders correctly with buy quote', () => {
const { getByText } = renderWithProvider(
<Quote quote={mockQuote} showInfo={jest.fn()} rampType={RampType.BUY} />,
);

expect(getByText('Continue with Mock Provider')).toBeTruthy();
expect(getByText(/0\.005\s*ETH/)).toBeTruthy();
expect(getByText(/\s*\$\s*98\s*USD/)).toBeTruthy();
});

it('renders correctly with sell quote', () => {
const { getByText } = renderWithProvider(
<Quote
quote={mockSellQuote}
showInfo={jest.fn()}
rampType={RampType.SELL}
/>,
);

expect(getByText('Continue with Mock Sell Provider')).toBeTruthy();
expect(getByText(/0\.005\s*ETH/)).toBeTruthy();
expect(getByText(/\s*\$\s*100\s*USD/)).toBeTruthy();
});

it('calls onPress when not highlighted and pressed', () => {
const onPressMock = jest.fn();
const { getByLabelText } = renderWithProvider(
<Quote
quote={mockQuote}
onPress={onPressMock}
showInfo={jest.fn()}
rampType={RampType.BUY}
/>,
);

fireEvent.press(getByLabelText('Mock Provider'));
expect(onPressMock).toHaveBeenCalled();
});

it('shows loading indicator when isLoading is true', () => {
const { getByTestId } = renderWithProvider(
<Quote
quote={mockQuote}
isLoading
showInfo={jest.fn()}
rampType={RampType.BUY}
/>,
);

expect(getByTestId('buy-button-loading')).toBeTruthy();
});

it('displays previously used provider tag', () => {
const { getByText } = renderWithProvider(
<Quote
quote={mockQuote}
previouslyUsedProvider
showInfo={jest.fn()}
rampType={RampType.BUY}
/>,
);

expect(getByText('Previously used')).toBeTruthy();
});

it('displays best rate tag', () => {
const { getByText } = renderWithProvider(
<Quote quote={mockQuote} showInfo={jest.fn()} rampType={RampType.BUY} />,
);

expect(getByText('Best rate')).toBeTruthy();
});

it('calls onPressCTA when CTA button is pressed', () => {
const onPressCTAMock = jest.fn();
const { getByText } = renderWithProvider(
<Quote
quote={mockQuote}
onPressCTA={onPressCTAMock}
showInfo={jest.fn()}
rampType={RampType.BUY}
/>,
);

fireEvent.press(getByText('Continue with Mock Provider'));
expect(onPressCTAMock).toHaveBeenCalled();
});
});
32 changes: 25 additions & 7 deletions app/components/UI/Ramp/components/Quote/Quote.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import {
import { strings } from '../../../../../../locales/i18n';
import ApplePayButton from '../../containers/ApplePayButton';
import RemoteImage from '../../../../Base/RemoteImage';
import TagColored from '../../../../../component-library/components-temp/TagColored';
import TagColored, {
TagColor,
} from '../../../../../component-library/components-temp/TagColored';
import styleSheet from './Quote.styles';
import { useStyles } from '../../../../../component-library/hooks';
import { isBuyQuote } from '../../utils';
Expand Down Expand Up @@ -88,6 +90,8 @@ const Quote: React.FC<Props> = ({
const fiatCode = fiat?.symbol ?? '';
const fiatSymbol = fiat?.denomSymbol ?? '';

const shouldShowTags = previouslyUsedProvider || quote?.tags?.isBestRate;

const expandedHeight = useSharedValue(0);
const handleOnLayout = (event: LayoutChangeEvent) => {
const { nativeEvent } = event;
Expand Down Expand Up @@ -126,12 +130,21 @@ const Quote: React.FC<Props> = ({
topAccessoryGap={8}
topAccessory={
<>
{previouslyUsedProvider ? (
<TagColored>
{strings('fiat_on_ramp_aggregator.previously_used')}
</TagColored>
) : null}
{shouldShowTags && (
<View style={styles.tags}>
{previouslyUsedProvider ? (
<TagColored>
{strings('fiat_on_ramp_aggregator.previously_used')}
</TagColored>
) : null}

{quote?.tags?.isBestRate ? (
<TagColored color={TagColor.Success}>
{strings('fiat_on_ramp_aggregator.best_rate')}
</TagColored>
) : null}
</View>
)}
<TouchableOpacity
onPress={highlighted ? showInfo : undefined}
disabled={!highlighted}
Expand Down Expand Up @@ -182,6 +195,7 @@ const Quote: React.FC<Props> = ({
>
{isLoading ? (
<ActivityIndicator
testID="buy-button-loading"
size={'small'}
color={colors.primary.inverse}
/>
Expand Down Expand Up @@ -210,7 +224,11 @@ const Quote: React.FC<Props> = ({
{crypto?.symbol}
</>
) : (
`≈ ${renderFiat(amountOut, fiatCode, fiat?.decimals)}`
`≈ ${fiatSymbol} ${renderFiat(
amountOut,
fiatCode,
fiat?.decimals,
)}`
)}
</Text>
</ListItemColumn>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ describe('StakeConfirmationView', () => {
route: {
key: '1',
params: {
amountWei: '3210000000000000',
amountFiat: '7.46',
annualRewardRate: '2.5%',
annualRewardsETH: '2.5 ETH',
annualRewardsFiat: '$5000',
amountWei: '10000000000000000',
amountFiat: '26.21',
annualRewardRate: '2.6%',
annualRewardsETH: '0.00026 ETH',
annualRewardsFiat: '$0.68',
},
name: 'params',
},
Expand Down
Loading

0 comments on commit 435b72f

Please sign in to comment.