Skip to content

Commit

Permalink
Merge branch 'main' into chore/custom-span-sentry-tags
Browse files Browse the repository at this point in the history
  • Loading branch information
tommasini authored Oct 16, 2024
2 parents 907d093 + f996de1 commit cd0386d
Show file tree
Hide file tree
Showing 63 changed files with 7,149 additions and 1,074 deletions.
63 changes: 45 additions & 18 deletions app/components/UI/Navbar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1824,34 +1824,61 @@ export const getSettingsNavigationOptions = (title, themeColors) => {
};
};

export function getStakingNavbar(title, navigation, themeColors) {
/**
*
* @param {String} title - Navbar Title.
* @param {NavigationProp<ParamListBase>} navigation Navigation object returned from useNavigation hook.
* @param {ThemeColors} themeColors theme.colors returned from useStyles hook.
* @param {{ backgroundColor?: string, hasCancelButton?: boolean, hasBackButton?: boolean }} [options] - Optional options for navbar.
* @returns Staking Navbar Component.
*/
export function getStakingNavbar(title, navigation, themeColors, options) {
const { hasBackButton = true, hasCancelButton = true } = options ?? {};

const innerStyles = StyleSheet.create({
headerStyle: {
backgroundColor:
options?.backgroundColor ?? themeColors.background.default,
shadowOffset: null,
},
headerLeft: {
marginHorizontal: 16,
},
headerButtonText: {
color: themeColors.primary.default,
fontSize: 14,
...fontStyles.normal,
},
headerStyle: {
backgroundColor: themeColors.background.default,
shadowColor: importedColors.transparent,
elevation: 0,
},
});

function navigationPop() {
navigation.goBack();
}

return {
headerTitle: () => (
<NavbarTitle title={title} disableNetwork translate={false} />
),
headerLeft: () => <View />,
headerRight: () => (
<TouchableOpacity
onPress={() => navigation.dangerouslyGetParent()?.pop()}
style={styles.closeButton}
>
<Text style={innerStyles.headerButtonText}>
{strings('navigation.cancel')}
</Text>
</TouchableOpacity>
<MorphText variant={TextVariant.HeadingMD}>{title}</MorphText>
),
headerStyle: innerStyles.headerStyle,
headerLeft: () =>
hasBackButton ? (
<ButtonIcon
size={ButtonIconSizes.Lg}
iconName={IconName.ArrowLeft}
onPress={navigationPop}
style={innerStyles.headerLeft}
/>
) : null,
headerRight: () =>
hasCancelButton ? (
<TouchableOpacity
onPress={() => navigation.dangerouslyGetParent()?.pop()}
style={styles.closeButton}
>
<Text style={innerStyles.headerButtonText}>
{strings('navigation.cancel')}
</Text>
</TouchableOpacity>
) : null,
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { Theme } from '../../../../../util/theme/models';
import { StyleSheet } from 'react-native';

const stylesSheet = (params: { theme: Theme }) => {
const { theme } = params;
const { colors } = theme;

return StyleSheet.create({
mainContainer: {
flex: 1,
paddingTop: 8,
paddingHorizontal: 16,
backgroundColor: colors.background.alternative,
justifyContent: 'space-between',
},
cardsContainer: {
paddingTop: 16,
gap: 8,
},
});
};

export default stylesSheet;
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React from 'react';
import renderWithProvider from '../../../../../util/test/renderWithProvider';
import StakeConfirmationView from './StakeConfirmationView';
import { Image } from 'react-native';
import { createMockAccountsControllerState } from '../../../../../util/test/accountsControllerTestUtils';
import { backgroundState } from '../../../../../util/test/initial-root-state';
import configureMockStore from 'redux-mock-store';
import { Provider } from 'react-redux';
import { StakeConfirmationViewProps } from './StakeConfirmationView.types';

jest.mock('../../../../hooks/useIpfsGateway', () => jest.fn());

Image.getSize = jest.fn((_uri, success) => {
success(100, 100); // Mock successful response for ETH native Icon Image
});

const MOCK_ADDRESS_1 = '0x0';
const MOCK_ADDRESS_2 = '0x1';

const MOCK_ACCOUNTS_CONTROLLER_STATE = createMockAccountsControllerState([
MOCK_ADDRESS_1,
MOCK_ADDRESS_2,
]);

const mockStore = configureMockStore();

const mockInitialState = {
settings: {},
engine: {
backgroundState: {
...backgroundState,
AccountsController: MOCK_ACCOUNTS_CONTROLLER_STATE,
},
},
};
const store = mockStore(mockInitialState);

jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
useSelector: jest
.fn()
.mockImplementation((callback) => callback(mockInitialState)),
}));

jest.mock('@react-navigation/native', () => {
const actualNav = jest.requireActual('@react-navigation/native');
return {
...actualNav,
useNavigation: () => ({
navigate: jest.fn(),
setOptions: jest.fn(),
}),
};
});

describe('StakeConfirmationView', () => {
it('render matches snapshot', () => {
const props: StakeConfirmationViewProps = {
route: {
key: '1',
params: { amountWei: '3210000000000000', amountFiat: '7.46' },
name: 'params',
},
};

const { toJSON } = renderWithProvider(
<Provider store={store}>
<StakeConfirmationView {...props} />
</Provider>,
);

expect(toJSON()).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { useEffect } from 'react';
import { View } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { useStyles } from '../../../../hooks/useStyles';
import { getStakingNavbar } from '../../../Navbar';
import styleSheet from './StakeConfirmationView.styles';
import TokenValueStack from '../../components/StakingConfirmation/TokenValueStack/TokenValueStack';
import AccountHeaderCard from '../../components/StakingConfirmation/AccountHeaderCard/AccountHeaderCard';
import RewardsCard from '../../components/StakingConfirmation/RewardsCard/RewardsCard';
import ConfirmationFooter from '../../components/StakingConfirmation/ConfirmationFooter/ConfirmationFooter';
import { StakeConfirmationViewProps } from './StakeConfirmationView.types';
import { MOCK_GET_VAULT_RESPONSE } from '../../components/StakingBalance/mockData';
import { strings } from '../../../../../../locales/i18n';

const MOCK_REWARD_DATA = {
REWARDS: {
ETH: '0.13 ETH',
FIAT: '$334.93',
},
};

const MOCK_STAKING_CONTRACT_NAME = 'MM Pooled Staking';

const StakeConfirmationView = ({ route }: StakeConfirmationViewProps) => {
const navigation = useNavigation();

const { styles, theme } = useStyles(styleSheet, {});

useEffect(() => {
navigation.setOptions(
getStakingNavbar(strings('stake.stake'), navigation, theme.colors, {
backgroundColor: theme.colors.background.alternative,
hasCancelButton: false,
}),
);
}, [navigation, theme.colors]);

return (
<View style={styles.mainContainer}>
<View>
<TokenValueStack
amountWei={route.params.amountWei}
amountFiat={`$${route.params.amountFiat}`}
tokenSymbol="ETH"
/>
<View style={styles.cardsContainer}>
<AccountHeaderCard contractName={MOCK_STAKING_CONTRACT_NAME} />
<RewardsCard
rewardRate={MOCK_GET_VAULT_RESPONSE.apy}
rewardsEth={MOCK_REWARD_DATA.REWARDS.ETH}
rewardsFiat={MOCK_REWARD_DATA.REWARDS.FIAT}
/>
</View>
</View>
<ConfirmationFooter />
</View>
);
};

export default StakeConfirmationView;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { RouteProp } from '@react-navigation/native';

interface StakeConfirmationViewRouteParams {
amountWei: string;
amountFiat: string;
}

export interface StakeConfirmationViewProps {
route: RouteProp<{ params: StakeConfirmationViewRouteParams }, 'params'>;
}
Loading

0 comments on commit cd0386d

Please sign in to comment.