conflict fix, fix safestorage mware

This commit is contained in:
mmv 2019-07-15 15:52:40 +04:00
commit 78ace6dbf0
19 changed files with 402 additions and 140 deletions

View File

@ -7,6 +7,8 @@ import { getWeb3 } from '~/logic/wallets/getWeb3'
import { calculateGasOf, calculateGasPrice } from '~/logic/wallets/ethTransactions'
import { ZERO_ADDRESS } from '~/logic/wallets/ethAddresses'
export const SENTINEL_ADDRESS = '0x0000000000000000000000000000000000000001'
let proxyFactoryMaster
let safeMaster

View File

@ -4,9 +4,8 @@ import { List } from 'immutable'
import { withStyles } from '@material-ui/core/styles'
import { SharedSnackbarConsumer } from '~/components/SharedSnackBar'
import Modal from '~/components/Modal'
import { type Owner, makeOwner } from '~/routes/safe/store/models/owner'
import { type Owner } from '~/routes/safe/store/models/owner'
import { getGnosisSafeInstanceAt } from '~/logic/contracts/safeContracts'
import { getOwners } from '~/logic/safe/utils'
import OwnerForm from './screens/OwnerForm'
import ThresholdForm from './screens/ThresholdForm'
import ReviewAddOwner from './screens/Review'
@ -28,7 +27,7 @@ type Props = {
owners: List<Owner>,
threshold: number,
network: string,
updateSafe: Function,
addSafeOwner: Function,
createTransaction: Function,
}
type ActiveScreen = 'selectOwner' | 'selectThreshold' | 'reviewAddOwner'
@ -39,29 +38,15 @@ export const sendAddOwner = async (
ownersOld: List<Owner>,
openSnackbar: Function,
createTransaction: Function,
updateSafe: Function,
addSafeOwner: Function,
) => {
const gnosisSafe = await getGnosisSafeInstanceAt(safeAddress)
const txData = gnosisSafe.contract.methods.addOwnerWithThreshold(values.ownerAddress, values.threshold).encodeABI()
const txHash = await createTransaction(safeAddress, safeAddress, 0, txData, openSnackbar)
const owners = []
const storedOwners = await getOwners(safeAddress)
storedOwners.forEach((value, key) => owners.push(makeOwner({
address: key,
name: (values.ownerAddress.toLowerCase() === key.toLowerCase()) ? values.ownerName : value,
})))
const newOwnerIndex = List(owners).findIndex(o => o.address.toLowerCase() === values.ownerAddress.toLowerCase())
if (newOwnerIndex < 0) {
owners.push(makeOwner({ address: values.ownerAddress, name: values.ownerName }))
}
if (txHash) {
updateSafe({
address: safeAddress,
owners: List(owners),
})
addSafeOwner({ safeAddress, ownerName: values.ownerName, ownerAddress: values.ownerAddress })
}
}
@ -75,7 +60,7 @@ const AddOwner = ({
threshold,
network,
createTransaction,
updateSafe,
addSafeOwner,
}: Props) => {
const [activeScreen, setActiveScreen] = useState<ActiveScreen>('selectOwner')
const [values, setValues] = useState<Object>({})
@ -120,7 +105,7 @@ const AddOwner = ({
const onAddOwner = async () => {
onClose()
try {
sendAddOwner(values, safeAddress, owners, openSnackbar, createTransaction, updateSafe)
sendAddOwner(values, safeAddress, owners, openSnackbar, createTransaction, addSafeOwner)
} catch (error) {
// eslint-disable-next-line
console.log('Error while removing an owner ' + error)

View File

@ -1,6 +1,6 @@
// @flow
import {
lg, sm, border, background,
lg, md, sm, border, background,
} from '~/theme/variables'
export const styles = () => ({

View File

@ -1,6 +1,5 @@
// @flow
import React from 'react'
import { List } from 'immutable'
import { withStyles } from '@material-ui/core/styles'
import Close from '@material-ui/icons/Close'
import OpenInNew from '@material-ui/icons/OpenInNew'
@ -16,7 +15,6 @@ import TextField from '~/components/forms/TextField'
import Paragraph from '~/components/layout/Paragraph'
import Identicon from '~/components/Identicon'
import { getEtherScanLink } from '~/logic/wallets/getWeb3'
import type { Owner } from '~/routes/safe/store/models/owner'
import { composeValidators, required, minMaxLength } from '~/components/forms/validator'
import Modal from '~/components/Modal'
import { styles } from './style'
@ -30,23 +28,15 @@ const openIconStyle = {
color: secondary,
}
const stylesModal = () => ({
smallerModalWindow: {
height: 'auto',
position: 'static',
},
})
type Props = {
onClose: () => void,
classes: Object,
isOpen: boolean,
safeAddress: string,
ownerAddress: string,
owners: List<Owner>,
network: string,
selectedOwnerName: string,
updateSafe: Function,
editSafeOwner: Function,
}
const EditOwnerComponent = ({
@ -56,15 +46,11 @@ const EditOwnerComponent = ({
safeAddress,
ownerAddress,
selectedOwnerName,
updateSafe,
owners,
editSafeOwner,
network,
}: Props) => {
const handleSubmit = (values) => {
const ownerToUpdateIndex = owners.findIndex(o => o.address === ownerAddress)
const updatedOwners = owners.update(ownerToUpdateIndex, owner => owner.set('name', values.ownerName))
updateSafe({ address: safeAddress, owners: updatedOwners })
editSafeOwner({ safeAddress, ownerAddress, ownerName: values.ownerName })
onClose()
}
@ -74,7 +60,7 @@ const EditOwnerComponent = ({
description="Edit owner from Safe"
handleClose={onClose}
open={isOpen}
paperClassName={stylesModal.smallerModalWindow}
paperClassName={classes.smallerModalWindow}
>
<Row align="center" grow className={classes.heading}>
<Paragraph className={classes.manage} noMargin weight="bolder">

View File

@ -36,4 +36,8 @@ export const styles = () => ({
cursor: 'pointer',
},
},
smallerModalWindow: {
height: 'auto',
position: 'static',
},
})

View File

@ -4,9 +4,8 @@ import { List } from 'immutable'
import { withStyles } from '@material-ui/core/styles'
import { SharedSnackbarConsumer } from '~/components/SharedSnackBar'
import Modal from '~/components/Modal'
import { type Owner, makeOwner } from '~/routes/safe/store/models/owner'
import { getGnosisSafeInstanceAt } from '~/logic/contracts/safeContracts'
import { getOwners } from '~/logic/safe/utils'
import { type Owner } from '~/routes/safe/store/models/owner'
import { getGnosisSafeInstanceAt, SENTINEL_ADDRESS } from '~/logic/contracts/safeContracts'
import CheckOwner from './screens/CheckOwner'
import ThresholdForm from './screens/ThresholdForm'
import ReviewRemoveOwner from './screens/Review'
@ -31,12 +30,10 @@ type Props = {
threshold: number,
network: string,
createTransaction: Function,
updateSafe: Function,
removeSafeOwner: Function,
}
type ActiveScreen = 'checkOwner' | 'selectThreshold' | 'reviewRemoveOwner'
const SENTINEL_ADDRESS = '0x0000000000000000000000000000000000000001'
export const sendRemoveOwner = async (
values: Object,
safeAddress: string,
@ -45,7 +42,7 @@ export const sendRemoveOwner = async (
ownersOld: List<Owner>,
openSnackbar: Function,
createTransaction: Function,
updateSafe: Function,
removeSafeOwner: Function,
) => {
const gnosisSafe = await getGnosisSafeInstanceAt(safeAddress)
const safeOwners = await gnosisSafe.getOwners()
@ -57,16 +54,8 @@ export const sendRemoveOwner = async (
const txHash = await createTransaction(safeAddress, safeAddress, 0, txData, openSnackbar)
let owners = []
const storedOwners = await getOwners(safeAddress)
storedOwners.forEach((value, key) => owners.push(makeOwner({ address: key, name: value })))
owners = List(owners).filter(o => o.address.toLowerCase() !== ownerAddressToRemove.toLowerCase())
if (txHash) {
updateSafe({
address: safeAddress,
owners,
})
removeSafeOwner({ safeAddress, ownerAddress: ownerAddressToRemove })
}
}
@ -82,7 +71,7 @@ const RemoveOwner = ({
threshold,
network,
createTransaction,
updateSafe,
removeSafeOwner,
}: Props) => {
const [activeScreen, setActiveScreen] = useState<ActiveScreen>('checkOwner')
const [values, setValues] = useState<Object>({})
@ -128,7 +117,7 @@ const RemoveOwner = ({
owners,
openSnackbar,
createTransaction,
updateSafe,
removeSafeOwner,
)
} catch (error) {
// eslint-disable-next-line

View File

@ -4,9 +4,7 @@ import { List } from 'immutable'
import { withStyles } from '@material-ui/core/styles'
import { SharedSnackbarConsumer } from '~/components/SharedSnackBar'
import Modal from '~/components/Modal'
import { type Owner, makeOwner } from '~/routes/safe/store/models/owner'
import { getOwners } from '~/logic/safe/utils'
import { getGnosisSafeInstanceAt } from '~/logic/contracts/safeContracts'
import { getGnosisSafeInstanceAt, SENTINEL_ADDRESS } from '~/logic/contracts/safeContracts'
import OwnerForm from './screens/OwnerForm'
import ReviewReplaceOwner from './screens/Review'
@ -30,12 +28,10 @@ type Props = {
network: string,
threshold: string,
createTransaction: Function,
updateSafe: Function,
replaceSafeOwner: Function,
}
type ActiveScreen = 'checkOwner' | 'reviewReplaceOwner'
const SENTINEL_ADDRESS = '0x0000000000000000000000000000000000000001'
export const sendReplaceOwner = async (
values: Object,
safeAddress: string,
@ -44,7 +40,7 @@ export const sendReplaceOwner = async (
ownersOld: List<Owner>,
openSnackbar: Function,
createTransaction: Function,
updateSafe: Function,
replaceSafeOwner: Function,
) => {
const gnosisSafe = await getGnosisSafeInstanceAt(safeAddress)
const safeOwners = await gnosisSafe.getOwners()
@ -56,22 +52,12 @@ export const sendReplaceOwner = async (
const txHash = await createTransaction(safeAddress, safeAddress, 0, txData, openSnackbar)
let owners = []
const storedOwners = await getOwners(safeAddress)
storedOwners.forEach((value, key) => owners.push(makeOwner({
address: key,
name: (values.ownerAddress.toLowerCase() === key.toLowerCase()) ? values.ownerName : value,
})))
const newOwnerIndex = List(owners).findIndex(o => o.address.toLowerCase() === values.ownerAddress.toLowerCase())
if (newOwnerIndex < 0) {
owners.push(makeOwner({ address: values.ownerAddress, name: values.ownerName }))
}
owners = List(owners).filter(o => o.address.toLowerCase() !== ownerAddressToRemove.toLowerCase())
if (txHash) {
updateSafe({
address: safeAddress,
owners,
replaceSafeOwner({
safeAddress,
oldOwnerAddress: ownerAddressToRemove,
ownerAddress: values.ownerAddress,
ownerName: values.ownerName,
})
}
}
@ -88,7 +74,7 @@ const ReplaceOwner = ({
network,
threshold,
createTransaction,
updateSafe,
replaceSafeOwner,
}: Props) => {
const [activeScreen, setActiveScreen] = useState<ActiveScreen>('checkOwner')
const [values, setValues] = useState<Object>({})
@ -125,7 +111,7 @@ const ReplaceOwner = ({
owners,
openSnackbar,
createTransaction,
updateSafe,
replaceSafeOwner,
)
} catch (error) {
// eslint-disable-next-line

View File

@ -1,6 +1,6 @@
// @flow
import {
lg, sm, border, background,
lg, md, sm, border, background,
} from '~/theme/variables'
export const styles = () => ({

View File

@ -57,7 +57,10 @@ type Props = {
threshold: number,
userAddress: string,
createTransaction: Function,
updateSafe: Function,
addSafeOwner: Function,
removeSafeOwner: Function,
replaceSafeOwner: Function,
editSafeOwner: Function,
granted: boolean,
}
@ -108,7 +111,10 @@ class ManageOwners extends React.Component<Props, State> {
network,
userAddress,
createTransaction,
updateSafe,
addSafeOwner,
removeSafeOwner,
replaceSafeOwner,
editSafeOwner,
granted,
} = this.props
const {
@ -211,7 +217,7 @@ class ManageOwners extends React.Component<Props, State> {
network={network}
userAddress={userAddress}
createTransaction={createTransaction}
updateSafe={updateSafe}
addSafeOwner={addSafeOwner}
/>
<RemoveOwnerModal
onClose={this.onHide('RemoveOwner')}
@ -225,7 +231,7 @@ class ManageOwners extends React.Component<Props, State> {
network={network}
userAddress={userAddress}
createTransaction={createTransaction}
updateSafe={updateSafe}
removeSafeOwner={removeSafeOwner}
/>
<ReplaceOwnerModal
onClose={this.onHide('ReplaceOwner')}
@ -239,7 +245,7 @@ class ManageOwners extends React.Component<Props, State> {
threshold={threshold}
userAddress={userAddress}
createTransaction={createTransaction}
updateSafe={updateSafe}
replaceSafeOwner={replaceSafeOwner}
/>
<EditOwnerModal
onClose={this.onHide('EditOwner')}
@ -249,7 +255,7 @@ class ManageOwners extends React.Component<Props, State> {
selectedOwnerName={selectedOwnerName}
owners={owners}
network={network}
updateSafe={updateSafe}
editSafeOwner={editSafeOwner}
/>
</React.Fragment>
)

View File

@ -1,10 +1,19 @@
// @flow
import updateSafeName from '~/routes/safe/store/actions/updateSafeName'
import addSafeOwner from '~/routes/safe/store/actions/addSafeOwner'
import removeSafeOwner from '~/routes/safe/store/actions/removeSafeOwner'
import replaceSafeOwner from '~/routes/safe/store/actions/replaceSafeOwner'
import editSafeOwner from '~/routes/safe/store/actions/editSafeOwner'
export type Actions = {
updateSafeName: Function,
addSafeOwner: Function,
removeSafeOwner: Function,
replaceSafeOwner: Function,
editSafeOwner: Function,
}
export default {
updateSafeName,
addSafeOwner,
removeSafeOwner,
replaceSafeOwner,
editSafeOwner,
}

View File

@ -37,7 +37,10 @@ type Props = Actions & {
threshold: number,
network: string,
createTransaction: Function,
updateSafe: Function,
addSafeOwner: Function,
removeSafeOwner: Function,
replaceSafeOwner: Function,
editSafeOwner: Function,
userAddress: string,
}
@ -75,6 +78,10 @@ class Settings extends React.Component<Props, State> {
userAddress,
createTransaction,
updateSafe,
addSafeOwner,
removeSafeOwner,
replaceSafeOwner,
editSafeOwner,
} = this.props
return (
@ -148,7 +155,10 @@ class Settings extends React.Component<Props, State> {
network={network}
createTransaction={createTransaction}
userAddress={userAddress}
updateSafe={updateSafe}
addSafeOwner={addSafeOwner}
removeSafeOwner={removeSafeOwner}
replaceSafeOwner={replaceSafeOwner}
editSafeOwner={editSafeOwner}
granted={granted}
/>
)}

View File

@ -0,0 +1,8 @@
// @flow
import { createAction } from 'redux-actions'
export const ADD_SAFE_OWNER = 'ADD_SAFE_OWNER'
const addSafeOwner = createAction<string, *>(ADD_SAFE_OWNER)
export default addSafeOwner

View File

@ -0,0 +1,8 @@
// @flow
import { createAction } from 'redux-actions'
export const EDIT_SAFE_OWNER = 'EDIT_SAFE_OWNER'
const editSafeOwner = createAction<string, *>(EDIT_SAFE_OWNER)
export default editSafeOwner

View File

@ -0,0 +1,8 @@
// @flow
import { createAction } from 'redux-actions'
export const REMOVE_SAFE_OWNER = 'REMOVE_SAFE_OWNER'
const removeSafeOwner = createAction<string, *>(REMOVE_SAFE_OWNER)
export default removeSafeOwner

View File

@ -0,0 +1,8 @@
// @flow
import { createAction } from 'redux-actions'
export const REPLACE_SAFE_OWNER = 'REPLACE_SAFE_OWNER'
const replaceSafeOwner = createAction<string, *>(REPLACE_SAFE_OWNER)
export default replaceSafeOwner

View File

@ -3,16 +3,30 @@ import type { Store, AnyAction } from 'redux'
import { ADD_SAFE } from '~/routes/safe/store/actions/addSafe'
import { UPDATE_SAFE } from '~/routes/safe/store/actions/updateSafe'
import { REMOVE_SAFE } from '~/routes/safe/store/actions/removeSafe'
import { ADD_SAFE_OWNER } from '~/routes/safe/store/actions/addSafeOwner'
import { REMOVE_SAFE_OWNER } from '~/routes/safe/store/actions/removeSafeOwner'
import { REPLACE_SAFE_OWNER } from '~/routes/safe/store/actions/replaceSafeOwner'
import { EDIT_SAFE_OWNER } from '~/routes/safe/store/actions/editSafeOwner'
import { type GlobalState } from '~/store/'
import { saveSafes, setOwners, removeOwners } from '~/logic/safe/utils'
import { safesMapSelector } from '~/routes/safeList/store/selectors'
import { getActiveTokensAddressesForAllSafes } from '~/routes/safe/store/selectors'
import { tokensSelector } from '~/logic/tokens/store/selectors'
import type { Token } from '~/logic/tokens/store/model/token'
import { makeOwner } from '~/routes/safe/store/models/owner'
import { saveActiveTokens } from '~/logic/tokens/utils/tokensStorage'
import { ACTIVATE_TOKEN_FOR_ALL_SAFES } from '~/routes/safe/store/actions/activateTokenForAllSafes'
const watchedActions = [ADD_SAFE, UPDATE_SAFE, REMOVE_SAFE, ACTIVATE_TOKEN_FOR_ALL_SAFES]
const watchedActions = [
ADD_SAFE,
UPDATE_SAFE,
REMOVE_SAFE,
ADD_SAFE_OWNER,
REMOVE_SAFE_OWNER,
REPLACE_SAFE_OWNER,
EDIT_SAFE_OWNER,
ACTIVATE_TOKEN_FOR_ALL_SAFES,
]
const safeStorageMware = (store: Store<GlobalState>) => (next: Function) => async (action: AnyAction) => {
const handledAction = next(action)
@ -20,36 +34,78 @@ const safeStorageMware = (store: Store<GlobalState>) => (next: Function) => asyn
if (watchedActions.includes(action.type)) {
const state: GlobalState = store.getState()
const safes = safesMapSelector(state)
saveSafes(safes.toJSON())
await saveSafes(safes.toJSON())
// recalculate active tokens
if (action.payload.activeTokens || action.type === ACTIVATE_TOKEN_FOR_ALL_SAFES) {
const tokens = tokensSelector(state)
const activeTokenAddresses = getActiveTokensAddressesForAllSafes(state)
switch (action.type) {
case ACTIVATE_TOKEN_FOR_ALL_SAFES: {
let { activeTokens } = action.payload
if (activeTokens) {
const tokens = tokensSelector(state)
const activeTokenAddresses = getActiveTokensAddressesForAllSafes(state)
const activeTokens = tokens.withMutations((map) => {
map.forEach((token: Token) => {
if (!activeTokenAddresses.has(token.address)) {
map.remove(token.address)
}
})
})
activeTokens = tokens.withMutations((map) => {
map.forEach((token: Token) => {
if (!activeTokenAddresses.has(token.address)) {
map.remove(token.address)
}
})
})
saveActiveTokens(activeTokens)
}
if (action.type === ADD_SAFE) {
const { safe } = action.payload
setOwners(safe.address, safe.owners)
} else if (action.type === UPDATE_SAFE) {
const { address, owners } = action.payload
if (address && owners) {
setOwners(address, owners)
saveActiveTokens(activeTokens)
}
break
}
} else if (action.type === REMOVE_SAFE) {
const safeAddress = action.payload
removeOwners(safeAddress)
case ADD_SAFE: {
const { safe } = action.payload
setOwners(safe.address, safe.owners)
break
}
case UPDATE_SAFE: {
const { safeAddress, owners } = action.payload
if (safeAddress && owners) {
setOwners(safeAddress, owners)
}
break
}
case REMOVE_SAFE: {
const { safeAddress } = action.payload
await removeOwners(safeAddress)
break
}
case ADD_SAFE_OWNER: {
const { safeAddress, ownerAddress, ownerName } = action.payload
const { owners } = safes.get(safeAddress)
setOwners(safeAddress, owners.push(makeOwner({ address: ownerAddress, name: ownerName })))
break
}
case REMOVE_SAFE_OWNER: {
const { safeAddress, ownerAddress } = action.payload
const { owners } = safes.get(safeAddress)
setOwners(safeAddress, owners.filter(o => o.address.toLowerCase() !== ownerAddress.toLowerCase()))
break
}
case REPLACE_SAFE_OWNER: {
const {
safeAddress, ownerAddress, ownerName, oldOwnerAddress,
} = action.payload
const { owners } = safes.get(safeAddress)
setOwners(
safeAddress,
owners
.filter(o => o.address.toLowerCase() !== oldOwnerAddress.toLowerCase())
.push(makeOwner({ address: ownerAddress, name: ownerName })),
)
break
}
case EDIT_SAFE_OWNER: {
const { safeAddress, ownerAddress, ownerName } = action.payload
const { owners } = safes.get(safeAddress)
const ownerToUpdateIndex = owners.findIndex(o => o.address.toLowerCase() === ownerAddress.toLowerCase())
setOwners(safeAddress, owners.update(ownerToUpdateIndex, owner => owner.set('name', ownerName)))
break
}
default:
break
}
}

View File

@ -4,12 +4,16 @@ import { handleActions, type ActionType } from 'redux-actions'
import { ADD_SAFE, buildOwnersFrom } from '~/routes/safe/store/actions/addSafe'
import SafeRecord, { type Safe, type SafeProps } from '~/routes/safe/store/models/safe'
import TokenBalance from '~/routes/safe/store/models/tokenBalance'
import { type OwnerProps } from '~/routes/safe/store/models/owner'
import { makeOwner, type OwnerProps } from '~/routes/safe/store/models/owner'
import { loadFromStorage } from '~/utils/storage'
import { SAFES_KEY } from '~/logic/safe/utils'
import { UPDATE_SAFE } from '~/routes/safe/store/actions/updateSafe'
import { ACTIVATE_TOKEN_FOR_ALL_SAFES } from '~/routes/safe/store/actions/activateTokenForAllSafes'
import { REMOVE_SAFE } from '~/routes/safe/store/actions/removeSafe'
import { ADD_SAFE_OWNER } from '~/routes/safe/store/actions/addSafeOwner'
import { REMOVE_SAFE_OWNER } from '~/routes/safe/store/actions/removeSafeOwner'
import { REPLACE_SAFE_OWNER } from '~/routes/safe/store/actions/replaceSafeOwner'
import { EDIT_SAFE_OWNER } from '~/routes/safe/store/actions/editSafeOwner'
export const SAFE_REDUCER_ID = 'safes'
@ -97,6 +101,42 @@ export default handleActions<State, *>(
return state.delete(safeAddress)
},
[ADD_SAFE_OWNER]: (state: State, action: ActionType<Function>): State => {
const { safeAddress, ownerName, ownerAddress } = action.payload
return state.update(safeAddress, prevSafe => prevSafe.merge({
owners: prevSafe.owners.push(makeOwner({ address: ownerAddress, name: ownerName })),
}))
},
[REMOVE_SAFE_OWNER]: (state: State, action: ActionType<Function>): State => {
const { safeAddress, ownerAddress } = action.payload
return state.update(safeAddress, prevSafe => prevSafe.merge({
owners: prevSafe.owners.filter(o => o.address.toLowerCase() !== ownerAddress.toLowerCase()),
}))
},
[REPLACE_SAFE_OWNER]: (state: State, action: ActionType<Function>): State => {
const {
safeAddress, oldOwnerAddress, ownerName, ownerAddress,
} = action.payload
return state.update(safeAddress, prevSafe => prevSafe.merge({
owners: prevSafe.owners
.filter(o => o.address.toLowerCase() !== oldOwnerAddress.toLowerCase())
.push(makeOwner({ address: ownerAddress, name: ownerName })),
}))
},
[EDIT_SAFE_OWNER]: (state: State, action: ActionType<Function>): State => {
const { safeAddress, ownerAddress, ownerName } = action.payload
return state.update(safeAddress, (prevSafe) => {
const ownerToUpdateIndex = prevSafe.owners.findIndex(
o => o.address.toLowerCase() === ownerAddress.toLowerCase(),
)
const updatedOwners = prevSafe.owners.update(ownerToUpdateIndex, owner => owner.set('name', ownerName))
return prevSafe.merge({ owners: updatedOwners })
})
},
},
Map(),
)

View File

@ -96,8 +96,10 @@ describe('DOM > Feature > Settings - Manage owners', () => {
// check if there are 2 owners
let ownerRows = SafeDom.getAllByTestId(OWNERS_ROW_TESTID)
expect(ownerRows.length).toBe(2)
expect(ownerRows[0]).toHaveTextContent('Adol 1 Eth Account0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1')
expect(ownerRows[1]).toHaveTextContent('Adol 2 Eth Account0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0')
expect(ownerRows[0]).toHaveTextContent('Adol 1 Eth Account')
expect(ownerRows[0]).toHaveTextContent('0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1')
expect(ownerRows[1]).toHaveTextContent('Adol 2 Eth Account')
expect(ownerRows[1]).toHaveTextContent('0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0')
// click remove owner btn which opens the modal
const removeOwnerBtn = SafeDom.getAllByTestId(REMOVE_OWNER_BTN_TESTID)[1]
@ -117,7 +119,8 @@ describe('DOM > Feature > Settings - Manage owners', () => {
// check if owner was removed
ownerRows = SafeDom.getAllByTestId(OWNERS_ROW_TESTID)
expect(ownerRows.length).toBe(1)
expect(ownerRows[0]).toHaveTextContent('Adol 1 Eth Account0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1')
expect(ownerRows[0]).toHaveTextContent('Adol 1 Eth Account')
expect(ownerRows[0]).toHaveTextContent('0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1')
})
it('Adds a new owner', async () => {
@ -140,7 +143,8 @@ describe('DOM > Feature > Settings - Manage owners', () => {
// check if there is 1 owner
let ownerRows = SafeDom.getAllByTestId(OWNERS_ROW_TESTID)
expect(ownerRows.length).toBe(1)
expect(ownerRows[0]).toHaveTextContent('Adol 1 Eth Account0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1')
expect(ownerRows[0]).toHaveTextContent('Adol 1 Eth Account')
expect(ownerRows[0]).toHaveTextContent('0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1')
// click add owner btn
fireEvent.click(SafeDom.getByTestId(ADD_OWNER_BTN_TESTID))
@ -163,8 +167,10 @@ describe('DOM > Feature > Settings - Manage owners', () => {
// check if owner was added
ownerRows = SafeDom.getAllByTestId(OWNERS_ROW_TESTID)
expect(ownerRows.length).toBe(2)
expect(ownerRows[0]).toHaveTextContent('Adol 1 Eth Account0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1')
expect(ownerRows[1]).toHaveTextContent(`${NEW_OWNER_NAME}${NEW_OWNER_ADDRESS}`)
expect(ownerRows[0]).toHaveTextContent('Adol 1 Eth Account')
expect(ownerRows[0]).toHaveTextContent('0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1')
expect(ownerRows[1]).toHaveTextContent(NEW_OWNER_NAME)
expect(ownerRows[1]).toHaveTextContent(NEW_OWNER_ADDRESS)
})
it('Replaces an owner', async () => {
@ -189,8 +195,10 @@ describe('DOM > Feature > Settings - Manage owners', () => {
// check if there are 2 owners
let ownerRows = SafeDom.getAllByTestId(OWNERS_ROW_TESTID)
expect(ownerRows.length).toBe(2)
expect(ownerRows[0]).toHaveTextContent('Adol 1 Eth Account0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1')
expect(ownerRows[1]).toHaveTextContent('Adol 2 Eth Account0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0')
expect(ownerRows[0]).toHaveTextContent('Adol 1 Eth Account')
expect(ownerRows[0]).toHaveTextContent('0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1')
expect(ownerRows[1]).toHaveTextContent('Adol 2 Eth Account')
expect(ownerRows[1]).toHaveTextContent('0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0')
// click replace owner btn which opens the modal
const replaceOwnerBtn = SafeDom.getAllByTestId(REPLACE_OWNER_BTN_TESTID)[1]
@ -212,7 +220,9 @@ describe('DOM > Feature > Settings - Manage owners', () => {
// check if the owner was replaced
ownerRows = SafeDom.getAllByTestId(OWNERS_ROW_TESTID)
expect(ownerRows.length).toBe(2)
expect(ownerRows[0]).toHaveTextContent('Adol 1 Eth Account0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1')
expect(ownerRows[1]).toHaveTextContent(`${NEW_OWNER_NAME}${NEW_OWNER_ADDRESS}`)
expect(ownerRows[0]).toHaveTextContent('Adol 1 Eth Account')
expect(ownerRows[0]).toHaveTextContent('0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1')
expect(ownerRows[1]).toHaveTextContent(NEW_OWNER_NAME)
expect(ownerRows[1]).toHaveTextContent(NEW_OWNER_ADDRESS)
})
})

163
yarn.lock
View File

@ -46,7 +46,7 @@
semver "^5.4.1"
source-map "^0.5.0"
"@babel/core@7.5.4", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5":
"@babel/core@7.5.4", "@babel/core@^7.4.5":
version "7.5.4"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.4.tgz#4c32df7ad5a58e9ea27ad025c11276324e0b4ddd"
integrity sha512-+DaeBEpYq6b2+ZmHx3tHspC+ZRflrvLqwfv8E3hNr5LVQoyBnL8RPKSBCg+rK2W2My9PWlujBiqd0ZPsR9Q6zQ==
@ -66,6 +66,26 @@
semver "^5.4.1"
source-map "^0.5.0"
"@babel/core@^7.0.0", "@babel/core@^7.1.0":
version "7.4.5"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.4.5.tgz#081f97e8ffca65a9b4b0fdc7e274e703f000c06a"
integrity sha512-OvjIh6aqXtlsA8ujtGKfC7LYWksYSX8yQcM8Ay3LuvVeQ63lcOKgoZWVqcpFwkd29aYU9rVx7jxhfhiEDV9MZA==
dependencies:
"@babel/code-frame" "^7.0.0"
"@babel/generator" "^7.4.4"
"@babel/helpers" "^7.4.4"
"@babel/parser" "^7.4.5"
"@babel/template" "^7.4.4"
"@babel/traverse" "^7.4.5"
"@babel/types" "^7.4.4"
convert-source-map "^1.1.0"
debug "^4.1.0"
json5 "^2.1.0"
lodash "^4.17.11"
resolve "^1.3.2"
semver "^5.4.1"
source-map "^0.5.0"
"@babel/generator@^7.4.0", "@babel/generator@^7.5.0":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.0.tgz#f20e4b7a91750ee8b63656073d843d2a736dca4a"
@ -292,7 +312,7 @@
"@babel/helper-create-class-features-plugin" "^7.4.0"
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-proposal-class-properties@7.5.0", "@babel/plugin-proposal-class-properties@^7.3.3":
"@babel/plugin-proposal-class-properties@7.5.0":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.0.tgz#5bc6a0537d286fcb4fd4e89975adbca334987007"
integrity sha512-9L/JfPCT+kShiiTTzcnBJ8cOwdKVmlC1RcCf9F0F9tERVrM4iWtWnXtjWCRqNm2la2BxO1MPArWNsU9zsSJWSQ==
@ -300,6 +320,14 @@
"@babel/helper-create-class-features-plugin" "^7.5.0"
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-proposal-class-properties@^7.3.3":
version "7.4.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.4.4.tgz#93a6486eed86d53452ab9bab35e368e9461198ce"
integrity sha512-WjKTI8g8d5w1Bc9zgwSz2nfrsNQsXcCf9J9cdCvrJV6RF56yztwm4TmJC0MgJ9tvwO9gUA/mcYe89bLdGfiXFg==
dependencies:
"@babel/helper-create-class-features-plugin" "^7.4.4"
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-proposal-decorators@7.4.0":
version "7.4.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.4.0.tgz#8e1bfd83efa54a5f662033afcc2b8e701f4bb3a9"
@ -761,7 +789,16 @@
"@babel/helper-plugin-utils" "^7.0.0"
babel-plugin-dynamic-import-node "^2.3.0"
"@babel/plugin-transform-modules-commonjs@^7.4.3", "@babel/plugin-transform-modules-commonjs@^7.5.0":
"@babel/plugin-transform-modules-commonjs@^7.4.3":
version "7.4.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz#0bef4713d30f1d78c2e59b3d6db40e60192cac1e"
integrity sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw==
dependencies:
"@babel/helper-module-transforms" "^7.4.4"
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/helper-simple-access" "^7.1.0"
"@babel/plugin-transform-modules-commonjs@^7.5.0":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz#425127e6045231360858eeaa47a71d75eded7a74"
integrity sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ==
@ -771,7 +808,15 @@
"@babel/helper-simple-access" "^7.1.0"
babel-plugin-dynamic-import-node "^2.3.0"
"@babel/plugin-transform-modules-systemjs@^7.4.0", "@babel/plugin-transform-modules-systemjs@^7.5.0":
"@babel/plugin-transform-modules-systemjs@^7.4.0":
version "7.4.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.4.tgz#dc83c5665b07d6c2a7b224c00ac63659ea36a405"
integrity sha512-MSiModfILQc3/oqnG7NrP1jHaSPryO6tA2kOMmAQApz5dayPxWiHqmq4sWH2xF5LcQK56LlbKByCd8Aah/OIkQ==
dependencies:
"@babel/helper-hoist-variables" "^7.4.4"
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-transform-modules-systemjs@^7.5.0":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz#e75266a13ef94202db2a0620977756f51d52d249"
integrity sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg==
@ -1015,7 +1060,7 @@
js-levenshtein "^1.1.3"
semver "^5.5.0"
"@babel/preset-env@7.5.4", "@babel/preset-env@^7.4.5":
"@babel/preset-env@7.5.4":
version "7.5.4"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.5.4.tgz#64bc15041a3cbb0798930319917e70fcca57713d"
integrity sha512-hFnFnouyRNiH1rL8YkX1ANCNAUVC8Djwdqfev8i1415tnAG+7hlA5zhZ0Q/3Q5gkop4HioIPbCEWAalqcbxRoQ==
@ -1071,6 +1116,60 @@
js-levenshtein "^1.1.3"
semver "^5.5.0"
"@babel/preset-env@^7.4.5":
version "7.4.5"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.4.5.tgz#2fad7f62983d5af563b5f3139242755884998a58"
integrity sha512-f2yNVXM+FsR5V8UwcFeIHzHWgnhXg3NpRmy0ADvALpnhB0SLbCvrCRr4BLOUYbQNLS+Z0Yer46x9dJXpXewI7w==
dependencies:
"@babel/helper-module-imports" "^7.0.0"
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-proposal-async-generator-functions" "^7.2.0"
"@babel/plugin-proposal-json-strings" "^7.2.0"
"@babel/plugin-proposal-object-rest-spread" "^7.4.4"
"@babel/plugin-proposal-optional-catch-binding" "^7.2.0"
"@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
"@babel/plugin-syntax-async-generators" "^7.2.0"
"@babel/plugin-syntax-json-strings" "^7.2.0"
"@babel/plugin-syntax-object-rest-spread" "^7.2.0"
"@babel/plugin-syntax-optional-catch-binding" "^7.2.0"
"@babel/plugin-transform-arrow-functions" "^7.2.0"
"@babel/plugin-transform-async-to-generator" "^7.4.4"
"@babel/plugin-transform-block-scoped-functions" "^7.2.0"
"@babel/plugin-transform-block-scoping" "^7.4.4"
"@babel/plugin-transform-classes" "^7.4.4"
"@babel/plugin-transform-computed-properties" "^7.2.0"
"@babel/plugin-transform-destructuring" "^7.4.4"
"@babel/plugin-transform-dotall-regex" "^7.4.4"
"@babel/plugin-transform-duplicate-keys" "^7.2.0"
"@babel/plugin-transform-exponentiation-operator" "^7.2.0"
"@babel/plugin-transform-for-of" "^7.4.4"
"@babel/plugin-transform-function-name" "^7.4.4"
"@babel/plugin-transform-literals" "^7.2.0"
"@babel/plugin-transform-member-expression-literals" "^7.2.0"
"@babel/plugin-transform-modules-amd" "^7.2.0"
"@babel/plugin-transform-modules-commonjs" "^7.4.4"
"@babel/plugin-transform-modules-systemjs" "^7.4.4"
"@babel/plugin-transform-modules-umd" "^7.2.0"
"@babel/plugin-transform-named-capturing-groups-regex" "^7.4.5"
"@babel/plugin-transform-new-target" "^7.4.4"
"@babel/plugin-transform-object-super" "^7.2.0"
"@babel/plugin-transform-parameters" "^7.4.4"
"@babel/plugin-transform-property-literals" "^7.2.0"
"@babel/plugin-transform-regenerator" "^7.4.5"
"@babel/plugin-transform-reserved-words" "^7.2.0"
"@babel/plugin-transform-shorthand-properties" "^7.2.0"
"@babel/plugin-transform-spread" "^7.2.0"
"@babel/plugin-transform-sticky-regex" "^7.2.0"
"@babel/plugin-transform-template-literals" "^7.4.4"
"@babel/plugin-transform-typeof-symbol" "^7.2.0"
"@babel/plugin-transform-unicode-regex" "^7.4.4"
"@babel/types" "^7.4.4"
browserslist "^4.6.0"
core-js-compat "^3.1.1"
invariant "^2.2.2"
js-levenshtein "^1.1.3"
semver "^5.5.0"
"@babel/preset-flow@^7.0.0", "@babel/preset-flow@^7.0.0-beta.40":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.0.0.tgz#afd764835d9535ec63d8c7d4caf1c06457263da2"
@ -1151,7 +1250,16 @@
globals "^11.1.0"
lodash "^4.17.11"
"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.0":
"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4":
version "7.4.4"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.4.tgz#8db9e9a629bb7c29370009b4b779ed93fe57d5f0"
integrity sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==
dependencies:
esutils "^2.0.2"
lodash "^4.17.11"
to-fast-properties "^2.0.0"
"@babel/types@^7.5.0":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.0.tgz#e47d43840c2e7f9105bc4d3a2c371b4d0c7832ab"
integrity sha512-UFpDVqRABKsW01bvw7/wSUe56uy6RXM5+VJibVVAybDGxEW25jdwiFJEf7ASvSaC7sN7rbE/l3cLp2izav+CtQ==
@ -7983,7 +8091,7 @@ fs-extra@6.0.1, fs-extra@^6.0.1:
jsonfile "^4.0.0"
universalify "^0.1.0"
fs-extra@8.1.0, fs-extra@^8.0.1:
fs-extra@8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
@ -8039,6 +8147,15 @@ fs-extra@^7.0.0:
jsonfile "^4.0.0"
universalify "^0.1.0"
fs-extra@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.0.1.tgz#90294081f978b1f182f347a440a209154344285b"
integrity sha512-W+XLrggcDzlle47X/XnS7FXrXu9sDo+Ze9zpndeBxdgv88FHLm1HtmkhEwavruS6koanBjp098rUpHs65EmG7A==
dependencies:
graceful-fs "^4.1.2"
jsonfile "^4.0.0"
universalify "^0.1.0"
fs-minipass@^1.2.5:
version "1.2.6"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07"
@ -18329,7 +18446,7 @@ webpack-sources@^1.1.0, webpack-sources@^1.3.0:
source-list-map "^2.0.0"
source-map "~0.6.1"
webpack@4.35.3, webpack@^4.33.0:
webpack@4.35.3:
version "4.35.3"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.35.3.tgz#66bc35ef215a7b75e8790f84d560013ffecf0ca3"
integrity sha512-xggQPwr9ILlXzz61lHzjvgoqGU08v5+Wnut19Uv3GaTtzN4xBTcwnobodrXE142EL1tOiS5WVEButooGzcQzTA==
@ -18358,6 +18475,36 @@ webpack@4.35.3, webpack@^4.33.0:
watchpack "^1.5.0"
webpack-sources "^1.3.0"
webpack@^4.33.0:
version "4.35.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.35.0.tgz#ad3f0f8190876328806ccb7a36f3ce6e764b8378"
integrity sha512-M5hL3qpVvtr8d4YaJANbAQBc4uT01G33eDpl/psRTBCfjxFTihdhin1NtAKB1ruDwzeVdcsHHV3NX+QsAgOosw==
dependencies:
"@webassemblyjs/ast" "1.8.5"
"@webassemblyjs/helper-module-context" "1.8.5"
"@webassemblyjs/wasm-edit" "1.8.5"
"@webassemblyjs/wasm-parser" "1.8.5"
acorn "^6.0.5"
acorn-dynamic-import "^4.0.0"
ajv "^6.1.0"
ajv-keywords "^3.1.0"
chrome-trace-event "^1.0.0"
enhanced-resolve "^4.1.0"
eslint-scope "^4.0.0"
json-parse-better-errors "^1.0.2"
loader-runner "^2.3.0"
loader-utils "^1.1.0"
memory-fs "~0.4.1"
micromatch "^3.1.8"
mkdirp "~0.5.0"
neo-async "^2.5.0"
node-libs-browser "^2.0.0"
schema-utils "^1.0.0"
tapable "^1.1.0"
terser-webpack-plugin "^1.1.0"
watchpack "^1.5.0"
webpack-sources "^1.3.0"
websocket-driver@>=0.5.1:
version "0.7.3"
resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.3.tgz#a2d4e0d4f4f116f1e6297eba58b05d430100e9f9"