Skip to content

Commit

Permalink
fixes and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ArminaAiren committed Nov 1, 2023
1 parent bbc116f commit d4f9b0e
Show file tree
Hide file tree
Showing 27 changed files with 214 additions and 232 deletions.
3 changes: 3 additions & 0 deletions icons/collection.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 47 additions & 1 deletion mocks/address/tokens.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { AddressTokenBalance } from 'types/api/address';
import type { AddressCollectionsResponse, AddressNFTsResponse, AddressTokenBalance } from 'types/api/address';

import * as tokens from 'mocks/tokens/tokenInfo';
import * as tokenInstance from 'mocks/tokens/tokenInstance';
Expand Down Expand Up @@ -117,3 +117,49 @@ export const erc1155List = {
erc1155b,
],
};

export const nfts: AddressNFTsResponse = {
items: [
{
...tokenInstance.base,
token_type: 'ERC-1155',
value: '11',
},
{
...tokenInstance.unique,
token_type: 'ERC-721',
value: '1',
},
],
next_page_params: null,
};

const nftInstance = {
...tokenInstance.base,
token_type: 'ERC-1155',
value: '11',
};

export const collections: AddressCollectionsResponse = {
items: [
{
token: tokens.tokenInfoERC1155a,
amount: '100',
token_instances: Array(5).fill(nftInstance),
},
{
token: tokens.tokenInfoERC20LongSymbol,
amount: '100',
token_instances: Array(5).fill(nftInstance),
},
{
token: tokens.tokenInfoERC1155WithoutName,
amount: '1',
token_instances: [ nftInstance ],
},
],
next_page_params: {
token_contract_address_hash: '123',
token_type: 'ERC-1155',
},
};
30 changes: 22 additions & 8 deletions ui/address/AddressTokens.pw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import AddressTokens from './AddressTokens';
const ADDRESS_HASH = addressMock.withName.hash;
const API_URL_ADDRESS = buildApiUrl('address', { hash: ADDRESS_HASH });
const API_URL_TOKENS = buildApiUrl('address_tokens', { hash: ADDRESS_HASH });
const API_URL_NFT = buildApiUrl('address_nfts', { hash: ADDRESS_HASH });
const API_URL_COLLECTIONS = buildApiUrl('address_collections', { hash: ADDRESS_HASH });

const nextPageParams = {
items_count: 50,
Expand Down Expand Up @@ -52,6 +54,14 @@ const test = base.extend({
status: 200,
body: JSON.stringify(response1155),
}));
await page.route(API_URL_NFT, (route) => route.fulfill({
status: 200,
body: JSON.stringify(tokensMock.nfts),
}));
await page.route(API_URL_COLLECTIONS, (route) => route.fulfill({
status: 200,
body: JSON.stringify(tokensMock.collections),
}));

use(page);
},
Expand All @@ -76,10 +86,10 @@ test('erc20 +@dark-mode', async({ mount }) => {
await expect(component).toHaveScreenshot();
});

test('erc721 +@dark-mode', async({ mount }) => {
test('collections +@dark-mode', async({ mount }) => {
const hooksConfig = {
router: {
query: { hash: ADDRESS_HASH, tab: 'tokens_erc721' },
query: { hash: ADDRESS_HASH, tab: 'tokens_nfts' },
isReady: true,
},
};
Expand All @@ -95,10 +105,10 @@ test('erc721 +@dark-mode', async({ mount }) => {
await expect(component).toHaveScreenshot();
});

test('erc1155 +@dark-mode', async({ mount }) => {
test('nfts +@dark-mode', async({ mount }) => {
const hooksConfig = {
router: {
query: { hash: ADDRESS_HASH, tab: 'tokens_erc1155' },
query: { hash: ADDRESS_HASH, tab: 'tokens_nfts' },
isReady: true,
},
};
Expand All @@ -111,6 +121,8 @@ test('erc1155 +@dark-mode', async({ mount }) => {
{ hooksConfig },
);

await component.getByText('List').click();

await expect(component).toHaveScreenshot();
});

Expand All @@ -136,10 +148,10 @@ test.describe('mobile', () => {
await expect(component).toHaveScreenshot();
});

test('erc721', async({ mount }) => {
test('nfts', async({ mount }) => {
const hooksConfig = {
router: {
query: { hash: ADDRESS_HASH, tab: 'tokens_erc721' },
query: { hash: ADDRESS_HASH, tab: 'tokens_nfts' },
isReady: true,
},
};
Expand All @@ -152,13 +164,15 @@ test.describe('mobile', () => {
{ hooksConfig },
);

await component.getByLabel('list').click();

await expect(component).toHaveScreenshot();
});

test('erc1155', async({ mount }) => {
test('collections', async({ mount }) => {
const hooksConfig = {
router: {
query: { hash: ADDRESS_HASH, tab: 'tokens_erc1155' },
query: { hash: ADDRESS_HASH, tab: 'tokens_nfts' },
isReady: true,
},
};
Expand Down
89 changes: 9 additions & 80 deletions ui/address/AddressTokens.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import { Box } from '@chakra-ui/react';
import { useQueryClient } from '@tanstack/react-query';
import { useRouter } from 'next/router';
import React from 'react';

import type { SocketMessage } from 'lib/socket/types';
import type { AddressTokenBalance, AddressTokensBalancesSocketMessage, AddressTokensResponse } from 'types/api/address';
import type { TokenType } from 'types/api/token';
import type { PaginationParams } from 'ui/shared/pagination/types';

import { getResourceKey } from 'lib/api/useApiQuery';
import listIcon from 'icons/apps.svg';
import collectionIcon from 'icons/collection.svg';
import { useAppContext } from 'lib/contexts/app';
import * as cookies from 'lib/cookies';
import useIsMobile from 'lib/hooks/useIsMobile';
import getQueryParamString from 'lib/router/getQueryParamString';
import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage';
import { ADDRESS_TOKEN_BALANCE_ERC_20, ADDRESS_NFT_1155, ADDRESS_COLLECTION } from 'stubs/address';
import { generateListStub } from 'stubs/utils';
import Pagination from 'ui/shared/pagination/Pagination';
Expand All @@ -27,7 +22,7 @@ import AddressNFTs from './tokens/AddressNFTs';
import ERC20Tokens from './tokens/ERC20Tokens';
import TokenBalances from './tokens/TokenBalances';

type TNftDisplayType = 'collections' | 'list';
type TNftDisplayType = 'collection' | 'list';

const TAB_LIST_PROPS = {
marginBottom: 0,
Expand All @@ -41,20 +36,14 @@ const TAB_LIST_PROPS_MOBILE = {
columnGap: 3,
};

const tokenBalanceItemIdentityFactory = (match: AddressTokenBalance) => (item: AddressTokenBalance) => ((
match.token.address === item.token.address &&
match.token_id === item.token_id &&
match.token_instance?.id === item.token_instance?.id
));

const AddressTokens = () => {
const router = useRouter();
const isMobile = useIsMobile();

const scrollRef = React.useRef<HTMLDivElement>(null);

const displayTypeCookie = cookies.get(cookies.NAMES.ADDRESS_NFT_DISPLAY_TYPE, useAppContext().cookies);
const [ nftDisplayType, setNftDisplayType ] = React.useState<TNftDisplayType>(displayTypeCookie === 'list' ? 'list' : 'collections');
const [ nftDisplayType, setNftDisplayType ] = React.useState<TNftDisplayType>(displayTypeCookie === 'list' ? 'list' : 'collection');

const tab = getQueryParamString(router.query.tab);
const hash = getQueryParamString(router.query.hash);
Expand All @@ -76,7 +65,7 @@ const AddressTokens = () => {
pathParams: { hash },
scrollRef,
options: {
enabled: tab === 'tokens_nfts' && nftDisplayType === 'collections',
enabled: tab === 'tokens_nfts' && nftDisplayType === 'collection',
refetchOnMount: false,
placeholderData: generateListStub<'address_collections'>(ADDRESS_COLLECTION, 10, { next_page_params: null }),
},
Expand All @@ -93,69 +82,6 @@ const AddressTokens = () => {
},
});

const queryClient = useQueryClient();

const updateTokensData = React.useCallback((type: TokenType, payload: AddressTokensBalancesSocketMessage) => {
const queryKey = getResourceKey('address_tokens', { pathParams: { hash }, queryParams: { type } });

queryClient.setQueryData(queryKey, (prevData: AddressTokensResponse | undefined) => {
const items = prevData?.items.map((currentItem) => {
const updatedData = payload.token_balances.find(tokenBalanceItemIdentityFactory(currentItem));
return updatedData ?? currentItem;
}) || [];

const extraItems = prevData?.next_page_params ?
[] :
payload.token_balances.filter((socketItem) => !items.some(tokenBalanceItemIdentityFactory(socketItem)));

if (!prevData) {
return {
items: extraItems,
next_page_params: null,
};
}

return {
items: items.concat(extraItems),
next_page_params: prevData.next_page_params,
};
});
}, [ hash, queryClient ]);

const handleTokenBalancesErc20Message: SocketMessage.AddressTokenBalancesErc20['handler'] = React.useCallback((payload) => {
updateTokensData('ERC-20', payload);
}, [ updateTokensData ]);

const handleTokenBalancesErc721Message: SocketMessage.AddressTokenBalancesErc721['handler'] = React.useCallback((payload) => {
updateTokensData('ERC-721', payload);
}, [ updateTokensData ]);

const handleTokenBalancesErc1155Message: SocketMessage.AddressTokenBalancesErc1155['handler'] = React.useCallback((payload) => {
updateTokensData('ERC-1155', payload);
}, [ updateTokensData ]);

const channel = useSocketChannel({
topic: `addresses:${ hash.toLowerCase() }`,
// !!!
isDisabled: erc20Query.isPlaceholderData || nftsQuery.isPlaceholderData || collectionsQuery.isPlaceholderData,
});

useSocketMessage({
channel,
event: 'updated_token_balances_erc_20',
handler: handleTokenBalancesErc20Message,
});
useSocketMessage({
channel,
event: 'updated_token_balances_erc_721',
handler: handleTokenBalancesErc721Message,
});
useSocketMessage({
channel,
event: 'updated_token_balances_erc_1155',
handler: handleTokenBalancesErc1155Message,
});

const handleNFTsDisplayTypeChange = React.useCallback((val: TNftDisplayType) => {
cookies.set(cookies.NAMES.ADDRESS_NFT_DISPLAY_TYPE, val);
setNftDisplayType(val);
Expand All @@ -177,7 +103,10 @@ const AddressTokens = () => {
onChange={ handleNFTsDisplayTypeChange }
defaultValue={ nftDisplayType }
name="type"
options={ [ { title: 'By collections', value: 'collections' }, { title: 'List', value: 'list' } ] }
options={ [
{ title: 'By collection', value: 'collection', icon: collectionIcon, onlyIcon: isMobile },
{ title: 'List', value: 'list', icon: listIcon, onlyIcon: isMobile },
] }
/>
);

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
75 changes: 0 additions & 75 deletions ui/address/tokenSelect/TokenSelect.pw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ import { Flex } from '@chakra-ui/react';
import { test as base, expect, devices } from '@playwright/experimental-ct-react';
import React from 'react';

import * as coinBalanceMock from 'mocks/address/coinBalanceHistory';
import * as tokensMock from 'mocks/address/tokens';
import { tokenInfoERC20a } from 'mocks/tokens/tokenInfo';
import * as socketServer from 'playwright/fixtures/socketServer';
import TestApp from 'playwright/TestApp';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import MockAddressPage from 'ui/address/testUtils/MockAddressPage';
Expand Down Expand Up @@ -175,76 +173,3 @@ base('long values', async({ mount, page }) => {

await expect(page).toHaveScreenshot({ clip: CLIPPING_AREA });
});

test.describe('socket', () => {
const testWithSocket = test.extend<socketServer.SocketServerFixture>({
createSocket: socketServer.createSocket,
});
testWithSocket.describe.configure({ mode: 'serial' });

testWithSocket('new item after token balance update', async({ page, mount, createSocket }) => {
await mount(
<TestApp withSocket>
<MockAddressPage>
<Flex>
<TokenSelect/>
</Flex>
</MockAddressPage>
</TestApp>,
{ hooksConfig },
);

await page.route(TOKENS_ERC20_API_URL, async(route) => route.fulfill({
status: 200,
body: JSON.stringify({
items: [
...tokensMock.erc20List.items,
tokensMock.erc20d,
],
}),
}), { times: 1 });

const socket = await createSocket();
const channel = await socketServer.joinChannel(socket, 'addresses:1');
socketServer.sendMessage(socket, channel, 'token_balance', {
block_number: 1,
});

const button = page.getByRole('button', { name: /select/i });
const text = await button.innerText();
expect(text).toContain('10');
});

testWithSocket('new item after coin balance update', async({ page, mount, createSocket }) => {
await mount(
<TestApp withSocket>
<MockAddressPage>
<Flex>
<TokenSelect/>
</Flex>
</MockAddressPage>
</TestApp>,
{ hooksConfig },
);

await page.route(TOKENS_ERC20_API_URL, async(route) => route.fulfill({
status: 200,
body: JSON.stringify({
items: [
...tokensMock.erc20List.items,
tokensMock.erc20d,
],
}),
}), { times: 1 });

const socket = await createSocket();
const channel = await socketServer.joinChannel(socket, 'addresses:1');
socketServer.sendMessage(socket, channel, 'coin_balance', {
coin_balance: coinBalanceMock.base,
});

const button = page.getByRole('button', { name: /select/i });
const text = await button.innerText();
expect(text).toContain('10');
});
});
Loading

0 comments on commit d4f9b0e

Please sign in to comment.