Skip to content

Commit

Permalink
Merge pull request #1657 from oasisprotocol/mz/addrTests
Browse files Browse the repository at this point in the history
Add tests to Address Book
  • Loading branch information
buberdds authored Sep 12, 2023
2 parents 9932308 + 05a0460 commit dae6efe
Show file tree
Hide file tree
Showing 10 changed files with 1,490 additions and 22 deletions.
64 changes: 64 additions & 0 deletions playwright/tests/syncTabs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,70 @@ test.describe('syncTabs', () => {
}
})

test.describe('adding and removing contacts in tabs', () => {
test('unpersisted', async ({ page, context }) => {
await page.goto('/open-wallet/private-key')
await fillPrivateKeyWithoutPassword(page, {
persistenceCheckboxChecked: false,
persistenceCheckboxDisabled: false,
})
const tab2 = await context.newPage()
await testSyncingContacts(page, tab2)
})

test('persisted', async ({ page, context }) => {
await addPersistedStorage(page)
await page.goto('/')
await page.getByPlaceholder('Enter your password here').fill(password)
await page.keyboard.press('Enter')
const tab2 = await context.newPage()
await testSyncingContacts(page, tab2)
})

test('incognito', async ({ page, context }) => {
await addPersistedStorage(page)
await page.goto('/')
await page.getByRole('button', { name: 'Continue without the profile' }).click()
const tab2 = await context.newPage()
await tab2.goto('/open-wallet/private-key')
await fillPrivateKeyWithoutPassword(tab2, {
persistenceCheckboxChecked: false,
persistenceCheckboxDisabled: true,
})
await testSyncingContacts(page, tab2)
})

async function testSyncingContacts(page: Page, tab2: Page) {
await page.getByTestId('account-selector').click()
await page.getByTestId('toolbar-contacts-tab').click()
await page.getByText('You have no contacts yet.')

await tab2.goto('/')
await tab2.getByTestId('account-selector').click()
await tab2.getByTestId('toolbar-contacts-tab').click()
await tab2.getByRole('button', { name: 'Add Contact' }).click()
await tab2.getByPlaceholder('Name').fill('Foo')
await tab2
.getByPlaceholder('Address', { exact: true })
.fill('oasis1qq2vzcvxn0js5unsch5me2xz4kr43vcasv0d5eq4')
await tab2.getByRole('button', { name: 'Save' }).click()
await expect(tab2.getByTestId('account-choice')).toHaveCount(1)
await expect(page.getByTestId('account-choice')).toHaveCount(1)

await page.getByRole('button', { name: 'Manage' }).click()
await page.getByPlaceholder('Name').fill('Bar')
await page.getByRole('button', { name: 'Cancel' }).click()
await expect(page.getByTestId('account-name')).toHaveText('Foo')
await expect(tab2.getByTestId('account-name')).toHaveText('Foo')

await page.getByRole('button', { name: 'Manage' }).click()
await page.getByRole('button', { name: 'Delete contact' }).click()
await page.getByRole('button', { name: 'Yes, delete' }).click()
await expect(page.getByText('You have no contacts yet.')).toBeVisible()
await expect(tab2.getByText('You have no contacts yet.')).toBeVisible()
}
})

test.describe('switching account should not sync', () => {
test('unpersisted', async ({ page, context }) => {
await page.goto('/open-wallet/private-key')
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/Toolbar/Features/Account/Account.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { BalanceDetails } from '../../../../state/account/types'
import { Button } from 'grommet/es6/components/Button'
import { DerivationFormatter, DerivationFormatterProps } from './DerivationFormatter'

interface AccountProps {
export interface AccountProps {
address: string
balance: BalanceDetails | undefined
onClick: (address: string) => void
Expand Down Expand Up @@ -69,7 +69,7 @@ export const Account = memo((props: AccountProps) => {

<Box flex="grow" gap={size === 'small' ? undefined : 'xsmall'}>
{props.name && (
<Box>
<Box data-testid="account-name">
<Text weight="bold">{props.name}</Text>
</Box>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
import { render } from '@testing-library/react'
import { render, screen } from '@testing-library/react'
import { WalletType } from 'app/state/wallet/types'
import * as React from 'react'
import { Provider } from 'react-redux'
import { configureAppStore } from 'store/configureStore'
import { ThemeProvider } from 'styles/theme/ThemeProvider'
import { Account, AccountProps } from '../Account'

import { Account } from '../Account'
const props = {
address: 'oasis1qq3xrq0urs8qcffhvmhfhz4p0mu7ewc8rscnlwxe',
balance: { available: '200', debonding: '0', delegations: '800', total: '1000' },
onClick: () => {},
isActive: false,
displayBalance: true,
displayCheckbox: true,
displayAccountNumber: true,
path: [44, 474, 0, 0, 0],
displayDerivation: {
type: WalletType.Mnemonic,
pathDisplay: "m/44'/474'/0'/0'/0'",
},
name: 'My Account',
}

const renderComponent = (store: any) =>
const renderComponent = (store: any, props: AccountProps) =>
render(
<Provider store={store}>
<ThemeProvider>
<Account
address="oasis1qq3xrq0urs8qcffhvmhfhz4p0mu7ewc8rscnlwxe"
balance={{ available: '200', debonding: '0', delegations: '800', total: '1000' }}
onClick={() => {}}
isActive={false}
displayBalance={true}
displayCheckbox={true}
displayAccountNumber={true}
path={[44, 474, 0, 0, 0]}
displayDerivation={{
type: WalletType.Mnemonic,
pathDisplay: "m/44'/474'/0'/0'/0'",
}}
/>
<Account {...props} />
</ThemeProvider>
</Provider>,
)
Expand All @@ -37,7 +38,13 @@ describe('<Account />', () => {
})

it('should match snapshot', () => {
const component = renderComponent(store)
const component = renderComponent(store, props)
expect(component.baseElement).toMatchSnapshot()
})

it('should render without name', () => {
const propsWithoutName = { ...props, name: undefined }
renderComponent(store, propsWithoutName)
expect(screen.queryByTestId('account-name')).not.toBeInTheDocument()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,16 @@ exports[`<Account /> should match snapshot 1`] = `
<div
class="c10"
>
<div
class="c11"
data-testid="account-name"
>
<span
class="c9"
>
My Account
</span>
</div>
<div
class="c11"
>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { render } from '@testing-library/react'
import { Provider } from 'react-redux'
import { configureAppStore } from 'store/configureStore'
import { ThemeProvider } from 'styles/theme/ThemeProvider'
import { AddContact } from '../AddContact'

const renderComponent = (store: any) =>
render(
<Provider store={store}>
<ThemeProvider>
<AddContact setLayerVisibility={() => {}} />
</ThemeProvider>
</Provider>,
)

describe('<AddContact />', () => {
let store: ReturnType<typeof configureAppStore>

beforeEach(() => {
store = configureAppStore()
})

it('should match snapshot', () => {
const component = renderComponent(store)
expect(component.baseElement).toMatchSnapshot()
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { Provider } from 'react-redux'
import { configureAppStore } from 'store/configureStore'
import { ThemeProvider } from 'styles/theme/ThemeProvider'
import { Contact } from 'app/state/contacts/types'
import { ContactAccountForm } from '../ContactAccountForm'

const contact = {
address: 'oasis1qq2vzcvxn0js5unsch5me2xz4kr43vcasv0d5eq4',
name: 'My Contact',
}
const onCancel = jest.fn()
const onDelete = jest.fn()
const onSave = jest.fn()
const renderComponent = (store: any, contact?: Contact, onDelete?: () => void) =>
render(
<Provider store={store}>
<ThemeProvider>
<ContactAccountForm onCancel={onCancel} onSave={onSave} contact={contact} onDelete={onDelete} />
</ThemeProvider>
</Provider>,
)

describe('<ContactAccountForm />', () => {
let store: ReturnType<typeof configureAppStore>

beforeEach(() => {
store = configureAppStore()
})

it('should throw required field error', async () => {
renderComponent(store)
await userEvent.click(screen.getByRole('button', { name: 'toolbar.contacts.save' }))
expect(screen.getAllByText('toolbar.contacts.validation.required').length).toEqual(2)
expect(onSave).not.toHaveBeenCalled()
})

it('should throw name length error', async () => {
renderComponent(store)
await userEvent.type(screen.getByPlaceholderText('toolbar.contacts.name'), 'fooBarFooBarFooBar')
await userEvent.click(screen.getByRole('button', { name: 'toolbar.contacts.save' }))
expect(screen.getByText('toolbar.contacts.validation.nameLengthError')).toBeInTheDocument()
expect(onSave).not.toHaveBeenCalled()
})

it('should throw address error', async () => {
renderComponent(store)
await userEvent.type(screen.getByPlaceholderText('toolbar.contacts.address'), 'fooBar')
await userEvent.click(screen.getByRole('button', { name: 'toolbar.contacts.save' }))
expect(screen.getByText('toolbar.contacts.validation.addressError')).toBeInTheDocument()
expect(onSave).not.toHaveBeenCalled()
})

it('should throw unique address error', async () => {
const storeWithContacts = configureAppStore({
contacts: {
oasis1qq2vzcvxn0js5unsch5me2xz4kr43vcasv0d5eq4: contact,
},
})
renderComponent(storeWithContacts)
await userEvent.type(
screen.getByPlaceholderText('toolbar.contacts.address'),
'oasis1qq2vzcvxn0js5unsch5me2xz4kr43vcasv0d5eq4',
)
await userEvent.click(screen.getByRole('button', { name: 'toolbar.contacts.save' }))
expect(screen.getByText('toolbar.contacts.validation.addressNotUniqueError')).toBeInTheDocument()
expect(onSave).not.toHaveBeenCalled()
})

it('should submit a form', async () => {
renderComponent(store)
await userEvent.type(screen.getByPlaceholderText('toolbar.contacts.name'), 'FooBar')
await userEvent.type(
screen.getByPlaceholderText('toolbar.contacts.address'),
'oasis1qq2vzcvxn0js5unsch5me2xz4kr43vcasv0d5eq4',
)
await userEvent.click(screen.getByRole('button', { name: 'toolbar.contacts.save' }))
expect(onSave).toHaveBeenCalled()
})

it('should render a form in edit mode', async () => {
renderComponent(store, contact, onDelete)
expect(screen.getByPlaceholderText('toolbar.contacts.address')).toBeDisabled()
await userEvent.click(screen.getByRole('button', { name: 'toolbar.contacts.delete.button' }))
expect(screen.getByText('toolbar.contacts.delete.title')).toBeInTheDocument()
})
})
Loading

0 comments on commit dae6efe

Please sign in to comment.