-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generic chain key component, render Solana, Aptos and Starknet
- Loading branch information
Showing
8 changed files
with
358 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import * as React from 'react' | ||
|
||
import { render, screen } from 'support/test-utils' | ||
|
||
import { CSAKeyRow } from './CSAKeyRow' | ||
import { buildCSAKey } from 'support/factories/gql/fetchCSAKeys' | ||
|
||
const { queryByText } = screen | ||
|
||
describe('CSAKeyRow', () => { | ||
function renderComponent(csaKey: CsaKeysPayload_ResultsFields) { | ||
render( | ||
<table> | ||
<tbody> | ||
<CSAKeyRow csaKey={csaKey} /> | ||
</tbody> | ||
</table>, | ||
) | ||
} | ||
|
||
it('renders a row', () => { | ||
const csaKey = buildCSAKey() | ||
|
||
renderComponent(csaKey) | ||
|
||
expect(queryByText(csaKey.publicKey)).toBeInTheDocument() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import React from 'react' | ||
|
||
import TableCell from '@material-ui/core/TableCell' | ||
import TableRow from '@material-ui/core/TableRow' | ||
import Typography from '@material-ui/core/Typography' | ||
|
||
import { CopyIconButton } from 'src/components/Copy/CopyIconButton' | ||
|
||
interface Props { | ||
chainKey: any | ||
fields: any[] | ||
} | ||
|
||
export const NonEVMKeyRow: React.FC<Props> = ({ chainKey, fields }) => { | ||
return ( | ||
<TableRow hover> | ||
{fields.map((field, idx) => ( | ||
<TableCell key={idx}> | ||
<Typography variant="body1"> | ||
{chainKey[field.key]} {field.copy && (<CopyIconButton data={chainKey[field.key]} />)} | ||
</Typography> | ||
</TableCell> | ||
))} | ||
</TableRow> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import * as React from 'react' | ||
|
||
import { GraphQLError } from 'graphql' | ||
import { renderWithRouter, screen } from 'support/test-utils' | ||
import { MockedProvider, MockedResponse } from '@apollo/client/testing' | ||
|
||
import { CSAKeys, CSA_KEYS_QUERY } from './CSAKeys' | ||
import { buildCSAKeys } from 'support/factories/gql/fetchCSAKeys' | ||
import Notifications from 'pages/Notifications' | ||
import { waitForLoading } from 'support/test-helpers/wait' | ||
|
||
const { findByText } = screen | ||
|
||
function renderComponent(mocks: MockedResponse[]) { | ||
renderWithRouter( | ||
<> | ||
<Notifications /> | ||
<MockedProvider mocks={mocks} addTypename={false}> | ||
<CSAKeys /> | ||
</MockedProvider> | ||
</>, | ||
) | ||
} | ||
|
||
function fetchCSAKeysQuery( | ||
csaKeys: ReadonlyArray<CsaKeysPayload_ResultsFields>, | ||
) { | ||
return { | ||
request: { | ||
query: CSA_KEYS_QUERY, | ||
}, | ||
result: { | ||
data: { | ||
csaKeys: { | ||
results: csaKeys, | ||
}, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
describe('CSAKeys', () => { | ||
it('renders the page', async () => { | ||
const payload = buildCSAKeys() | ||
const mocks: MockedResponse[] = [fetchCSAKeysQuery(payload)] | ||
|
||
renderComponent(mocks) | ||
|
||
await waitForLoading() | ||
|
||
expect(await findByText(payload[0].publicKey)).toBeInTheDocument() | ||
}) | ||
|
||
it('renders GQL query errors', async () => { | ||
const mocks: MockedResponse[] = [ | ||
{ | ||
request: { | ||
query: CSA_KEYS_QUERY, | ||
}, | ||
result: { | ||
errors: [new GraphQLError('Error!')], | ||
}, | ||
}, | ||
] | ||
|
||
renderComponent(mocks) | ||
|
||
expect(await findByText('Error!')).toBeInTheDocument() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import React from 'react' | ||
|
||
import { NonEVMKeysCard } from './NonEVMKeysCard' | ||
import { useNonEvmAccountsQuery } from 'src/hooks/queries/useNonEvmAccountsQuery' | ||
|
||
const SCHEMAS = { | ||
"aptosKeys": { | ||
title: "Aptos", | ||
fields: [{label: "Public Key", key: "id", copy: true}, {label: "Account", key: "account", copy: true}], | ||
}, | ||
"solanaKeys": { | ||
title: "Solana", | ||
fields: [{label: "Public Key", key: "id", copy: true}] | ||
}, | ||
"starknetKeys": { | ||
title: "Starknet", | ||
fields: [{label: "Public Key", key: "id", copy: true}] | ||
} | ||
} | ||
|
||
export const NonEVMKeys = () => { | ||
const { data, loading, error } = useNonEvmAccountsQuery({ | ||
fetchPolicy: 'cache-and-network', | ||
}) | ||
// TODO: | ||
// const [createNonEVMKey] = useMutation<CreateCsaKey, CreateCsaKeyVariables>( | ||
// CREATE_NONEVM_KEY_MUTATION, | ||
// ) | ||
|
||
const handleCreate = async () => { | ||
// try { | ||
// const result = await createNonEVMKey() | ||
// | ||
// const payload = result.data?.createNonEVMKey | ||
// switch (payload?.__typename) { | ||
// case 'CreateNonEVMKeySuccess': | ||
// dispatch(notifySuccessMsg('NonEVM Key created')) | ||
// | ||
// refetch() | ||
// | ||
// break | ||
// } | ||
// } catch (e) { | ||
// handleMutationError(e) | ||
// } | ||
} | ||
|
||
return ( | ||
<> | ||
{data && Object.entries(data).map( | ||
([key, chain]) => (typeof chain === 'object' && "results" in chain) && chain.results?.length > 0 && (<NonEVMKeysCard | ||
loading={loading} | ||
schema={SCHEMAS[key as keyof typeof SCHEMAS] || {title: key, fields: [{label: "Public Key", key: "id", copy: true}]}} | ||
data={chain} | ||
errorMsg={error?.message} | ||
onCreate={handleCreate} | ||
key={key} | ||
/>) | ||
)} | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import * as React from 'react' | ||
|
||
import { render, screen } from 'support/test-utils' | ||
|
||
import { buildCSAKeys } from 'support/factories/gql/fetchCSAKeys' | ||
import { CSAKeysCard, Props as CSAKeysCardProps } from './CSAKeysCard' | ||
import userEvent from '@testing-library/user-event' | ||
|
||
const { getByRole, queryByRole, queryByText } = screen | ||
|
||
function renderComponent(cardProps: CSAKeysCardProps) { | ||
render(<CSAKeysCard {...cardProps} />) | ||
} | ||
|
||
describe('CSAKeysCard', () => { | ||
let handleCreate: jest.Mock | ||
|
||
beforeEach(() => { | ||
handleCreate = jest.fn() | ||
}) | ||
|
||
it('renders the keys', () => { | ||
const csaKeys = buildCSAKeys() | ||
|
||
renderComponent({ | ||
loading: false, | ||
data: { | ||
csaKeys: { | ||
results: csaKeys, | ||
}, | ||
}, | ||
onCreate: handleCreate, | ||
}) | ||
|
||
expect(queryByText(csaKeys[0].publicKey)).toBeInTheDocument() | ||
expect(queryByText(csaKeys[1].publicKey)).toBeInTheDocument() | ||
|
||
// Button should not appear when there are keys present | ||
expect(queryByRole('button', { name: /new csa key/i })).toBeNull() | ||
}) | ||
|
||
it('renders no content', () => { | ||
renderComponent({ | ||
loading: false, | ||
data: { | ||
csaKeys: { | ||
results: [], | ||
}, | ||
}, | ||
onCreate: handleCreate, | ||
}) | ||
|
||
expect(queryByText('No entries to show')).toBeInTheDocument() | ||
|
||
// Button should appear when there are no keys | ||
expect(queryByRole('button', { name: /new csa key/i })).toBeInTheDocument() | ||
}) | ||
|
||
it('renders a loading spinner', () => { | ||
renderComponent({ | ||
loading: true, | ||
onCreate: handleCreate, | ||
}) | ||
|
||
expect(queryByRole('progressbar')).toBeInTheDocument() | ||
}) | ||
|
||
it('renders an error message', () => { | ||
renderComponent({ | ||
loading: false, | ||
errorMsg: 'error message', | ||
onCreate: handleCreate, | ||
}) | ||
|
||
expect(queryByText('error message')).toBeInTheDocument() | ||
}) | ||
|
||
it('calls onCreate', () => { | ||
renderComponent({ | ||
loading: false, | ||
data: { | ||
csaKeys: { | ||
results: [], | ||
}, | ||
}, | ||
onCreate: handleCreate, | ||
}) | ||
|
||
userEvent.click(getByRole('button', { name: /new csa key/i })) | ||
|
||
expect(handleCreate).toHaveBeenCalled() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import React from 'react' | ||
|
||
import Button from '@material-ui/core/Button' | ||
import Card from '@material-ui/core/Card' | ||
import CardHeader from '@material-ui/core/CardHeader' | ||
import Table from '@material-ui/core/Table' | ||
import TableBody from '@material-ui/core/TableBody' | ||
import TableCell from '@material-ui/core/TableCell' | ||
import TableHead from '@material-ui/core/TableHead' | ||
|
||
import { NonEVMKeyRow } from './NonEVMKeyRow' | ||
import { ErrorRow } from 'src/components/TableRow/ErrorRow' | ||
import { LoadingRow } from 'src/components/TableRow/LoadingRow' | ||
import { NoContentRow } from 'src/components/TableRow/NoContentRow' | ||
|
||
export interface Props { | ||
loading: boolean | ||
schema: {title: string, fields: any[]} | ||
data?: any | ||
errorMsg?: string | ||
onCreate: () => void | ||
} | ||
|
||
export const NonEVMKeysCard: React.FC<Props> = ({ | ||
schema, | ||
data, | ||
errorMsg, | ||
loading, | ||
onCreate, | ||
}) => { | ||
return ( | ||
<Card> | ||
<CardHeader | ||
action={ | ||
data?.results?.length === 0 && ( | ||
<Button variant="outlined" color="primary" onClick={onCreate}> | ||
New Key | ||
</Button> | ||
) | ||
} | ||
title={`${schema.title} Keys`} | ||
subheader={`Manage your ${schema.title} Keys`} | ||
/> | ||
<Table> | ||
<TableHead> | ||
{schema.fields.map((field, idx) => ( | ||
<TableCell key={idx}>{field.label}</TableCell> | ||
))} | ||
</TableHead> | ||
<TableBody> | ||
<LoadingRow visible={loading} /> | ||
<NoContentRow visible={data?.results?.length === 0} /> | ||
<ErrorRow msg={errorMsg} /> | ||
|
||
{data?.results?.map((key: string, idx: number) => ( | ||
<NonEVMKeyRow chainKey={key} fields={schema.fields} key={idx} /> | ||
))} | ||
</TableBody> | ||
</Table> | ||
</Card> | ||
) | ||
} |