tests for account part
@@ -0,0 +1,164 @@
|
||||
import type { TokenInfoApplication, TokenInfoApplications, VerifiedAddress, VerifiedAddressResponse } from 'types/api/account';
|
||||
import type { AddressValidationResponseSuccess } from 'ui/addressVerification/types';
|
||||
|
||||
export const SIGNATURE = '0x96491e0cd1b99c14951552361b7f6ff64f41651b5d1c12501914342c8a6847e21e08726c3505e11ba2af9a40ac0b05c8d113e7fd1f74594224b9c7276ebb3a661b';
|
||||
|
||||
export const VERIFIED_ADDRESS: Record<string, VerifiedAddress> = {
|
||||
NEW_ITEM: {
|
||||
userId: '1',
|
||||
chainId: '99',
|
||||
contractAddress: '0xF822070D07067D1519490dBf49448a7E30EE9ea5',
|
||||
verifiedDate: '2022-09-01',
|
||||
metadata: {
|
||||
tokenName: 'Test Token',
|
||||
tokenSymbol: 'TT',
|
||||
},
|
||||
},
|
||||
ITEM_1: {
|
||||
userId: '1',
|
||||
chainId: '99',
|
||||
contractAddress: '0xd0e3010d1ecdbd17aae178b2bf36eb413d8a7441',
|
||||
verifiedDate: '2022-08-01',
|
||||
metadata: {
|
||||
tokenName: 'My Token',
|
||||
tokenSymbol: 'MYT',
|
||||
},
|
||||
},
|
||||
ITEM_2: {
|
||||
userId: '1',
|
||||
chainId: '99',
|
||||
contractAddress: '0xa8FCe579a11E551635b9c9CB915BEcd873C51254',
|
||||
verifiedDate: '2022-09-23',
|
||||
metadata: {
|
||||
tokenName: 'Cat Token',
|
||||
tokenSymbol: 'CATT',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const ADDRESS_CHECK_RESPONSE = {
|
||||
SUCCESS: {
|
||||
status: 'SUCCESS',
|
||||
result: {
|
||||
// eslint-disable-next-line max-len
|
||||
signingMessage: '[eth-goerli.blockscout.com] [2023-04-18 18:47:40] I, hereby verify that I am the owner/creator of the address [0xf822070d07067d1519490dbf49448a7e30ee9ea5]',
|
||||
contractCreator: '0xd0e3010d1ecdbd17aae178b2bf36eb413d8a7441',
|
||||
contractOwner: '0xa8FCe579a11E551635b9c9CB915BEcd873C51254',
|
||||
},
|
||||
},
|
||||
SOURCE_CODE_NOT_VERIFIED_ERROR: {
|
||||
status: 'SOURCE_CODE_NOT_VERIFIED_ERROR',
|
||||
},
|
||||
};
|
||||
|
||||
export const ADDRESS_VERIFY_RESPONSE: Record<string, AddressValidationResponseSuccess> = {
|
||||
SUCCESS: {
|
||||
status: 'SUCCESS',
|
||||
result: {
|
||||
verifiedAddress: VERIFIED_ADDRESS.NEW_ITEM,
|
||||
},
|
||||
},
|
||||
INVALID_SIGNER_ERROR: {
|
||||
status: 'INVALID_SIGNER_ERROR',
|
||||
invalidSigner: {
|
||||
signer: '0xF822070D07067D1519490dBf49448a7E30EE9ea5',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const VERIFIED_ADDRESS_RESPONSE: Record<string, VerifiedAddressResponse> = {
|
||||
DEFAULT: {
|
||||
verifiedAddresses: [
|
||||
VERIFIED_ADDRESS.ITEM_1,
|
||||
VERIFIED_ADDRESS.ITEM_2,
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export const TOKEN_INFO_APPLICATION_BASE = {
|
||||
id: '1',
|
||||
tokenAddress: VERIFIED_ADDRESS.ITEM_1.contractAddress,
|
||||
status: 'APPROVED',
|
||||
updatedAt: '2022-11-08 12:47:10.149148Z',
|
||||
requesterName: 'Tom',
|
||||
requesterEmail: 'tom@example.com',
|
||||
projectName: 'My project',
|
||||
projectWebsite: 'http://example.com',
|
||||
projectEmail: 'token@example.com',
|
||||
iconUrl: 'https://placekitten.com/100',
|
||||
projectDescription: 'description',
|
||||
projectSector: 'DeFi',
|
||||
comment: '',
|
||||
docs: 'https://example.com/docs',
|
||||
github: 'https://github.com',
|
||||
telegram: 'https://telegram.com',
|
||||
linkedin: 'https://linkedin.com',
|
||||
discord: 'https://discord.com',
|
||||
slack: 'https://slack.com',
|
||||
twitter: 'https://twitter.com',
|
||||
openSea: 'https://opensea.com',
|
||||
facebook: 'https://facebook.com',
|
||||
medium: 'https://medium.com',
|
||||
reddit: 'https://reddit.com',
|
||||
support: 'support@example.com',
|
||||
coinMarketCapTicker: 'https://coinmarketcap.com',
|
||||
coinGeckoTicker: 'https://coingecko.com',
|
||||
defiLlamaTicker: 'https://defillama.com',
|
||||
};
|
||||
|
||||
export const TOKEN_INFO_APPLICATION: Record<string, TokenInfoApplication> = {
|
||||
APPROVED: {
|
||||
...TOKEN_INFO_APPLICATION_BASE,
|
||||
tokenAddress: VERIFIED_ADDRESS.ITEM_1.contractAddress,
|
||||
id: '1',
|
||||
status: 'APPROVED',
|
||||
updatedAt: '2022-11-08 12:47:10.149148Z',
|
||||
},
|
||||
IN_PROCESS: {
|
||||
...TOKEN_INFO_APPLICATION_BASE,
|
||||
tokenAddress: VERIFIED_ADDRESS.ITEM_2.contractAddress,
|
||||
id: '2',
|
||||
status: 'IN_PROCESS',
|
||||
updatedAt: '2022-11-10 08:11:10.149148Z',
|
||||
},
|
||||
UPDATED_ITEM: {
|
||||
...TOKEN_INFO_APPLICATION_BASE,
|
||||
tokenAddress: VERIFIED_ADDRESS.ITEM_1.contractAddress,
|
||||
id: '1',
|
||||
status: 'IN_PROCESS',
|
||||
updatedAt: '2022-11-11 05:11:10.149148Z',
|
||||
},
|
||||
};
|
||||
|
||||
export const TOKEN_INFO_APPLICATIONS_RESPONSE: Record<string, TokenInfoApplications> = {
|
||||
DEFAULT: {
|
||||
submissions: [
|
||||
TOKEN_INFO_APPLICATION.APPROVED,
|
||||
TOKEN_INFO_APPLICATION.IN_PROCESS,
|
||||
],
|
||||
},
|
||||
FOR_UPDATE: {
|
||||
submissions: [
|
||||
{
|
||||
...TOKEN_INFO_APPLICATION.APPROVED,
|
||||
status: 'UPDATE_REQUIRED',
|
||||
},
|
||||
TOKEN_INFO_APPLICATION.IN_PROCESS,
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export const TOKEN_INFO_FORM_CONFIG = {
|
||||
projectSectors: [
|
||||
'Infra & Dev tooling',
|
||||
'DeFi',
|
||||
'Data',
|
||||
'Bridge',
|
||||
'NFT',
|
||||
'Payments',
|
||||
'Faucet',
|
||||
'DAO',
|
||||
'Games',
|
||||
'Wallet',
|
||||
],
|
||||
};
|
||||
@@ -4,13 +4,16 @@ import React from 'react';
|
||||
|
||||
import getNetworkTitle from 'lib/networks/getNetworkTitle';
|
||||
import VerifiedAddresses from 'ui/pages/VerifiedAddresses';
|
||||
import Page from 'ui/shared/Page/Page';
|
||||
|
||||
const VerifiedAddressesPage: NextPage = () => {
|
||||
const title = getNetworkTitle();
|
||||
return (
|
||||
<>
|
||||
<Head><title>{ title }</title></Head>
|
||||
<VerifiedAddresses/>
|
||||
<Page>
|
||||
<VerifiedAddresses/>
|
||||
</Page>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@ import { compile } from 'path-to-regexp';
|
||||
import type { ResourceName, ResourcePathParams } from 'lib/api/resources';
|
||||
import { RESOURCES } from 'lib/api/resources';
|
||||
|
||||
export default function buildApiUrl<R extends ResourceName>(resourceName: R, pathParams?: ResourcePathParams<R>) {
|
||||
export default function buildApiUrl<R extends ResourceName>(resourceName: R, pathParams?: ResourcePathParams<R>, noBasePath?: boolean) {
|
||||
const resource = RESOURCES[resourceName];
|
||||
return compile('/node-api/proxy/poa/core' + resource.path)(pathParams);
|
||||
return compile(`/node-api/proxy${ noBasePath ? '' : '/poa/core' }` + resource.path)(pathParams);
|
||||
}
|
||||
|
||||
@@ -183,6 +183,7 @@ export interface TokenInfoApplicationConfig {
|
||||
export interface TokenInfoApplication {
|
||||
coinGeckoTicker?: string;
|
||||
coinMarketCapTicker?: string;
|
||||
comment?: string;
|
||||
defiLlamaTicker?: string;
|
||||
discord?: string;
|
||||
docs?: string;
|
||||
|
||||
@@ -60,6 +60,7 @@ const AddressVerificationModal = ({ defaultAddress, isOpen, onClose, onSubmit, o
|
||||
{
|
||||
title: 'Copy and sign message',
|
||||
content: <AddressVerificationStepSignature { ...data } onContinue={ handleGoToThirdStep }/>,
|
||||
fallback: <AddressVerificationStepSignature { ...data } onContinue={ handleGoToThirdStep } noWeb3Provider/>,
|
||||
},
|
||||
{
|
||||
title: 'Congrats! Address is verified.',
|
||||
@@ -89,7 +90,7 @@ const AddressVerificationModal = ({ defaultAddress, isOpen, onClose, onSubmit, o
|
||||
</ModalHeader>
|
||||
<ModalCloseButton/>
|
||||
<ModalBody mb={ 0 }>
|
||||
<Web3ModalProvider>
|
||||
<Web3ModalProvider fallback={ step?.fallback || step.content }>
|
||||
{ step.content }
|
||||
</Web3ModalProvider>
|
||||
</ModalBody>
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import { test, expect } from '@playwright/experimental-ct-react';
|
||||
import React from 'react';
|
||||
|
||||
import * as mocks from 'mocks/account/verifiedAddresses';
|
||||
import TestApp from 'playwright/TestApp';
|
||||
import buildApiUrl from 'playwright/utils/buildApiUrl';
|
||||
|
||||
import AddressVerificationStepAddress from './AddressVerificationStepAddress';
|
||||
|
||||
const CHECK_ADDRESS_URL = buildApiUrl('address_verification', { chainId: '99', type: ':prepare' }, true);
|
||||
|
||||
test('base view', async({ mount, page }) => {
|
||||
await page.route(CHECK_ADDRESS_URL, (route) => route.fulfill({
|
||||
status: 200,
|
||||
body: JSON.stringify(mocks.ADDRESS_CHECK_RESPONSE.SUCCESS),
|
||||
}));
|
||||
|
||||
const props = {
|
||||
onContinue: () => {},
|
||||
defaultAddress: mocks.VERIFIED_ADDRESS.NEW_ITEM.contractAddress,
|
||||
};
|
||||
|
||||
await mount(
|
||||
<TestApp>
|
||||
<AddressVerificationStepAddress { ...props }/>
|
||||
</TestApp>,
|
||||
);
|
||||
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test('SOURCE_CODE_NOT_VERIFIED_ERROR view +@mobile', async({ mount, page }) => {
|
||||
await page.route(CHECK_ADDRESS_URL, (route) => route.fulfill({
|
||||
status: 200,
|
||||
body: JSON.stringify(mocks.ADDRESS_CHECK_RESPONSE.SOURCE_CODE_NOT_VERIFIED_ERROR),
|
||||
}));
|
||||
|
||||
const props = {
|
||||
onContinue: () => {},
|
||||
};
|
||||
|
||||
await mount(
|
||||
<TestApp>
|
||||
<AddressVerificationStepAddress { ...props }/>
|
||||
</TestApp>,
|
||||
);
|
||||
|
||||
const addressInput = page.getByLabel(/smart contract address/i);
|
||||
await addressInput.focus();
|
||||
await addressInput.type(mocks.VERIFIED_ADDRESS.NEW_ITEM.contractAddress);
|
||||
await page.getByRole('button', { name: /continue/i }).click();
|
||||
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
@@ -103,8 +103,8 @@ const AddressVerificationStepAddress = ({ defaultAddress, onContinue }: Props) =
|
||||
<Box>Enter the contract address you are verifying ownership for.</Box>
|
||||
{ rootError && <Alert status="warning" mt={ 3 }>{ rootError }</Alert> }
|
||||
<AddressVerificationFieldAddress formState={ formState } control={ control }/>
|
||||
<Flex alignItems="center" mt={ 8 } columnGap={ 5 }>
|
||||
<Button size="lg" type="submit" isDisabled={ formState.isSubmitting }>
|
||||
<Flex alignItems={{ base: 'flex-start', lg: 'center' }} mt={ 8 } columnGap={ 5 } rowGap={ 2 } flexDir={{ base: 'column', lg: 'row' }}>
|
||||
<Button size="lg" type="submit" isDisabled={ formState.isSubmitting } flexShrink={ 0 }>
|
||||
Continue
|
||||
</Button>
|
||||
<AdminSupportText/>
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import { test, expect } from '@playwright/experimental-ct-react';
|
||||
import React from 'react';
|
||||
|
||||
import * as mocks from 'mocks/account/verifiedAddresses';
|
||||
import TestApp from 'playwright/TestApp';
|
||||
import buildApiUrl from 'playwright/utils/buildApiUrl';
|
||||
|
||||
import AddressVerificationStepSignature from './AddressVerificationStepSignature';
|
||||
|
||||
const VERIFY_ADDRESS_URL = buildApiUrl('address_verification', { chainId: '99', type: ':verify' }, true);
|
||||
|
||||
test('base view', async({ mount, page }) => {
|
||||
await page.route(VERIFY_ADDRESS_URL, (route) => route.fulfill({
|
||||
status: 200,
|
||||
body: JSON.stringify(mocks.ADDRESS_VERIFY_RESPONSE.SUCCESS),
|
||||
}));
|
||||
|
||||
const props = {
|
||||
onContinue: () => {},
|
||||
noWeb3Provider: true,
|
||||
address: mocks.VERIFIED_ADDRESS.NEW_ITEM.contractAddress,
|
||||
signingMessage: mocks.ADDRESS_CHECK_RESPONSE.SUCCESS.result.signingMessage,
|
||||
};
|
||||
|
||||
await mount(
|
||||
<TestApp>
|
||||
<AddressVerificationStepSignature { ...props }/>
|
||||
</TestApp>,
|
||||
);
|
||||
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test('INVALID_SIGNER_ERROR view +@mobile', async({ mount, page }) => {
|
||||
await page.route(VERIFY_ADDRESS_URL, (route) => route.fulfill({
|
||||
status: 200,
|
||||
body: JSON.stringify(mocks.ADDRESS_VERIFY_RESPONSE.INVALID_SIGNER_ERROR),
|
||||
}));
|
||||
|
||||
const props = {
|
||||
onContinue: () => {},
|
||||
noWeb3Provider: true,
|
||||
address: mocks.VERIFIED_ADDRESS.NEW_ITEM.contractAddress,
|
||||
...mocks.ADDRESS_CHECK_RESPONSE.SUCCESS.result,
|
||||
};
|
||||
|
||||
await mount(
|
||||
<TestApp>
|
||||
<AddressVerificationStepSignature { ...props }/>
|
||||
</TestApp>,
|
||||
);
|
||||
|
||||
const signatureInput = page.getByLabel(/signature hash/i);
|
||||
await signatureInput.fill(mocks.SIGNATURE);
|
||||
await page.getByRole('button', { name: /verify/i }).click();
|
||||
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
@@ -28,10 +28,11 @@ type Fields = RootFields & AddressVerificationFormSecondStepFields;
|
||||
|
||||
interface Props extends AddressVerificationFormFirstStepFields, AddressCheckStatusSuccess{
|
||||
onContinue: (newItem: VerifiedAddress) => void;
|
||||
noWeb3Provider?: boolean;
|
||||
}
|
||||
|
||||
const AddressVerificationStepSignature = ({ address, signingMessage, contractCreator, contractOwner, onContinue }: Props) => {
|
||||
const [ signMethod, setSignMethod ] = React.useState<'wallet' | 'manually'>('wallet');
|
||||
const AddressVerificationStepSignature = ({ address, signingMessage, contractCreator, contractOwner, onContinue, noWeb3Provider }: Props) => {
|
||||
const [ signMethod, setSignMethod ] = React.useState<'wallet' | 'manually'>(noWeb3Provider ? 'manually' : 'wallet');
|
||||
|
||||
const { open: openWeb3Modal } = useWeb3Modal();
|
||||
const { isConnected } = useAccount();
|
||||
@@ -208,13 +209,15 @@ const AddressVerificationStepSignature = ({ address, signingMessage, contractCre
|
||||
<CopyToClipboard text={ signingMessage } ml="auto" display="block"/>
|
||||
<AddressVerificationFieldMessage formState={ formState } control={ control }/>
|
||||
</div>
|
||||
<RadioGroup onChange={ handleSignMethodChange } value={ signMethod } display="flex" flexDir="column" rowGap={ 4 }>
|
||||
<Radio value="wallet">Sign via Web3 wallet</Radio>
|
||||
<Radio value="manually">Sign manually</Radio>
|
||||
</RadioGroup>
|
||||
{ !noWeb3Provider && (
|
||||
<RadioGroup onChange={ handleSignMethodChange } value={ signMethod } display="flex" flexDir="column" rowGap={ 4 }>
|
||||
<Radio value="wallet">Sign via Web3 wallet</Radio>
|
||||
<Radio value="manually">Sign manually</Radio>
|
||||
</RadioGroup>
|
||||
) }
|
||||
{ signMethod === 'manually' && <AddressVerificationFieldSignature formState={ formState } control={ control }/> }
|
||||
</Flex>
|
||||
<Flex alignItems="center" mt={ 8 } columnGap={ 5 }>
|
||||
<Flex alignItems={{ base: 'flex-start', lg: 'center' }} mt={ 8 } columnGap={ 5 } rowGap={ 2 } flexDir={{ base: 'column', lg: 'row' }}>
|
||||
{ button }
|
||||
<AdminSupportText/>
|
||||
</Flex>
|
||||
|
||||
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 50 KiB |
@@ -43,7 +43,6 @@ export type AddressValidationResponseSuccess = {
|
||||
status: 'INVALID_SIGNER_ERROR';
|
||||
invalidSigner: {
|
||||
signer: string;
|
||||
validAddresses: Array<string>;
|
||||
};
|
||||
} |
|
||||
{ status: 'VALIDITY_EXPIRED_ERROR' } |
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
import { test, expect } from '@playwright/experimental-ct-react';
|
||||
import React from 'react';
|
||||
|
||||
import * as mocks from 'mocks/account/verifiedAddresses';
|
||||
import TestApp from 'playwright/TestApp';
|
||||
import buildApiUrl from 'playwright/utils/buildApiUrl';
|
||||
|
||||
import VerifiedAddresses from './VerifiedAddresses';
|
||||
|
||||
const VERIFIED_ADDRESS_URL = buildApiUrl('verified_addresses', { chainId: '99' }, true);
|
||||
const TOKEN_INFO_APPLICATIONS_URL = buildApiUrl('token_info_applications', { chainId: '99', id: undefined }, true);
|
||||
|
||||
test.beforeEach(async({ context }) => {
|
||||
await context.route(mocks.TOKEN_INFO_APPLICATION_BASE.iconUrl, (route) => {
|
||||
return route.fulfill({
|
||||
status: 200,
|
||||
path: './playwright/image_s.jpg',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('base view +@mobile', async({ mount, page }) => {
|
||||
await page.route(VERIFIED_ADDRESS_URL, (route) => route.fulfill({
|
||||
body: JSON.stringify(mocks.VERIFIED_ADDRESS_RESPONSE.DEFAULT),
|
||||
}));
|
||||
|
||||
await page.route(TOKEN_INFO_APPLICATIONS_URL, (route) => route.fulfill({
|
||||
body: JSON.stringify(mocks.TOKEN_INFO_APPLICATIONS_RESPONSE.DEFAULT),
|
||||
}));
|
||||
|
||||
const component = await mount(
|
||||
<TestApp>
|
||||
<VerifiedAddresses/>
|
||||
</TestApp>,
|
||||
);
|
||||
|
||||
await expect(component).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test('address verification flow', async({ mount, page }) => {
|
||||
const CHECK_ADDRESS_URL = buildApiUrl('address_verification', { chainId: '99', type: ':prepare' }, true);
|
||||
const VERIFY_ADDRESS_URL = buildApiUrl('address_verification', { chainId: '99', type: ':verify' }, true);
|
||||
|
||||
await page.route(VERIFIED_ADDRESS_URL, (route) => route.fulfill({
|
||||
body: JSON.stringify(mocks.VERIFIED_ADDRESS_RESPONSE.DEFAULT),
|
||||
}));
|
||||
|
||||
await page.route(TOKEN_INFO_APPLICATIONS_URL, (route) => route.fulfill({
|
||||
body: JSON.stringify(mocks.TOKEN_INFO_APPLICATIONS_RESPONSE.DEFAULT),
|
||||
}));
|
||||
|
||||
await page.route(CHECK_ADDRESS_URL, (route) => route.fulfill({
|
||||
body: JSON.stringify(mocks.ADDRESS_CHECK_RESPONSE.SUCCESS),
|
||||
}));
|
||||
|
||||
await page.route(VERIFY_ADDRESS_URL, (route) => {
|
||||
return route.fulfill({
|
||||
body: JSON.stringify(mocks.ADDRESS_VERIFY_RESPONSE.SUCCESS),
|
||||
});
|
||||
});
|
||||
|
||||
await mount(
|
||||
<TestApp>
|
||||
<VerifiedAddresses/>
|
||||
</TestApp>,
|
||||
);
|
||||
|
||||
// open modal
|
||||
await page.getByRole('button', { name: /add address/i }).click();
|
||||
|
||||
// fill first step
|
||||
const addressInput = page.getByLabel(/smart contract address/i);
|
||||
await addressInput.fill(mocks.VERIFIED_ADDRESS.NEW_ITEM.contractAddress);
|
||||
await page.getByRole('button', { name: /continue/i }).click();
|
||||
|
||||
// fill second step
|
||||
const option = page.getByText(/sign manually/i);
|
||||
option.click();
|
||||
const signatureInput = page.getByLabel(/signature hash/i);
|
||||
await signatureInput.fill(mocks.SIGNATURE);
|
||||
await page.getByRole('button', { name: /verify/i }).click();
|
||||
|
||||
// success screen
|
||||
await page.getByRole('button', { name: /view my verified addresses/i }).click();
|
||||
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test('application update flow', async({ mount, page }) => {
|
||||
const TOKEN_INFO_APPLICATION_URL = buildApiUrl('token_info_applications', { chainId: '99', id: mocks.TOKEN_INFO_APPLICATION.UPDATED_ITEM.id }, true);
|
||||
const FORM_CONFIG_URL = buildApiUrl('token_info_applications_config', { chainId: '99' }, true);
|
||||
|
||||
await page.route(VERIFIED_ADDRESS_URL, (route) => route.fulfill({
|
||||
body: JSON.stringify(mocks.VERIFIED_ADDRESS_RESPONSE.DEFAULT),
|
||||
}));
|
||||
|
||||
await page.route(TOKEN_INFO_APPLICATIONS_URL, (route) => route.fulfill({
|
||||
body: JSON.stringify(mocks.TOKEN_INFO_APPLICATIONS_RESPONSE.FOR_UPDATE),
|
||||
}));
|
||||
|
||||
await page.route(FORM_CONFIG_URL, (route) => route.fulfill({
|
||||
body: JSON.stringify(mocks.TOKEN_INFO_FORM_CONFIG),
|
||||
}));
|
||||
|
||||
// PUT request
|
||||
await page.route(TOKEN_INFO_APPLICATION_URL, (route) => route.fulfill({
|
||||
body: JSON.stringify(mocks.TOKEN_INFO_APPLICATION.UPDATED_ITEM),
|
||||
}));
|
||||
|
||||
await mount(
|
||||
<TestApp>
|
||||
<VerifiedAddresses/>
|
||||
</TestApp>,
|
||||
);
|
||||
|
||||
// open form
|
||||
await page.locator('tr').filter({ hasText: 'waiting for update' }).locator('button[aria-label="edit"]').click();
|
||||
|
||||
// change project name
|
||||
const addressInput = page.getByLabel(/project name/i);
|
||||
await addressInput.fill('New name');
|
||||
|
||||
await page.getByRole('button', { name: /send request/i }).click();
|
||||
|
||||
const locator = page.locator('tr').filter({ hasText: 'in progress' }).filter({ hasText: 'nov 11, 2022' });
|
||||
await expect(locator).toBeVisible();
|
||||
});
|
||||
@@ -12,7 +12,6 @@ import getQueryParamString from 'lib/router/getQueryParamString';
|
||||
import AddressVerificationModal from 'ui/addressVerification/AddressVerificationModal';
|
||||
import AccountPageDescription from 'ui/shared/AccountPageDescription';
|
||||
import DataListDisplay from 'ui/shared/DataListDisplay';
|
||||
import Page from 'ui/shared/Page/Page';
|
||||
import PageTitle from 'ui/shared/Page/PageTitle';
|
||||
import SkeletonListAccount from 'ui/shared/skeletons/SkeletonListAccount';
|
||||
import SkeletonTable from 'ui/shared/skeletons/SkeletonTable';
|
||||
@@ -86,9 +85,9 @@ const VerifiedAddresses = () => {
|
||||
return { submissions: [ newItem ] };
|
||||
}
|
||||
|
||||
const isExisting = prevData.submissions.some((item) => item.id === newItem.id);
|
||||
const isExisting = prevData.submissions.some((item) => item.id.toLowerCase() === newItem.id.toLowerCase());
|
||||
const submissions = isExisting ?
|
||||
prevData.submissions.map((item) => item.id === newItem.id ? newItem : item) :
|
||||
prevData.submissions.map((item) => item.id.toLowerCase() === newItem.id.toLowerCase() ? newItem : item) :
|
||||
[ newItem, ...prevData.submissions ];
|
||||
return { submissions };
|
||||
});
|
||||
@@ -128,14 +127,14 @@ const VerifiedAddresses = () => {
|
||||
|
||||
if (selectedAddress) {
|
||||
return (
|
||||
<Page>
|
||||
<>
|
||||
<PageTitle text="Token info application form" backLink={ backLink }/>
|
||||
<TokenInfoForm
|
||||
address={ selectedAddress }
|
||||
application={ applicationsQuery.data?.submissions.find(({ tokenAddress }) => tokenAddress === selectedAddress) }
|
||||
application={ applicationsQuery.data?.submissions.find(({ tokenAddress }) => tokenAddress.toLowerCase() === selectedAddress.toLowerCase()) }
|
||||
onSubmit={ handleApplicationSubmit }
|
||||
/>
|
||||
</Page>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -146,7 +145,7 @@ const VerifiedAddresses = () => {
|
||||
<VerifiedAddressesListItem
|
||||
key={ item.contractAddress }
|
||||
item={ item }
|
||||
application={ applicationsQuery.data?.submissions?.find(({ tokenAddress }) => tokenAddress === item.contractAddress) }
|
||||
application={ applicationsQuery.data?.submissions?.find(({ tokenAddress }) => tokenAddress.toLowerCase() === item.contractAddress.toLowerCase()) }
|
||||
onAdd={ handleItemAdd }
|
||||
onEdit={ handleItemEdit }
|
||||
/>
|
||||
@@ -164,7 +163,7 @@ const VerifiedAddresses = () => {
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<>
|
||||
<PageTitle text="My verified addresses"/>
|
||||
<AccountPageDescription allowCut={ false }>
|
||||
<span>
|
||||
@@ -205,7 +204,7 @@ const VerifiedAddresses = () => {
|
||||
onAddTokenInfoClick={ handleItemAdd }
|
||||
onShowListClick={ modalProps.onClose }
|
||||
/>
|
||||
</Page>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 64 KiB |
@@ -45,7 +45,7 @@ const TokenInfoMenuItem = ({ className, hash }: Props) => {
|
||||
}, [ router ]);
|
||||
|
||||
const content = (() => {
|
||||
if (!verifiedAddressesQuery.data?.verifiedAddresses.find(({ contractAddress }) => contractAddress === hash)) {
|
||||
if (!verifiedAddressesQuery.data?.verifiedAddresses.find(({ contractAddress }) => contractAddress.toLowerCase() === hash.toLowerCase())) {
|
||||
return (
|
||||
<MenuItem className={ className } onClick={ handleAddAddressClick }>
|
||||
Add token info
|
||||
@@ -55,7 +55,11 @@ const TokenInfoMenuItem = ({ className, hash }: Props) => {
|
||||
|
||||
return (
|
||||
<MenuItem className={ className } onClick={ handleAddApplicationClick }>
|
||||
{ applicationsQuery.data?.submissions.some(({ tokenAddress }) => tokenAddress === hash) ? 'Update token info' : 'Add token info' }
|
||||
{
|
||||
applicationsQuery.data?.submissions.some(({ tokenAddress }) => tokenAddress.toLowerCase() === hash.toLowerCase()) ?
|
||||
'Update token info' :
|
||||
'Add token info'
|
||||
}
|
||||
</MenuItem>
|
||||
);
|
||||
})();
|
||||
|
||||
@@ -55,7 +55,7 @@ const { wagmiClient, ethereumClient } = (() => {
|
||||
|
||||
interface Props {
|
||||
children: React.ReactNode;
|
||||
fallback?: () => JSX.Element;
|
||||
fallback?: JSX.Element | (() => JSX.Element);
|
||||
}
|
||||
|
||||
const Web3ModalProvider = ({ children, fallback }: Props) => {
|
||||
@@ -63,7 +63,7 @@ const Web3ModalProvider = ({ children, fallback }: Props) => {
|
||||
const web3ModalTheme = useColorModeValue('light', 'dark');
|
||||
|
||||
if (!wagmiClient || !ethereumClient) {
|
||||
return fallback?.() || null;
|
||||
return typeof fallback === 'function' ? fallback() : (fallback || null);
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -29,7 +29,7 @@ const VerifiedAddressesTable = ({ data, applications, onItemEdit, onItemAdd }: P
|
||||
<VerifiedAddressesTableItem
|
||||
key={ item.contractAddress }
|
||||
item={ item }
|
||||
application={ applications?.find(({ tokenAddress }) => tokenAddress === item.contractAddress) }
|
||||
application={ applications?.find(({ tokenAddress }) => tokenAddress.toLowerCase() === item.contractAddress.toLowerCase()) }
|
||||
onAdd={ onItemAdd }
|
||||
onEdit={ onItemEdit }
|
||||
/>
|
||||
|
||||