Skip to content

Commit

Permalink
Use proper typing
Browse files Browse the repository at this point in the history
Use an object and function instead of switch
  • Loading branch information
segun committed Jul 20, 2023
1 parent 2a68338 commit 9c0f01a
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 339 deletions.
11 changes: 4 additions & 7 deletions app/components/UI/BlockaidBanner/BlockaidBanner.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,6 @@ export const getBlockaidBannerStoryProps = (): BlockaidBannerProps => {
storybookPropsGroupID,
);

const attackDetails = text(
'attackDetails',
'Sample Attack Details',
storybookPropsGroupID,
);

return {
severity: severitySelector,
title,
Expand All @@ -51,8 +45,11 @@ export const getBlockaidBannerStoryProps = (): BlockaidBannerProps => {
},
onClose: () => console.log('closeButton clicked!'),
attackType: 'raw_signature_farming',
attackDetails,
flagType: 'malicious',
features: [
'Operator is an EOA',
'Operator is untrusted according to previous activity',
],
};
};

Expand Down
84 changes: 16 additions & 68 deletions app/components/UI/BlockaidBanner/BlockaidBanner.test.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,22 @@
import React from 'react';
import { fireEvent, render } from '@testing-library/react-native';
import BlockaidBanner from './BlockaidBanner';
import { Text } from 'react-native-svg';
import ListItem from '../../../components/Base/ListItem';
import { FlatList } from 'react-native-gesture-handler';
import FontAwesome5Icon from 'react-native-vector-icons/FontAwesome5';
import { StyleSheet } from 'react-native';

describe('BlockaidBanner', () => {
const listItems = [
{
title: 'attack_description_1',
description: 'We found attack vectors in this request',
},
{
title: 'attack_description_2',
description: 'This request shows a fake token name and icon.',
},
{
title: 'attack_description_3',
description:
'If you approve this request, a third party known for scams might take all your assets.',
},
const mockFeatures = [
'We found attack vectors in this request',
'This request shows a fake token name and icon.',
'If you approve this request, a third party known for scams might take all your assets.',
'Operator is an EOA',
'Operator is untrusted according to previous activity',
];

const styles = StyleSheet.create({
wrapper: {
padding: 15,
},
});

it('should render correctly', () => {
const wrapper = render(
<BlockaidBanner
flagType="warning"
attackType="approval_farming"
attackDetails="This is a string attack details"
features={mockFeatures}
/>,
);

Expand All @@ -47,7 +28,7 @@ describe('BlockaidBanner', () => {
<BlockaidBanner
flagType="malicious"
attackType="raw_signature_farming"
attackDetails="This is a string attack details"
features={mockFeatures}
/>,
);

Expand All @@ -68,7 +49,7 @@ describe('BlockaidBanner', () => {
<BlockaidBanner
flagType="malicious"
attackType="raw_signature_farming"
attackDetails="This is a string attack details"
features={mockFeatures}
/>,
);

Expand All @@ -78,51 +59,12 @@ describe('BlockaidBanner', () => {
).toBeDefined();
});

it('should render correctly with string attack details', async () => {
const wrapper = render(
<BlockaidBanner
flagType="malicious"
attackType="approval_farming"
attackDetails="This is a string attack details"
/>,
);

expect(wrapper).toMatchSnapshot();
expect(await wrapper.queryByTestId('accordion-header')).toBeDefined();
expect(
await wrapper.queryByText('This is a string attack details'),
).toBeNull();
fireEvent.press(await wrapper.getByText('See details'));
expect(
await wrapper.getByText('This is a string attack details'),
).toBeDefined();
});

it('should render correctly with list attack details', async () => {
const wrapper = render(
<BlockaidBanner
flagType="malicious"
attackType="approval_farming"
attackDetails={
<>
<FlatList
data={listItems}
renderItem={({ item }) => (
<ListItem style={styles}>
<ListItem.Content style={styles}>
<ListItem.Icon style={styles}>
<FontAwesome5Icon name="dot-circle" size={25} />
</ListItem.Icon>
<ListItem.Body style={styles}>
<Text>{item.description}</Text>
</ListItem.Body>
</ListItem.Content>
</ListItem>
)}
keyExtractor={(item) => item.title}
/>
</>
}
features={mockFeatures}
/>,
);

Expand All @@ -146,5 +88,11 @@ describe('BlockaidBanner', () => {
'If you approve this request, a third party known for scams might take all your assets.',
),
).toBeDefined();
expect(await wrapper.queryByText('Operator is an EOA')).toBeDefined();
expect(
await wrapper.queryByText(
'Operator is untrusted according to previous activity',
),
).toBeDefined();
});
});
80 changes: 37 additions & 43 deletions app/components/UI/BlockaidBanner/BlockaidBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,71 @@ import React from 'react';
import { strings } from '../../../../locales/i18n';
import { useTheme } from '@react-navigation/native';
import { AccordionHeaderHorizontalAlignment } from '../../../component-library/components/Accordions/Accordion';
import { BlockaidBannerProps } from './BlockaidBanner.types';
import { AttackType, BlockaidBannerProps } from './BlockaidBanner.types';
import { BannerAlertSeverity } from '../../../component-library/components/Banners/Banner';
import { DEFAULT_BANNERBASE_DESCRIPTION_TEXTVARIANT } from '../../../component-library/components/Banners/Banner/foundation/BannerBase/BannerBase.constants';
import { FlatList } from 'react-native-gesture-handler';
import {
REASON_DESCRIPTION_I18N_KEY_MAP,
SUSPICIOUS_TITLED_REQUESTS,
} from './utils';
import { StyleSheet } from 'react-native';
import Accordion from '../../../component-library/components/Accordions/Accordion/Accordion';
import AttributionLink from './AttributionLink';
import BannerAlert from '../../../component-library/components/Banners/Banner/variants/BannerAlert/BannerAlert';
import FontAwesome5Icon from 'react-native-vector-icons/FontAwesome5';
import ListItem from '../../../components/Base/ListItem';
import Text from '../../../component-library/components/Texts/Text/Text';
import AttributionLink from './AttributionLink';

const getTitle = (attackType: AttackType) => {
if (SUSPICIOUS_TITLED_REQUESTS.indexOf(attackType) >= 0) {
return strings('blockaid_banner.suspicious_request_title');
}
return strings('blockaid_banner.deceptive_request_title');
};

const createStyles = (colors: any) =>
StyleSheet.create({
attributionLink: { color: colors.primary.default },
shieldIcon: { marginRight: 5, color: colors.primary.default },
});

const getTitleDescription = (attackType: string) => {
let title = strings('blockaid_banner.title');
let description;

switch (attackType) {
case 'raw_signature_farming':
title = strings('blockaid_banner.raw_signature_farming_title');
description = strings(
'blockaid_banner.raw_signature_farming_description',
);
break;
case 'approval_farming':
case 'set_approval_for_all_farming':
case 'permit_farming':
description = strings('blockaid_banner.approval_farming_description');
break;
case 'transfer_farming':
case 'transfer_from_farming':
case 'raw_native_token_transfer':
description = strings('blockaid_banner.transfer_farming_description');
break;
case 'seaport_farming':
description = strings('blockaid_banner.seaport_farming_description');
break;
case 'blur_farming':
description = strings('blockaid_banner.blur_farming_description');
break;
case 'unfair_trade':
default:
description = strings('blockaid_banner.unfair_trade_description');
break;
}
const getTitleDescription = (attackType: AttackType) => {
const title = getTitle(attackType);
const description = strings(REASON_DESCRIPTION_I18N_KEY_MAP[attackType]);

return { title, description };
};

const BlockaidBanner = (bannerProps: BlockaidBannerProps) => {
const { flagType, attackType, onToggleShowDetails, attackDetails } =
bannerProps;
const { flagType, attackType, features, onToggleShowDetails } = bannerProps;

const { colors } = useTheme();
const styles = createStyles(colors);

const { title, description } = getTitleDescription(attackType);

const renderAttackDetails = () =>
typeof attackDetails === 'string' ? (
<Text variant={DEFAULT_BANNERBASE_DESCRIPTION_TEXTVARIANT}>
{attackDetails}
</Text>
) : (
attackDetails
features.length <= 0 ? null : (
<FlatList
data={features}
renderItem={({ item }) => (
<ListItem style={styles}>
<ListItem.Content style={styles}>
<ListItem.Icon style={styles}>
<FontAwesome5Icon name="dot-circle" size={25} />
</ListItem.Icon>
<ListItem.Body style={styles}>
<Text>{item.description}</Text>
</ListItem.Body>
</ListItem.Content>
</ListItem>
)}
keyExtractor={(item) => item.title}
/>
);

return (
return flagType === 'benign' ? null : (
<BannerAlert
severity={
flagType === 'malicious'
Expand Down
32 changes: 17 additions & 15 deletions app/components/UI/BlockaidBanner/BlockaidBanner.types.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import { ReactNode } from 'react';
import { BannerAlertProps } from '../../../component-library/components/Banners/Banner/variants/BannerAlert/BannerAlert.types';

export type BlockaidBannerProps = BannerAlertProps & {
attackType:
| 'raw_signature_farming'
| 'approval_farming'
| 'set_approval_for_all_farming'
| 'permit_farming'
| 'transfer_farming'
| 'transfer_from_farming'
| 'raw_native_token_transfer'
| 'seaport_farming'
| 'blur_farming'
| 'unfair_trade'
| 'others';
export type AttackType =
| 'raw_signature_farming'
| 'approval_farming'
| 'set_approval_for_all_farming'
| 'permit_farming'
| 'transfer_farming'
| 'transfer_from_farming'
| 'raw_native_token_transfer'
| 'seaport_farming'
| 'blur_farming'
| 'unfair_trade'
| 'trade_order_farming'
| 'other'
| 'malicious_domain';

export type BlockaidBannerProps = BannerAlertProps & {
attackType: AttackType;
features: string[];
flagType: 'malicious' | 'warning' | 'benign';
attackDetails: string | ReactNode;
onToggleShowDetails?: () => void;
};
Loading

0 comments on commit 9c0f01a

Please sign in to comment.