tests wip
This commit is contained in:
parent
32ae4ff807
commit
fe82ee0c7e
|
@ -12,10 +12,11 @@ type Props = {
|
|||
margin?: 'xs' | 'sm' | 'md' | 'lg' | 'xl',
|
||||
align?: 'center' | 'end' | 'start',
|
||||
grow?: boolean,
|
||||
testId?: string,
|
||||
}
|
||||
|
||||
const Row = ({
|
||||
children, className, margin, align, grow, ...props
|
||||
children, className, margin, align, grow, testId = '', ...props
|
||||
}: Props) => {
|
||||
const rowClassNames = cx(
|
||||
styles.row,
|
||||
|
@ -26,7 +27,7 @@ const Row = ({
|
|||
)
|
||||
|
||||
return (
|
||||
<div className={rowClassNames} {...props}>
|
||||
<div className={rowClassNames} data-testid={testId} {...props}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import ListItem from '@material-ui/core/ListItem'
|
||||
import Avatar from '@material-ui/core/Avatar'
|
||||
import Mail from '@material-ui/icons/Mail'
|
||||
import ListItemText from '~/components/List/ListItemText'
|
||||
|
||||
type Props = {
|
||||
address: string,
|
||||
}
|
||||
|
||||
const Address = ({ address }: Props) => (
|
||||
<ListItem>
|
||||
<Avatar>
|
||||
<Mail />
|
||||
</Avatar>
|
||||
<ListItemText primary="Safe Address" secondary={address} cut />
|
||||
</ListItem>
|
||||
)
|
||||
|
||||
export default Address
|
|
@ -1,80 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import classNames from 'classnames'
|
||||
import AccountBalance from '@material-ui/icons/AccountBalance'
|
||||
import Avatar from '@material-ui/core/Avatar'
|
||||
import Collapse from '@material-ui/core/Collapse'
|
||||
import IconButton from '@material-ui/core/IconButton'
|
||||
import List from '@material-ui/core/List'
|
||||
import Img from '~/components/layout/Img'
|
||||
import ListItem from '@material-ui/core/ListItem'
|
||||
import ListItemIcon from '@material-ui/core/ListItemIcon'
|
||||
import ListItemText from '@material-ui/core/ListItemText'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import ExpandLess from '@material-ui/icons/ExpandLess'
|
||||
import ExpandMore from '@material-ui/icons/ExpandMore'
|
||||
import { Map } from 'immutable'
|
||||
import Button from '~/components/layout/Button'
|
||||
import openHoc, { type Open } from '~/components/hoc/OpenHoc'
|
||||
import { type WithStyles } from '~/theme/mui'
|
||||
import { type Token } from '~/logic/tokens/store/model/token'
|
||||
|
||||
type Props = Open & WithStyles & {
|
||||
tokens: Map<string, Token>,
|
||||
onMoveFunds: (token: Token) => void,
|
||||
}
|
||||
|
||||
const styles = {
|
||||
nested: {
|
||||
paddingLeft: '40px',
|
||||
},
|
||||
}
|
||||
|
||||
export const MOVE_FUNDS_BUTTON_TEXT = 'Move'
|
||||
|
||||
const BalanceComponent = openHoc(({
|
||||
open, toggle, tokens, classes, onMoveFunds,
|
||||
}: Props) => {
|
||||
const hasBalances = tokens.count() > 0
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<ListItem onClick={hasBalances ? toggle : undefined}>
|
||||
<Avatar>
|
||||
<AccountBalance />
|
||||
</Avatar>
|
||||
<ListItemText primary="Balance" secondary="List of different token balances" />
|
||||
<ListItemIcon>
|
||||
{open
|
||||
? <IconButton disableRipple><ExpandLess /></IconButton>
|
||||
: <IconButton disabled={!hasBalances} disableRipple><ExpandMore /></IconButton>
|
||||
}
|
||||
</ListItemIcon>
|
||||
</ListItem>
|
||||
<Collapse in={open} timeout="auto">
|
||||
<List component="div" disablePadding>
|
||||
{tokens.valueSeq().map((token: Token) => {
|
||||
const symbol = token.get('symbol')
|
||||
const name = token.get('name')
|
||||
const disabled = Number(token.get('funds')) === 0
|
||||
const onMoveFundsClick = () => onMoveFunds(token)
|
||||
|
||||
return (
|
||||
<ListItem key={symbol} className={classNames(classes.nested, symbol)}>
|
||||
<ListItemIcon>
|
||||
<Img src={token.get('logoUri')} height={30} alt={name} />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={name} secondary={`${token.get('funds')} ${symbol}`} />
|
||||
<Button variant="contained" color="primary" onClick={onMoveFundsClick} disabled={disabled}>
|
||||
{MOVE_FUNDS_BUTTON_TEXT}
|
||||
</Button>
|
||||
</ListItem>
|
||||
)
|
||||
})}
|
||||
</List>
|
||||
</Collapse>
|
||||
</React.Fragment>
|
||||
)
|
||||
})
|
||||
|
||||
export default withStyles(styles)(BalanceComponent)
|
|
@ -1,36 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import ListItem from '@material-ui/core/ListItem'
|
||||
import Avatar from '@material-ui/core/Avatar'
|
||||
import DoneAll from '@material-ui/icons/DoneAll'
|
||||
import ListItemText from '~/components/List/ListItemText'
|
||||
import Button from '~/components/layout/Button'
|
||||
|
||||
type Props = {
|
||||
confirmations: number,
|
||||
onEditThreshold: () => void,
|
||||
}
|
||||
|
||||
const EDIT_THRESHOLD_BUTTON_TEXT = 'EDIT'
|
||||
|
||||
const Confirmations = ({ confirmations, onEditThreshold }: Props) => (
|
||||
<ListItem>
|
||||
<Avatar>
|
||||
<DoneAll />
|
||||
</Avatar>
|
||||
<ListItemText
|
||||
primary="Confirmations"
|
||||
secondary={`${confirmations} required confirmations per transaction`}
|
||||
cut
|
||||
/>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={onEditThreshold}
|
||||
>
|
||||
{EDIT_THRESHOLD_BUTTON_TEXT}
|
||||
</Button>
|
||||
</ListItem>
|
||||
)
|
||||
|
||||
export default Confirmations
|
|
@ -1,35 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import ListItem from '@material-ui/core/ListItem'
|
||||
import Avatar from '@material-ui/core/Avatar'
|
||||
import AcoountBalanceWallet from '@material-ui/icons/AccountBalanceWallet'
|
||||
import Button from '~/components/layout/Button'
|
||||
import ListItemText from '~/components/List/ListItemText'
|
||||
|
||||
type Props = {
|
||||
onSeeTxs: () => void,
|
||||
}
|
||||
|
||||
export const SEE_MULTISIG_BUTTON_TEXT = 'TXs'
|
||||
|
||||
const MultisigTransactionsComponent = ({ onSeeTxs }: Props) => {
|
||||
const text = 'See multisig txs executed on this Safe'
|
||||
|
||||
return (
|
||||
<ListItem>
|
||||
<Avatar>
|
||||
<AcoountBalanceWallet />
|
||||
</Avatar>
|
||||
<ListItemText primary="Safe's Multisig Transaction" secondary={text} />
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={onSeeTxs}
|
||||
>
|
||||
{SEE_MULTISIG_BUTTON_TEXT}
|
||||
</Button>
|
||||
</ListItem>
|
||||
)
|
||||
}
|
||||
|
||||
export default MultisigTransactionsComponent
|
|
@ -1,91 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import openHoc, { type Open } from '~/components/hoc/OpenHoc'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import Collapse from '@material-ui/core/Collapse'
|
||||
import ListItemText from '~/components/List/ListItemText'
|
||||
import List from '@material-ui/core/List'
|
||||
import ListItem from '@material-ui/core/ListItem'
|
||||
import ListItemIcon from '@material-ui/core/ListItemIcon'
|
||||
import Avatar from '@material-ui/core/Avatar'
|
||||
import IconButton from '@material-ui/core/IconButton'
|
||||
import Button from '~/components/layout/Button'
|
||||
import Group from '@material-ui/icons/Group'
|
||||
import Delete from '@material-ui/icons/Delete'
|
||||
import Person from '@material-ui/icons/Person'
|
||||
import ExpandLess from '@material-ui/icons/ExpandLess'
|
||||
import ExpandMore from '@material-ui/icons/ExpandMore'
|
||||
import { type OwnerProps } from '~/routes/safe/store/models/owner'
|
||||
import { type WithStyles } from '~/theme/mui'
|
||||
import { sameAddress } from '~/logic/wallets/ethAddresses'
|
||||
|
||||
const styles = {
|
||||
nested: {
|
||||
paddingLeft: '40px',
|
||||
},
|
||||
}
|
||||
|
||||
type Props = Open & WithStyles & {
|
||||
owners: List<OwnerProps>,
|
||||
userAddress: string,
|
||||
onAddOwner: () => void,
|
||||
onRemoveOwner: (name: string, addres: string) => void,
|
||||
}
|
||||
|
||||
export const ADD_OWNER_BUTTON_TEXT = 'Add'
|
||||
export const REMOVE_OWNER_BUTTON_TEXT = 'Delete'
|
||||
|
||||
const Owners = openHoc(({
|
||||
open, toggle, owners, classes, onAddOwner, userAddress, onRemoveOwner,
|
||||
}: Props) => (
|
||||
<React.Fragment>
|
||||
<ListItem onClick={toggle}>
|
||||
<Avatar>
|
||||
<Group />
|
||||
</Avatar>
|
||||
<ListItemText primary="Owners" secondary={`${owners.size} owners`} />
|
||||
<ListItemIcon>
|
||||
{open
|
||||
? <IconButton disableRipple><ExpandLess /></IconButton>
|
||||
: <IconButton disableRipple><ExpandMore /></IconButton>
|
||||
}
|
||||
</ListItemIcon>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={onAddOwner}
|
||||
>
|
||||
{ADD_OWNER_BUTTON_TEXT}
|
||||
</Button>
|
||||
</ListItem>
|
||||
<Collapse in={open} timeout="auto" unmountOnExit>
|
||||
<List component="div" disablePadding>
|
||||
{owners.map((owner) => {
|
||||
const onRemoveIconClick = () => onRemoveOwner(owner.name, owner.address)
|
||||
|
||||
return (
|
||||
<ListItem key={owner.address} className={classes.nested}>
|
||||
<ListItemIcon>
|
||||
<Person />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
cut
|
||||
primary={owner.name}
|
||||
secondary={owner.address}
|
||||
/>
|
||||
{ !sameAddress(userAddress, owner.address)
|
||||
&& (
|
||||
<IconButton aria-label="Delete" onClick={onRemoveIconClick}>
|
||||
<Delete />
|
||||
</IconButton>
|
||||
)
|
||||
}
|
||||
</ListItem>
|
||||
)
|
||||
})}
|
||||
</List>
|
||||
</Collapse>
|
||||
</React.Fragment>
|
||||
))
|
||||
|
||||
export default withStyles(styles)(Owners)
|
|
@ -1,17 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
|
||||
<defs>
|
||||
<linearGradient id="a" x1="0%" y1="50.001%" y2="50.001%">
|
||||
<stop offset="0%" stop-color="#00B3CE"/>
|
||||
<stop offset="100%" stop-color="#00C8DD"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g fill="none" fill-rule="nonzero">
|
||||
<circle cx="250" cy="250" r="250" fill="url(#a)"/>
|
||||
<g fill="#FFF">
|
||||
<path d="M189.93 245.903l-49.95-49.674c-4.508 6.049-7.237 13.563-7.237 21.674 0 19.583 15.972 35.52 35.528 35.52 8.118 0 15.66-2.715 21.66-7.52z"/>
|
||||
<path d="M248.639 71.028c-52.077 0-100.542 21.097-136.063 58.694l-5.708 6.042 143.84 144.48v25.923l-.555.562-37.007-37.326c-17.18 11.423-39.153 14.757-59.903 7.528-34.924-12.653-53-50.882-40.361-85.5 1.826-5.41 4.52-10.23 7.52-14.743l-15.937-15.959-3.014 5.118c-16.555 27.104-25.597 58.403-25.597 90.59-.285 96.042 77.965 174.577 173.965 174.577h29.396V71.056l-30.576-.028zm-118.292 64.729c31.945-31.02 73.743-47.854 118.611-47.854h.285c.5 0 .993 0 1.465.02v168.5l-120.36-120.666z"/>
|
||||
<path d="M248.639 71.028c-52.077 0-100.542 21.097-136.063 58.694l-5.708 6.042 143.84 144.48v25.923l-.555.562-37.007-37.326c-17.18 11.423-39.153 14.757-59.903 7.528-34.924-12.653-53-50.882-40.361-85.5 1.826-5.41 4.52-10.23 7.52-14.743l-15.937-15.959-3.014 5.118c-16.555 27.104-25.597 58.403-25.597 90.59-.285 96.042 77.965 174.577 173.965 174.577h29.396V71.056l-30.576-.028zm-118.292 64.729c31.945-31.02 73.743-47.854 118.611-47.854h.285c.5 0 .993 0 1.465.02v168.5l-120.36-120.666zM423.611 250.41c0-79.618-64.764-144.417-144.389-144.473v17.3c70.104.027 127.125 57.069 127.125 127.166 0 70.11-57.02 127.166-127.125 127.194v17.278c79.625-.035 144.39-64.813 144.39-144.465z"/>
|
||||
<path d="M314.549 250.486l-6.855 42.98h33.577l-6.854-42.98c7.646-3.743 12.944-11.59 12.944-20.708 0-12.702-10.236-23-22.868-23-12.632 0-22.875 10.298-22.875 23-.014 9.132 5.285 16.965 12.93 20.708zM303.25 152.986c9.028 2.333 12.507-11.201 3.48-13.528-9.015-2.312-12.508 11.223-3.48 13.528M342.868 173.549c7.139 5.972 16.111-4.73 8.972-10.702-7.11-6-16.104 4.715-8.972 10.702M368.333 206.944c4.105 8.362 16.646 2.223 12.549-6.138-4.09-8.369-16.646-2.209-12.549 6.138M303.25 347.618c9.028-2.326 12.507 11.23 3.48 13.549-9.015 2.305-12.508-11.23-3.48-13.549M342.868 327.07c7.139-5.98 16.111 4.729 8.972 10.687-7.11 6.014-16.104-4.701-8.972-10.688M368.333 293.66c4.105-8.361 16.646-2.202 12.549 6.166-4.09 8.34-16.646 2.202-12.549-6.166M378.424 250.826c0 9.334 13.958 9.334 13.958 0 0-9.312-13.958-9.312-13.958 0"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.6 KiB |
|
@ -1,135 +0,0 @@
|
|||
// @flow
|
||||
import ListComponent from '@material-ui/core/List'
|
||||
import * as React from 'react'
|
||||
import { List } from 'immutable'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Bold from '~/components/layout/Bold'
|
||||
import Img from '~/components/layout/Img'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import Row from '~/components/layout/Row'
|
||||
import { type Safe } from '~/routes/safe/store/models/safe'
|
||||
import { type Token } from '~/logic/tokens/store/model/token'
|
||||
|
||||
import Transactions from '~/routes/safe/components/Transactions'
|
||||
import Threshold from '~/routes/safe/components/Threshold'
|
||||
import AddOwner from '~/routes/safe/components/AddOwner'
|
||||
import RemoveOwner from '~/routes/safe/components/RemoveOwner'
|
||||
import SendToken from '~/routes/safe/components/SendToken'
|
||||
|
||||
import Address from './Address'
|
||||
import BalanceInfo from './BalanceInfo'
|
||||
import Owners from './Owners'
|
||||
import Confirmations from './Confirmations'
|
||||
import MultisigTx from './MultisigTx'
|
||||
|
||||
const safeIcon = require('./assets/gnosis_safe.svg')
|
||||
|
||||
type SafeProps = {
|
||||
safe: Safe,
|
||||
tokens: List<Token>,
|
||||
userAddress: string,
|
||||
}
|
||||
|
||||
type State = {
|
||||
component?: React.Node,
|
||||
}
|
||||
|
||||
const listStyle = {
|
||||
width: '100%',
|
||||
}
|
||||
|
||||
class GnoSafe extends React.PureComponent<SafeProps, State> {
|
||||
state = {
|
||||
component: undefined,
|
||||
}
|
||||
|
||||
onListTransactions = () => {
|
||||
const { safe } = this.props
|
||||
|
||||
this.setState({
|
||||
component: (
|
||||
<Transactions threshold={safe.get('threshold')} safeName={safe.get('name')} safeAddress={safe.get('address')} />
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
onEditThreshold = () => {
|
||||
const { safe } = this.props
|
||||
|
||||
this.setState({
|
||||
component: <Threshold numOwners={safe.get('owners').count()} safe={safe} onReset={this.onListTransactions} />,
|
||||
})
|
||||
}
|
||||
|
||||
onAddOwner = (e: SyntheticEvent<HTMLButtonElement>) => {
|
||||
const { safe } = this.props
|
||||
e.stopPropagation()
|
||||
this.setState({ component: <AddOwner threshold={safe.get('threshold')} safe={safe} /> })
|
||||
}
|
||||
|
||||
onRemoveOwner = (name: string, address: string) => {
|
||||
const { safe } = this.props
|
||||
|
||||
this.setState({
|
||||
component: (
|
||||
<RemoveOwner
|
||||
safeAddress={safe.get('address')}
|
||||
threshold={safe.get('threshold')}
|
||||
safe={safe}
|
||||
name={name}
|
||||
userToRemove={address}
|
||||
/>
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
onMoveTokens = (ercToken: Token) => {
|
||||
const { safe } = this.props
|
||||
|
||||
this.setState({
|
||||
component: (
|
||||
<SendToken safe={safe} token={ercToken} key={ercToken.get('address')} onReset={this.onListTransactions} />
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const { safe, tokens, userAddress } = this.props
|
||||
const { component } = this.state
|
||||
const address = safe.get('address')
|
||||
|
||||
return (
|
||||
<Row grow>
|
||||
<Col sm={12} top="xs" md={5} margin="xl" overflow>
|
||||
<ListComponent style={listStyle}>
|
||||
<BalanceInfo tokens={tokens} onMoveFunds={this.onMoveTokens} safeAddress={address} />
|
||||
<Owners
|
||||
owners={safe.owners}
|
||||
onAddOwner={this.onAddOwner}
|
||||
userAddress={userAddress}
|
||||
onRemoveOwner={this.onRemoveOwner}
|
||||
/>
|
||||
<Confirmations confirmations={safe.get('threshold')} onEditThreshold={this.onEditThreshold} />
|
||||
<Address address={address} />
|
||||
<MultisigTx onSeeTxs={this.onListTransactions} />
|
||||
</ListComponent>
|
||||
</Col>
|
||||
<Col sm={12} center="xs" md={7} margin="xl" layout="column">
|
||||
<Block margin="xl">
|
||||
<Paragraph size="lg" noMargin align="right">
|
||||
<Bold>{safe.name.toUpperCase()}</Bold>
|
||||
</Paragraph>
|
||||
</Block>
|
||||
<Row grow>
|
||||
<Col sm={12} center={component ? undefined : 'sm'} middle={component ? undefined : 'sm'} layout="column">
|
||||
{component || <Img alt="Safe Icon" src={safeIcon} height={330} />}
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default GnoSafe
|
|
@ -22,6 +22,9 @@ import Modal from '~/components/Modal'
|
|||
import { styles } from './style'
|
||||
import { secondary } from '~/theme/variables'
|
||||
|
||||
export const RENAME_OWNER_INPUT_TESTID = 'rename-owner-input'
|
||||
export const SAVE_OWNER_CHANGES_BTN_TESTID = 'save-owner-changes-btn'
|
||||
|
||||
const openIconStyle = {
|
||||
height: '16px',
|
||||
color: secondary,
|
||||
|
@ -96,6 +99,7 @@ const EditOwnerComponent = ({
|
|||
text="Owner name*"
|
||||
initialValue={selectedOwnerName}
|
||||
className={classes.addressInput}
|
||||
testId={RENAME_OWNER_INPUT_TESTID}
|
||||
/>
|
||||
</Row>
|
||||
<Row>
|
||||
|
@ -115,7 +119,7 @@ const EditOwnerComponent = ({
|
|||
<Button className={classes.button} minWidth={140} onClick={onClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button type="submit" className={classes.button} variant="contained" minWidth={140} color="primary">
|
||||
<Button type="submit" className={classes.button} variant="contained" minWidth={140} color="primary" testId={SAVE_OWNER_CHANGES_BTN_TESTID}>
|
||||
Save
|
||||
</Button>
|
||||
</Row>
|
||||
|
|
|
@ -29,7 +29,7 @@ type Props = {
|
|||
network: string,
|
||||
threshold: string,
|
||||
createTransaction: Function,
|
||||
updateSafe: Function
|
||||
updateSafe: Function,
|
||||
}
|
||||
type ActiveScreen = 'checkOwner' | 'reviewReplaceOwner'
|
||||
|
||||
|
|
|
@ -28,6 +28,9 @@ import ReplaceOwnerIcon from './assets/icons/replace-owner.svg'
|
|||
import RenameOwnerIcon from './assets/icons/rename-owner.svg'
|
||||
import RemoveOwnerIcon from '../assets/icons/bin.svg'
|
||||
|
||||
export const RENAME_OWNER_BTN_TESTID = 'rename-owner-btn'
|
||||
export const OWNERS_ROW_TESTID = 'owners-row'
|
||||
|
||||
const controlsStyle = {
|
||||
backgroundColor: 'white',
|
||||
padding: sm,
|
||||
|
@ -120,7 +123,7 @@ class ManageOwners extends React.Component<Props, State> {
|
|||
</Paragraph>
|
||||
<Table label="owners" columns={columns} data={ownerData} size={ownerData.size} defaultFixed noBorder>
|
||||
{(sortedData: Array<OwnerRow>) => sortedData.map((row: any, index: number) => (
|
||||
<TableRow tabIndex={-1} key={index} className={classes.hide}>
|
||||
<TableRow tabIndex={-1} key={index} className={classes.hide} date-testid={OWNERS_ROW_TESTID}>
|
||||
{autoColumns.map((column: Column) => (
|
||||
<TableCell key={column.id} style={cellWidth(column.width)} align={column.align} component="td">
|
||||
{column.id === OWNERS_TABLE_ADDRESS_ID ? (
|
||||
|
@ -137,6 +140,7 @@ class ManageOwners extends React.Component<Props, State> {
|
|||
className={classes.editOwnerIcon}
|
||||
src={RenameOwnerIcon}
|
||||
onClick={this.onShow('EditOwner', row)}
|
||||
testId={RENAME_OWNER_BTN_TESTID}
|
||||
/>
|
||||
<Img
|
||||
alt="Replace owner"
|
||||
|
|
|
@ -20,6 +20,8 @@ import actions, { type Actions } from './actions'
|
|||
import { styles } from './style'
|
||||
import RemoveSafeIcon from './assets/icons/bin.svg'
|
||||
|
||||
export const OWNERS_SETTINGS_TAB_TEST_ID = 'owner-settings-tab'
|
||||
|
||||
type State = {
|
||||
showRemoveSafe: boolean,
|
||||
menuOptionIndex: number,
|
||||
|
@ -114,6 +116,7 @@ class Settings extends React.Component<Props, State> {
|
|||
<Row
|
||||
className={cn(classes.menuOption, menuOptionIndex === 2 && classes.active)}
|
||||
onClick={this.handleChange(2)}
|
||||
testId={OWNERS_SETTINGS_TAB_TEST_ID}
|
||||
>
|
||||
Owners (
|
||||
{owners.size}
|
||||
|
|
|
@ -10,7 +10,7 @@ import { SAFE_NAME_INPUT_TESTID, SAFE_NAME_SUBMIT_BTN_TESTID } from '~/routes/sa
|
|||
|
||||
afterEach(cleanup)
|
||||
|
||||
describe('DOM > Feature > Settings', () => {
|
||||
describe('DOM > Feature > Settings - Name', () => {
|
||||
let store
|
||||
let safeAddress
|
||||
beforeEach(async () => {
|
||||
|
|
|
@ -5,12 +5,14 @@ import { aMinedSafe } from '~/test/builder/safe.redux.builder'
|
|||
import { renderSafeView } from '~/test/builder/safe.dom.utils'
|
||||
import { sleep } from '~/utils/timer'
|
||||
import 'jest-dom/extend-expect'
|
||||
import { SETTINGS_TAB_BTN_TESTID, SAFE_VIEW_NAME_HEADING_TESTID } from '~/routes/safe/components/Layout'
|
||||
import { SAFE_NAME_INPUT_TESTID, SAFE_NAME_SUBMIT_BTN_TESTID } from '~/routes/safe/components/Settings/ChangeSafeName'
|
||||
import { SETTINGS_TAB_BTN_TESTID } from '~/routes/safe/components/Layout'
|
||||
import { OWNERS_SETTINGS_TAB_TEST_ID } from '~/routes/safe/components/Settings'
|
||||
import { RENAME_OWNER_BTN_TESTID, OWNERS_ROW_TESTID } from '~/routes/safe/components/Settings/ManageOwners'
|
||||
import { RENAME_OWNER_INPUT_TESTID, SAVE_OWNER_CHANGES_BTN_TESTID } from '~/routes/safe/components/Settings/ManageOwners/EditOwnerModal'
|
||||
|
||||
afterEach(cleanup)
|
||||
|
||||
describe('DOM > Feature > Settings > Manage owners', () => {
|
||||
describe('DOM > Feature > Settings - Manage owners', () => {
|
||||
let store
|
||||
let safeAddress
|
||||
beforeEach(async () => {
|
||||
|
@ -20,6 +22,34 @@ describe('DOM > Feature > Settings > Manage owners', () => {
|
|||
})
|
||||
|
||||
it('Changes owner\'s name', async () => {
|
||||
const NEW_OWNER_NAME = 'NEW OWNER NAME'
|
||||
|
||||
const SafeDom = renderSafeView(store, safeAddress)
|
||||
await sleep(1300)
|
||||
|
||||
// Travel to settings
|
||||
const settingsBtn = SafeDom.getByTestId(SETTINGS_TAB_BTN_TESTID)
|
||||
fireEvent.click(settingsBtn)
|
||||
await sleep(200)
|
||||
|
||||
// click on owners settings
|
||||
const ownersSettingsBtn = SafeDom.getByTestId(OWNERS_SETTINGS_TAB_TEST_ID)
|
||||
fireEvent.click(ownersSettingsBtn)
|
||||
await sleep(200)
|
||||
|
||||
// open rename owner modal
|
||||
const renameOwnerBtn = SafeDom.getByTestId(RENAME_OWNER_BTN_TESTID)
|
||||
fireEvent.click(renameOwnerBtn)
|
||||
|
||||
// rename owner
|
||||
const ownerNameInput = SafeDom.getByTestId(RENAME_OWNER_INPUT_TESTID)
|
||||
const saveOwnerChangesBtn = SafeDom.getByTestId(SAVE_OWNER_CHANGES_BTN_TESTID)
|
||||
fireEvent.change(ownerNameInput, { target: { value: NEW_OWNER_NAME } })
|
||||
fireEvent.click(saveOwnerChangesBtn)
|
||||
await sleep(200)
|
||||
|
||||
// check if the name updated
|
||||
const ownerRow = SafeDom.getByTestId(OWNERS_ROW_TESTID)
|
||||
expect(ownerRow).toHaveTextContent(NEW_OWNER_NAME)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
// @flow
|
||||
import TestUtils from 'react-dom/test-utils'
|
||||
import { sleep } from '~/utils/timer'
|
||||
import { checkMinedTx, checkPendingTx } from '~/test/builder/safe.dom.utils'
|
||||
import { whenExecuted } from '~/test/utils/logTransactions'
|
||||
import AddOwner from '~/routes/safe/components/AddOwner'
|
||||
|
||||
export const sendAddOwnerForm = async (
|
||||
SafeDom: React.Component<any, any>,
|
||||
addOwner: React.Component<any, any>,
|
||||
ownerName: string,
|
||||
ownerAddress: string,
|
||||
increase: boolean = false,
|
||||
) => {
|
||||
// load add multisig form component
|
||||
TestUtils.Simulate.click(addOwner)
|
||||
// give time to re-render it
|
||||
await sleep(400)
|
||||
|
||||
// fill the form
|
||||
const inputs = TestUtils.scryRenderedDOMComponentsWithTag(SafeDom, 'input')
|
||||
const nameInput = inputs[0]
|
||||
const addressInput = inputs[1]
|
||||
TestUtils.Simulate.change(nameInput, { target: { value: ownerName } })
|
||||
TestUtils.Simulate.change(addressInput, { target: { value: ownerAddress } })
|
||||
|
||||
if (increase) {
|
||||
const increaseInput = inputs[2]
|
||||
TestUtils.Simulate.change(increaseInput, { target: { value: 'true' } })
|
||||
}
|
||||
|
||||
// $FlowFixMe
|
||||
const form = TestUtils.findRenderedDOMComponentWithTag(SafeDom, 'form')
|
||||
|
||||
// submit it
|
||||
TestUtils.Simulate.submit(form)
|
||||
TestUtils.Simulate.submit(form)
|
||||
|
||||
return whenExecuted(SafeDom, AddOwner)
|
||||
}
|
||||
|
||||
export const checkMinedAddOwnerTx = (Transaction: React.Component<any, any>, name: string) => {
|
||||
checkMinedTx(Transaction, name)
|
||||
}
|
||||
|
||||
export const checkPendingAddOwnerTx = async (
|
||||
Transaction: React.Component<any, any>,
|
||||
safeThreshold: number,
|
||||
name: string,
|
||||
statusses: string[],
|
||||
) => {
|
||||
await checkPendingTx(Transaction, safeThreshold, name, statusses)
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import TestUtils from 'react-dom/test-utils'
|
||||
import { sleep } from '~/utils/timer'
|
||||
import { checkMinedTx, EXPAND_OWNERS_INDEX, checkPendingTx } from '~/test/builder/safe.dom.utils'
|
||||
import { filterMoveButtonsFrom } from '~/test/builder/safe.dom.builder'
|
||||
import { whenExecuted } from '~/test/utils/logTransactions'
|
||||
import RemoveOwner from '~/routes/safe/components/RemoveOwner'
|
||||
|
||||
export const sendRemoveOwnerForm = async (
|
||||
SafeDom: React.Component<any, any>,
|
||||
expandOwners: React.Component<any, any>,
|
||||
) => {
|
||||
// Expand owners
|
||||
TestUtils.Simulate.click(expandOwners)
|
||||
await sleep(400)
|
||||
|
||||
// Get delete button user
|
||||
const allButtons = TestUtils.scryRenderedDOMComponentsWithTag(SafeDom, 'button')
|
||||
const buttons = filterMoveButtonsFrom(allButtons)
|
||||
const removeUserButton = buttons[EXPAND_OWNERS_INDEX + 2] // + 2 one the Add and the next delete
|
||||
expect(removeUserButton.getAttribute('aria-label')).toBe('Delete')
|
||||
|
||||
// render form for deleting the user
|
||||
TestUtils.Simulate.click(removeUserButton)
|
||||
await sleep(400)
|
||||
|
||||
// $FlowFixMe
|
||||
const form = TestUtils.findRenderedDOMComponentWithTag(SafeDom, 'form')
|
||||
|
||||
// submit it
|
||||
TestUtils.Simulate.submit(form)
|
||||
TestUtils.Simulate.submit(form)
|
||||
|
||||
return whenExecuted(SafeDom, RemoveOwner)
|
||||
}
|
||||
|
||||
export const checkMinedRemoveOwnerTx = (Transaction: React.Component<any, any>, name: string) => {
|
||||
checkMinedTx(Transaction, name)
|
||||
}
|
||||
|
||||
export const checkPendingRemoveOwnerTx = async (
|
||||
Transaction: React.Component<any, any>,
|
||||
safeThreshold: number,
|
||||
name: string,
|
||||
statusses: string[],
|
||||
) => {
|
||||
await checkPendingTx(Transaction, safeThreshold, name, statusses)
|
||||
}
|
Loading…
Reference in New Issue