remove implementation tests for now
This commit is contained in:
parent
bf174d6f94
commit
6523a25c9b
|
@ -1,54 +0,0 @@
|
|||
// @flow
|
||||
/*
|
||||
import addBalances from '~/routes/safe/store/actions/addBalances'
|
||||
import { aNewStore } from '~/store'
|
||||
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
|
||||
import { balanceSelector } from '../selectors'
|
||||
|
||||
const balanceSelectorTests = () => {
|
||||
describe('Safe Selector[balanceSelector]', () => {
|
||||
it('should return 0 when safe address is not found', () => {
|
||||
// GIVEN
|
||||
const safeAddress = 'foo'
|
||||
const match = buildMathPropsFrom(safeAddress)
|
||||
const store = aNewStore()
|
||||
|
||||
// WHEN
|
||||
const balance = balanceSelector(store.getState(), { match })
|
||||
|
||||
// THEN
|
||||
expect(balance).toBe('0')
|
||||
})
|
||||
|
||||
it('should return 0 when safe has no funds', async () => {
|
||||
// GIVEN
|
||||
const safeAddress = 'foo'
|
||||
const match = buildMathPropsFrom(safeAddress)
|
||||
const store = aNewStore()
|
||||
|
||||
// WHEN
|
||||
await store.dispatch(addBalances('bar', '1'))
|
||||
const balance = balanceSelector(store.getState(), { match })
|
||||
|
||||
// THEN
|
||||
expect(balance).toBe('0')
|
||||
})
|
||||
|
||||
it('should return safe funds', async () => {
|
||||
// GIVEN
|
||||
const safeAddress = 'foo'
|
||||
const match = buildMathPropsFrom(safeAddress)
|
||||
const store = aNewStore()
|
||||
|
||||
// WHEN
|
||||
await store.dispatch(addBalances(safeAddress, '1.3456'))
|
||||
const balance = balanceSelector(store.getState(), { match })
|
||||
|
||||
// THEN
|
||||
expect(balance).toBe('1.3456')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default balanceSelectorTests
|
||||
*/
|
|
@ -1,59 +0,0 @@
|
|||
// @flow
|
||||
import SafeRecord, { type Safe } from '~/routes/safe/store/models/safe'
|
||||
import { buildOwnersFrom } from '~/routes/safe/store/actions/addSafe'
|
||||
|
||||
class SafeBuilder {
|
||||
safe: Safe
|
||||
|
||||
constructor() {
|
||||
this.safe = SafeRecord()
|
||||
}
|
||||
|
||||
withAddress(address: string) {
|
||||
this.safe = this.safe.set('address', address)
|
||||
return this
|
||||
}
|
||||
|
||||
withName(name: string) {
|
||||
this.safe = this.safe.set('name', name)
|
||||
return this
|
||||
}
|
||||
|
||||
withConfirmations(confirmations: number) {
|
||||
this.safe = this.safe.set('threshold', confirmations)
|
||||
return this
|
||||
}
|
||||
|
||||
withOwner(names: string[], adresses: string[]) {
|
||||
const owners = buildOwnersFrom(names, adresses)
|
||||
this.safe = this.safe.set('owners', owners)
|
||||
return this
|
||||
}
|
||||
|
||||
get() {
|
||||
return this.safe
|
||||
}
|
||||
}
|
||||
|
||||
const aSafe = () => new SafeBuilder()
|
||||
|
||||
export class SafeFactory {
|
||||
static oneOwnerSafe = (ownerAddress: string = '0x03db1a8b26d08df23337e9276a36b474510f0023') => aSafe()
|
||||
.withAddress('0x03db1a8b26d08df23337e9276a36b474510f0025')
|
||||
.withName('Adol ICO Safe')
|
||||
.withConfirmations(1)
|
||||
.withOwner(['Adol Metamask'], [ownerAddress])
|
||||
.get()
|
||||
|
||||
static twoOwnersSafe = (
|
||||
firstOwner: string = '0x03db1a8b26d08df23337e9276a36b474510f0023',
|
||||
secondOwner: string = '0x03db1a8b26d08df23337e9276a36b474510f0024',
|
||||
) => aSafe()
|
||||
.withAddress('0x03db1a8b26d08df23337e9276a36b474510f0026')
|
||||
.withName('Adol & Tobias Safe')
|
||||
.withConfirmations(2)
|
||||
.withOwner(['Adol Metamask', 'Tobias Metamask'], [firstOwner, secondOwner])
|
||||
.get()
|
||||
}
|
||||
|
||||
export default aSafe
|
|
@ -1,102 +0,0 @@
|
|||
// @flow
|
||||
/*
|
||||
import { List, Map } from 'immutable'
|
||||
import { makeTransaction, type Transaction } from '~/routes/safe/store/model/transaction'
|
||||
import { type Confirmation, makeConfirmation } from '~/routes/safe/store/model/confirmation'
|
||||
import { makeOwner } from '~/routes/safe/store/model/owner'
|
||||
import { confirmationsTransactionSelector } from '~/routes/safe/store/selectors/index'
|
||||
import { makeProvider } from '~/wallets/store/model/provider'
|
||||
|
||||
|
||||
const grantedSelectorTests = () => {
|
||||
describe('Safe Selector[confirmationsTransactionSelector]', () => {
|
||||
it('returns 1 confirmation if safe has only one owner when tx is created', () => {
|
||||
// GIVEN
|
||||
const firstConfirmation: Confirmation = makeConfirmation({
|
||||
owner: makeOwner(),
|
||||
status: true,
|
||||
hash: 'asdf',
|
||||
})
|
||||
|
||||
const transaction: Transaction = makeTransaction({
|
||||
name: 'Buy batteries',
|
||||
nonce: 1,
|
||||
value: 2,
|
||||
confirmations: List([firstConfirmation]),
|
||||
destination: 'destAddress',
|
||||
threshold: 2,
|
||||
tx: '',
|
||||
})
|
||||
|
||||
const reduxStore = {
|
||||
safes: Map(),
|
||||
providers: makeProvider(),
|
||||
tokens: Map(),
|
||||
transactions: Map(),
|
||||
}
|
||||
|
||||
// WHEN
|
||||
const threshold = confirmationsTransactionSelector(reduxStore, { transaction })
|
||||
|
||||
// THEN
|
||||
expect(threshold).toBe(1)
|
||||
})
|
||||
|
||||
it('returns 1 confirmation if safe has two or more owners when multisig tx is created', () => {
|
||||
// GIVEN
|
||||
const firstConfirmation: Confirmation = makeConfirmation({
|
||||
owner: makeOwner(),
|
||||
status: true,
|
||||
hash: 'asdf',
|
||||
})
|
||||
|
||||
const secondConfirmation: Confirmation = makeConfirmation({
|
||||
owner: makeOwner(),
|
||||
status: false,
|
||||
hash: '',
|
||||
})
|
||||
|
||||
const transaction: Transaction = makeTransaction({
|
||||
name: 'Buy batteries',
|
||||
nonce: 1,
|
||||
value: 2,
|
||||
confirmations: List([firstConfirmation, secondConfirmation]),
|
||||
destination: 'destAddress',
|
||||
threshold: 2,
|
||||
tx: '',
|
||||
})
|
||||
|
||||
const reduxStore = {
|
||||
safes: Map(),
|
||||
providers: makeProvider(),
|
||||
tokens: Map(),
|
||||
transactions: Map(),
|
||||
}
|
||||
|
||||
// WHEN
|
||||
const threshold = confirmationsTransactionSelector(reduxStore, { transaction })
|
||||
|
||||
// THEN
|
||||
expect(threshold).toBe(1)
|
||||
})
|
||||
|
||||
it('should return 0 confirmations if not transaction is sent as prop to component', () => {
|
||||
const reduxStore = {
|
||||
safes: Map(),
|
||||
providers: makeProvider(),
|
||||
tokens: Map(),
|
||||
transactions: Map(),
|
||||
}
|
||||
|
||||
// WHEN
|
||||
// $FlowFixMe
|
||||
const threshold = confirmationsTransactionSelector(reduxStore, { transaction: undefined })
|
||||
|
||||
// THEN
|
||||
expect(threshold).toBe(0)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default grantedSelectorTests
|
||||
*/
|
|
@ -1,84 +0,0 @@
|
|||
// @flow
|
||||
import { Map } from 'immutable'
|
||||
import { type Match } from 'react-router-dom'
|
||||
import { SAFE_REDUCER_ID } from '~/routes/safe/store/reducer/safe'
|
||||
import { type Safe } from '~/routes/safe/store/models/safe'
|
||||
import { SafeFactory } from '~/routes/safe/store/test/builder/safe.builder'
|
||||
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
|
||||
import { getProviderInfo } from '~/logic/wallets/getWeb3'
|
||||
import { grantedSelector } from '~/routes/safe/container/selector'
|
||||
import { makeProvider } from '~/logic/wallets/store/model/provider'
|
||||
|
||||
const grantedSelectorTests = () => {
|
||||
let provider
|
||||
beforeEach(async () => {
|
||||
provider = await getProviderInfo()
|
||||
})
|
||||
|
||||
describe('Safe Selector[grantedSelector]', () => {
|
||||
it('should be granted to operate a safe when the user is owner', () => {
|
||||
// GIVEN
|
||||
let map: Map<string, Safe> = Map()
|
||||
map = map.set('fooAddress', SafeFactory.oneOwnerSafe(provider.account))
|
||||
|
||||
const match: Match = buildMathPropsFrom('fooAddress')
|
||||
|
||||
const reduxStore = {
|
||||
[SAFE_REDUCER_ID]: map,
|
||||
providers: makeProvider(provider),
|
||||
tokens: undefined,
|
||||
transactions: undefined,
|
||||
}
|
||||
|
||||
// WHEN
|
||||
const granted = grantedSelector(reduxStore, { match })
|
||||
|
||||
// THEN
|
||||
expect(granted).toBe(true)
|
||||
})
|
||||
|
||||
it('should be granted to operate a safe when the user is owner in case-insensitive', () => {
|
||||
// GIVEN
|
||||
let map: Map<string, Safe> = Map()
|
||||
map = map.set('fooAddress', SafeFactory.oneOwnerSafe(provider.account.toUpperCase()))
|
||||
|
||||
const match: Match = buildMathPropsFrom('fooAddress')
|
||||
|
||||
const reduxStore = {
|
||||
[SAFE_REDUCER_ID]: map,
|
||||
providers: makeProvider(provider),
|
||||
tokens: undefined,
|
||||
transactions: undefined,
|
||||
}
|
||||
|
||||
// WHEN
|
||||
const granted = grantedSelector(reduxStore, { match })
|
||||
|
||||
// THEN
|
||||
expect(granted).toBe(true)
|
||||
})
|
||||
|
||||
it('should NOT be granted to operate with a Safe when the user is NOT owner', () => {
|
||||
// GIVEN
|
||||
let map: Map<string, Safe> = Map()
|
||||
map = map.set('fooAddress', SafeFactory.oneOwnerSafe('inventedOwner'))
|
||||
|
||||
const match: Match = buildMathPropsFrom('fooAddress')
|
||||
|
||||
const reduxStore = {
|
||||
[SAFE_REDUCER_ID]: map,
|
||||
providers: makeProvider(provider),
|
||||
tokens: undefined,
|
||||
transactions: undefined,
|
||||
}
|
||||
|
||||
// WHEN
|
||||
const granted = grantedSelector(reduxStore, { match })
|
||||
|
||||
// THEN
|
||||
expect(granted).toBe(false)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default grantedSelectorTests
|
|
@ -1,60 +0,0 @@
|
|||
// @flow
|
||||
import {
|
||||
combineReducers, createStore, applyMiddleware, compose,
|
||||
} from 'redux'
|
||||
import thunk from 'redux-thunk'
|
||||
import safeReducer, { SAFE_REDUCER_ID } from '~/routes/safe/store/reducer/safe'
|
||||
import addSafe from '~/routes/safe/store/actions/addSafe'
|
||||
import * as SafeFields from '~/routes/open/components/fields'
|
||||
import { getAccountsFrom, getNamesFrom } from '~/routes/open/utils/safeDataExtractor'
|
||||
import { SafeFactory } from './builder/safe.builder'
|
||||
|
||||
const aStore = (initState) => {
|
||||
const reducers = combineReducers({
|
||||
[SAFE_REDUCER_ID]: safeReducer,
|
||||
})
|
||||
const middlewares = [thunk]
|
||||
const enhancers = [applyMiddleware(...middlewares)]
|
||||
return createStore(reducers, initState, compose(...enhancers))
|
||||
}
|
||||
|
||||
const providerReducerTests = () => {
|
||||
describe('Safe Actions[addSafe]', () => {
|
||||
let store
|
||||
let address
|
||||
let formValues
|
||||
beforeEach(() => {
|
||||
store = aStore()
|
||||
address = '0x03db1a8b26d08df23337e9276a36b474510f0025'
|
||||
formValues = {
|
||||
[SafeFields.FIELD_NAME]: 'Adol ICO Safe',
|
||||
[SafeFields.FIELD_CONFIRMATIONS]: 1,
|
||||
[SafeFields.FIELD_OWNERS]: 1,
|
||||
[SafeFields.getOwnerAddressBy(0)]: '0x03db1a8b26d08df23337e9276a36b474510f0023',
|
||||
[SafeFields.getOwnerNameBy(0)]: 'Adol Metamask',
|
||||
address,
|
||||
}
|
||||
})
|
||||
|
||||
it('reducer should return SafeRecord from form values', () => {
|
||||
// GIVEN in beforeEach method
|
||||
|
||||
// WHEN
|
||||
store.dispatch(
|
||||
addSafe(
|
||||
formValues[SafeFields.FIELD_NAME],
|
||||
formValues.address,
|
||||
formValues[SafeFields.FIELD_CONFIRMATIONS],
|
||||
getNamesFrom(formValues),
|
||||
getAccountsFrom(formValues),
|
||||
),
|
||||
)
|
||||
const safes = store.getState()[SAFE_REDUCER_ID]
|
||||
|
||||
// THEN
|
||||
expect(safes.get(address)).toEqual(SafeFactory.oneOwnerSafe())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default providerReducerTests
|
|
@ -1,56 +0,0 @@
|
|||
// @flow
|
||||
import { Map } from 'immutable'
|
||||
import { type Match } from 'react-router-dom'
|
||||
import { SAFE_REDUCER_ID } from '~/routes/safe/store/reducer/safe'
|
||||
import { type Safe } from '~/routes/safe/store/models/safe'
|
||||
import { SafeFactory } from '~/routes/safe/store/test/builder/safe.builder'
|
||||
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
|
||||
import { safeSelector } from '../selectors'
|
||||
|
||||
const safeSelectorTests = () => {
|
||||
describe('Safe Selector[safeSelector]', () => {
|
||||
it('should return empty list when no safes', () => {
|
||||
// GIVEN
|
||||
const reduxStore = {
|
||||
[SAFE_REDUCER_ID]: Map(),
|
||||
providers: undefined,
|
||||
tokens: undefined,
|
||||
transactions: undefined,
|
||||
}
|
||||
const match: Match = buildMathPropsFrom('fooAddress')
|
||||
|
||||
// WHEN
|
||||
const safes = safeSelector(reduxStore, { match })
|
||||
|
||||
// THEN
|
||||
expect(safes).toBe(undefined)
|
||||
})
|
||||
|
||||
it('should return a list of size 2 when 2 safes are created', () => {
|
||||
// GIVEN
|
||||
let map: Map<string, Safe> = Map()
|
||||
map = map.set('fooAddress', SafeFactory.oneOwnerSafe())
|
||||
map = map.set('barAddress', SafeFactory.twoOwnersSafe())
|
||||
|
||||
const match: Match = buildMathPropsFrom('fooAddress')
|
||||
const undefMatch: Match = buildMathPropsFrom('inventedAddress')
|
||||
|
||||
const reduxStore = {
|
||||
[SAFE_REDUCER_ID]: map,
|
||||
providers: undefined,
|
||||
tokens: undefined,
|
||||
transactions: undefined,
|
||||
}
|
||||
|
||||
// WHEN
|
||||
const oneOwnerSafe = safeSelector(reduxStore, { match })
|
||||
const undefinedSafe = safeSelector(reduxStore, { match: undefMatch })
|
||||
|
||||
// THEN
|
||||
expect(oneOwnerSafe).toEqual(SafeFactory.oneOwnerSafe())
|
||||
expect(undefinedSafe).toBe(undefined)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default safeSelectorTests
|
|
@ -1,27 +0,0 @@
|
|||
// @flow
|
||||
import safeReducerTests from './safe.reducer'
|
||||
// import balanceSelectorTests from './balance.selector'
|
||||
import safeSelectorTests from './safe.selector'
|
||||
import grantedSelectorTests from './granted.selector'
|
||||
// import confirmationsSelectorTests from './confirmations.selector'
|
||||
// import transactionsSelectorTests from './transactions.selector'
|
||||
|
||||
describe('Safe Test suite', () => {
|
||||
// ACTIONS AND REDUCERS
|
||||
safeReducerTests()
|
||||
|
||||
// SAFE SELECTOR
|
||||
safeSelectorTests()
|
||||
|
||||
// BALANCE SELECTOR
|
||||
// balanceSelectorTests()
|
||||
|
||||
// GRANTED SELECTOR
|
||||
grantedSelectorTests()
|
||||
|
||||
// CONFIRMATIONS SELECTOR
|
||||
// confirmationsSelectorTests()
|
||||
|
||||
// TRANSACTIONS SELECTOR
|
||||
// transactionsSelectorTests()
|
||||
})
|
|
@ -1,131 +0,0 @@
|
|||
// @flow
|
||||
/*
|
||||
import { List, Map } from 'immutable'
|
||||
import { SAFE_REDUCER_ID } from '~/routes/safe/store/reducer/safe'
|
||||
import { safeTransactionsSelector } from '~/routes/safe/store/selectors/index'
|
||||
import { makeProvider } from '~/wallets/store/model/provider'
|
||||
import { makeConfirmation, type Confirmation } from '~/routes/safe/store/model/confirmation'
|
||||
import { makeOwner } from '~/routes/safe/store/model/owner'
|
||||
import { makeTransaction, type Transaction } from '~/routes/safe/store/model/transaction'
|
||||
|
||||
const grantedSelectorTests = () => {
|
||||
describe('Safe Selector[safeTransactionsSelector]', () => {
|
||||
it('should return empty list if no transactions in store', () => {
|
||||
// GIVEN
|
||||
const reduxStore = {
|
||||
[SAFE_REDUCER_ID]: Map(),
|
||||
providers: makeProvider(),
|
||||
tokens: undefined,
|
||||
transactions: Map(),
|
||||
}
|
||||
|
||||
// WHEN
|
||||
const transactions = safeTransactionsSelector(reduxStore, { safeAddress: 'fooAddress' })
|
||||
|
||||
// THEN
|
||||
expect(transactions).toEqual(List([]))
|
||||
})
|
||||
|
||||
it('should return empty list if transactions in store but not safe address in props', () => {
|
||||
// GIVEN
|
||||
const firstConfirmation: Confirmation = makeConfirmation({
|
||||
owner: makeOwner(),
|
||||
status: true,
|
||||
hash: 'asdf',
|
||||
})
|
||||
|
||||
const transaction: Transaction = makeTransaction({
|
||||
name: 'Buy batteries',
|
||||
nonce: 1,
|
||||
value: 2,
|
||||
confirmations: List([firstConfirmation]),
|
||||
destination: 'destAddress',
|
||||
threshold: 2,
|
||||
tx: '',
|
||||
})
|
||||
|
||||
const reduxStore = {
|
||||
[SAFE_REDUCER_ID]: Map(),
|
||||
providers: makeProvider(),
|
||||
tokens: undefined,
|
||||
transactions: Map({ fooAddress: List([transaction]) }),
|
||||
}
|
||||
|
||||
// WHEN
|
||||
const transactionsEmpty = safeTransactionsSelector(reduxStore, { safeAddress: '' })
|
||||
// $FlowFixMe
|
||||
const transactionsUndefined = safeTransactionsSelector(reduxStore, { safeAddress: undefined })
|
||||
|
||||
// THEN
|
||||
expect(transactionsEmpty).toEqual(List([]))
|
||||
expect(transactionsUndefined).toEqual(List([]))
|
||||
})
|
||||
|
||||
it('should return empty list if there are transactions belonging to different address', () => {
|
||||
// GIVEN
|
||||
const firstConfirmation: Confirmation = makeConfirmation({
|
||||
owner: makeOwner(),
|
||||
status: true,
|
||||
hash: 'asdf',
|
||||
})
|
||||
|
||||
const transaction: Transaction = makeTransaction({
|
||||
name: 'Buy batteries',
|
||||
nonce: 1,
|
||||
value: 2,
|
||||
confirmations: List([firstConfirmation]),
|
||||
destination: 'destAddress',
|
||||
threshold: 2,
|
||||
tx: '',
|
||||
})
|
||||
|
||||
const reduxStore = {
|
||||
[SAFE_REDUCER_ID]: Map(),
|
||||
providers: makeProvider(),
|
||||
tokens: undefined,
|
||||
transactions: Map({ fooAddress: List([transaction]) }),
|
||||
}
|
||||
|
||||
// WHEN
|
||||
const transactions = safeTransactionsSelector(reduxStore, { safeAddress: 'invented' })
|
||||
|
||||
// THEN
|
||||
expect(transactions).toEqual(List([]))
|
||||
})
|
||||
|
||||
it('should return transactions of safe', () => {
|
||||
// GIVEN
|
||||
const firstConfirmation: Confirmation = makeConfirmation({
|
||||
owner: makeOwner(),
|
||||
status: true,
|
||||
hash: 'asdf',
|
||||
})
|
||||
|
||||
const transaction: Transaction = makeTransaction({
|
||||
name: 'Buy batteries',
|
||||
nonce: 1,
|
||||
value: 2,
|
||||
confirmations: List([firstConfirmation]),
|
||||
destination: 'destAddress',
|
||||
threshold: 2,
|
||||
tx: '',
|
||||
})
|
||||
|
||||
const reduxStore = {
|
||||
[SAFE_REDUCER_ID]: Map(),
|
||||
providers: makeProvider(),
|
||||
tokens: undefined,
|
||||
transactions: Map({ fooAddress: List([transaction]) }),
|
||||
}
|
||||
|
||||
// WHEN
|
||||
const transactions = safeTransactionsSelector(reduxStore, { safeAddress: 'fooAddress' })
|
||||
|
||||
// THEN
|
||||
expect(transactions).toEqual(List([transaction]))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default grantedSelectorTests
|
||||
*/
|
|
@ -23,7 +23,7 @@ describe('DOM > Feature > Funds', () => {
|
|||
accounts = await getWeb3().eth.getAccounts()
|
||||
})
|
||||
|
||||
it('Sends ETH', async () => {
|
||||
it('Sends ETH with threshold = 1', async () => {
|
||||
// GIVEN
|
||||
const ethAmount = '5'
|
||||
await sendEtherTo(safeAddress, ethAmount)
|
||||
|
@ -64,7 +64,7 @@ describe('DOM > Feature > Funds', () => {
|
|||
)
|
||||
})
|
||||
|
||||
it('Sends Tokens', async () => {
|
||||
it('Sends Tokens with threshold = 1', async () => {
|
||||
// GIVEN
|
||||
const numTokens = '100'
|
||||
const tokenAddress = await sendTokenTo(safeAddress, numTokens)
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
// @flow
|
||||
import { Map } from 'immutable'
|
||||
import * as fetchTokensAction from '~/logic/tokens/store/actions/fetchTokens'
|
||||
import { aNewStore } from '~/store'
|
||||
import { aMinedSafe } from '~/test/builder/safe.redux.builder'
|
||||
import { type Token } from '~/logic/tokens/store/model/token'
|
||||
import { TOKEN_REDUCER_ID } from '~/logic/tokens/store/reducer/tokens'
|
||||
import { sendEtherTo, sendTokenTo } from '~/test/utils/tokenMovements'
|
||||
import { dispatchTknBalance } from '~/test/utils/transactions/moveTokens.helper'
|
||||
import { ETH_ADDRESS } from '~/logic/tokens/utils/tokenHelpers'
|
||||
|
||||
describe('Safe - redux balance property', () => {
|
||||
let store
|
||||
let address: string
|
||||
beforeEach(async () => {
|
||||
store = aNewStore()
|
||||
address = await aMinedSafe(store)
|
||||
})
|
||||
|
||||
it('reducer should return 0 to just deployed safe', async () => {
|
||||
// WHEN
|
||||
await store.dispatch(fetchTokensAction.fetchTokens(address))
|
||||
|
||||
// THEN
|
||||
const tokens: Map<string, Map<string, Token>> | typeof undefined = store.getState()[TOKEN_REDUCER_ID]
|
||||
if (!tokens) throw new Error()
|
||||
|
||||
const safeBalances: Map<string, Token> | typeof undefined = tokens.get(address)
|
||||
if (!safeBalances) throw new Error('No tokens available, probably failed to fetch')
|
||||
expect(safeBalances.size).toBe(11)
|
||||
|
||||
// safeBalances.forEach((token: string) => {
|
||||
// const record = safeBalances.get(token)
|
||||
// if (!record) throw new Error()
|
||||
// expect(record.get('funds')).toBe('0')
|
||||
// })
|
||||
})
|
||||
|
||||
it('reducer should return 0.03456 ETH as funds to safe with 0.03456 ETH', async () => {
|
||||
// WHEN
|
||||
await sendEtherTo(address, '0.03456')
|
||||
await store.dispatch(fetchTokensAction.fetchTokens(address))
|
||||
|
||||
// THEN
|
||||
const tokens: Map<string, Map<string, Token>> | typeof undefined = store.getState()[TOKEN_REDUCER_ID]
|
||||
if (!tokens) throw new Error()
|
||||
|
||||
const safeBalances: Map<string, Token> | typeof undefined = tokens.get(address)
|
||||
if (!safeBalances) throw new Error()
|
||||
expect(safeBalances.size).toBe(11)
|
||||
|
||||
const ethBalance = safeBalances.get(ETH_ADDRESS)
|
||||
if (!ethBalance) throw new Error()
|
||||
expect(ethBalance.get('funds')).toBe('0.03456')
|
||||
})
|
||||
|
||||
it('reducer should return 100 TKN when safe has 100 TKN', async () => {
|
||||
// GIVEN
|
||||
const numTokens = '100'
|
||||
const tokenAddress = await sendTokenTo(address, numTokens)
|
||||
|
||||
// WHEN
|
||||
await dispatchTknBalance(store, tokenAddress, address)
|
||||
|
||||
// THEN
|
||||
const safeBalances = store.getState()[TOKEN_REDUCER_ID].get(address)
|
||||
expect(safeBalances.size).toBe(1)
|
||||
|
||||
const tknBalance = safeBalances.get('TKN')
|
||||
expect(tknBalance.get('funds')).toBe(String(numTokens))
|
||||
})
|
||||
})
|
|
@ -1,112 +0,0 @@
|
|||
// @flow
|
||||
import { Map, List } from 'immutable'
|
||||
import { type Safe } from '~/routes/safe/store/models/safe'
|
||||
import { aNewStore } from '~/store'
|
||||
import { aMinedSafe } from '~/test/builder/safe.redux.builder'
|
||||
import updateSafe from '~/routes/safe/store/actions/updateSafe'
|
||||
import { loadSafe } from '~/routes/load/container/Load'
|
||||
import { safesMapSelector } from '~/routes/safeList/store/selectors'
|
||||
import { makeOwner, type Owner } from '~/routes/safe/store/models/owner'
|
||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||
import { safesInitialState } from '~/routes/safe/store/reducer/safe'
|
||||
import { setOwners, OWNERS_KEY } from '~/utils/storage'
|
||||
|
||||
describe('Safe - redux load safe', () => {
|
||||
let store
|
||||
let address: string
|
||||
let accounts
|
||||
beforeEach(async () => {
|
||||
store = aNewStore()
|
||||
address = await aMinedSafe(store)
|
||||
localStorage.clear()
|
||||
accounts = await getWeb3().eth.getAccounts()
|
||||
})
|
||||
|
||||
it('if safe is not present, store and persist it with default names', async () => {
|
||||
const safeName = 'Loaded Safe'
|
||||
const safeAddress = address
|
||||
const updateSafeFn: any = (...args) => store.dispatch(updateSafe(...args))
|
||||
|
||||
await loadSafe(safeName, safeAddress, updateSafeFn)
|
||||
|
||||
const safes: Map<string, Safe> = safesMapSelector(store.getState())
|
||||
expect(safes.size).toBe(1)
|
||||
if (!safes) throw new Error()
|
||||
const safe = safes.get(safeAddress)
|
||||
if (!safe) throw new Error()
|
||||
|
||||
expect(safe.get('name')).toBe(safeName)
|
||||
expect(safe.get('threshold')).toBe(1)
|
||||
expect(safe.get('address')).toBe(safeAddress)
|
||||
expect(safe.get('owners')).toEqual(List([makeOwner({ name: 'UNKNOWN', address: accounts[0] })]))
|
||||
|
||||
expect(await safesInitialState()).toEqual(safes)
|
||||
})
|
||||
|
||||
it('if safe is not present but owners, store and persist it with stored names', async () => {
|
||||
const safeName = 'Loaded Safe'
|
||||
const safeAddress = address
|
||||
const ownerName = 'Foo Bar Restores'
|
||||
const updateSafeFn: any = (...args) => store.dispatch(updateSafe(...args))
|
||||
const owner: Owner = makeOwner({ name: ownerName, address: accounts[0] })
|
||||
setOwners(safeAddress, List([owner]))
|
||||
|
||||
await loadSafe(safeName, safeAddress, updateSafeFn)
|
||||
|
||||
const safes: Map<string, Safe> = safesMapSelector(store.getState())
|
||||
expect(safes.size).toBe(1)
|
||||
if (!safes) throw new Error()
|
||||
const safe = safes.get(safeAddress)
|
||||
if (!safe) throw new Error()
|
||||
|
||||
expect(safe.get('name')).toBe(safeName)
|
||||
expect(safe.get('threshold')).toBe(1)
|
||||
expect(safe.get('address')).toBe(safeAddress)
|
||||
expect(safe.get('owners')).toEqual(List([makeOwner({ name: ownerName, address: accounts[0] })]))
|
||||
|
||||
expect(await safesInitialState()).toEqual(safes)
|
||||
})
|
||||
|
||||
it('if safe is present but no owners, store and persist it with default names', async () => {
|
||||
const safeAddress = await aMinedSafe(store)
|
||||
localStorage.removeItem(`${OWNERS_KEY}-${safeAddress}`)
|
||||
|
||||
const safeName = 'Loaded Safe'
|
||||
const updateSafeFn: any = (...args) => store.dispatch(updateSafe(...args))
|
||||
await loadSafe(safeName, safeAddress, updateSafeFn)
|
||||
|
||||
const safes: Map<string, Safe> = safesMapSelector(store.getState())
|
||||
expect(safes.size).toBe(2)
|
||||
if (!safes) throw new Error()
|
||||
const safe = safes.get(safeAddress)
|
||||
if (!safe) throw new Error()
|
||||
|
||||
expect(safe.get('name')).toBe(safeName)
|
||||
expect(safe.get('threshold')).toBe(1)
|
||||
expect(safe.get('address')).toBe(safeAddress)
|
||||
expect(safe.get('owners')).toEqual(List([makeOwner({ name: 'UNKNOWN', address: accounts[0] })]))
|
||||
|
||||
expect(await safesInitialState()).toEqual(safes)
|
||||
})
|
||||
|
||||
it('if safe is present but owners, store and persist it with stored names', async () => {
|
||||
const safeAddress = await aMinedSafe(store)
|
||||
|
||||
const safeName = 'Loaded Safe'
|
||||
const updateSafeFn: any = (...args) => store.dispatch(updateSafe(...args))
|
||||
await loadSafe(safeName, safeAddress, updateSafeFn)
|
||||
|
||||
const safes: Map<string, Safe> = safesMapSelector(store.getState())
|
||||
expect(safes.size).toBe(2)
|
||||
if (!safes) throw new Error()
|
||||
const safe = safes.get(safeAddress)
|
||||
if (!safe) throw new Error()
|
||||
|
||||
expect(safe.get('name')).toBe(safeName)
|
||||
expect(safe.get('threshold')).toBe(1)
|
||||
expect(safe.get('address')).toBe(safeAddress)
|
||||
expect(safe.get('owners')).toEqual(List([makeOwner({ name: 'Adol 1 Eth Account', address: accounts[0] })]))
|
||||
|
||||
expect(await safesInitialState()).toEqual(safes)
|
||||
})
|
||||
})
|
|
@ -1,237 +0,0 @@
|
|||
// @flow
|
||||
import { List } from 'immutable'
|
||||
import { aNewStore } from '~/store'
|
||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||
import { confirmationsTransactionSelector, safeTransactionsSelector } from '~/routes/safe/store/selectors'
|
||||
import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions'
|
||||
import { type Safe } from '~/routes/safe/store/models/safe'
|
||||
import { getGnosisSafeInstanceAt } from '~/logic/contracts/safeContracts'
|
||||
import { aMinedSafe } from '~/test/builder/safe.redux.builder'
|
||||
import { NAME_PARAM, OWNER_ADDRESS_PARAM, INCREASE_PARAM } from '~/routes/safe/components/AddOwner/AddOwnerForm'
|
||||
import { addOwner } from '~/routes/safe/components/AddOwner/index'
|
||||
import fetchSafe from '~/routes/safe/store/actions/fetchSafe'
|
||||
import { removeOwner, shouldDecrease, initialValuesFrom } from '~/routes/safe/components/RemoveOwner'
|
||||
import { DECREASE_PARAM } from '~/routes/safe/components/RemoveOwner/RemoveOwnerForm'
|
||||
import { getSafeFrom } from '~/test/utils/safeHelper'
|
||||
import { getOwnerNameBy, getOwnerAddressBy } from '~/routes/open/components/fields'
|
||||
import { processTransaction } from '~/logic/safe/safeFrontendOperations'
|
||||
import { allowedRemoveSenderInTxHistoryService } from '~/config'
|
||||
import { calculateValuesAfterRemoving } from '~/routes/open/components/SafeOwnersForm'
|
||||
|
||||
describe('React DOM TESTS > Add and remove owners', () => {
|
||||
const processOwnerModification = async (store, safeAddress, executor, threshold, alreadyConfirmed) => {
|
||||
const reduxTransactions = safeTransactionsSelector(store.getState(), { safeAddress })
|
||||
const tx = reduxTransactions.get(0)
|
||||
if (!tx) throw new Error()
|
||||
|
||||
const confirmed = confirmationsTransactionSelector(store.getState(), { transaction: tx })
|
||||
const data = tx.get('data')
|
||||
expect(data).not.toBe(null)
|
||||
expect(data).not.toBe(undefined)
|
||||
expect(data).not.toBe('')
|
||||
|
||||
return processTransaction(safeAddress, tx, confirmed, executor, threshold, alreadyConfirmed)
|
||||
}
|
||||
|
||||
const assureThresholdIs = async (gnosisSafe, threshold: number) => {
|
||||
const safeThreshold = await gnosisSafe.getThreshold()
|
||||
expect(Number(safeThreshold)).toEqual(threshold)
|
||||
}
|
||||
|
||||
const assureOwnersAre = async (gnosisSafe, ...owners) => {
|
||||
const safeOwners = await gnosisSafe.getOwners()
|
||||
expect(safeOwners.length).toEqual(owners.length)
|
||||
for (let i = 0; i < owners.length; i += 1) {
|
||||
expect(safeOwners[i]).toBe(owners[i])
|
||||
}
|
||||
}
|
||||
|
||||
const getAddressesFrom = (safe: Safe) => safe.get('owners').map(owner => owner.get('address'))
|
||||
|
||||
it.only('creates initialValues removing last owner', () => {
|
||||
const numOwners = 3
|
||||
const values = {
|
||||
moe: 'Bart',
|
||||
[getOwnerNameBy(0)]: 'Foo',
|
||||
[getOwnerAddressBy(0)]: '0x1',
|
||||
[getOwnerNameBy(1)]: 'Bar',
|
||||
[getOwnerAddressBy(1)]: '0x2',
|
||||
[getOwnerNameBy(2)]: 'Baz',
|
||||
[getOwnerAddressBy(2)]: '0x3',
|
||||
}
|
||||
|
||||
const indexToRemove = 2
|
||||
const initialValues = calculateValuesAfterRemoving(indexToRemove, numOwners, values)
|
||||
|
||||
expect(initialValues).toEqual({
|
||||
moe: 'Bart',
|
||||
[getOwnerNameBy(0)]: 'Foo',
|
||||
[getOwnerAddressBy(0)]: '0x1',
|
||||
[getOwnerNameBy(1)]: 'Bar',
|
||||
[getOwnerAddressBy(1)]: '0x2',
|
||||
})
|
||||
})
|
||||
|
||||
it.only('creates initialValues removing middle owner', () => {
|
||||
const numOwners = 3
|
||||
const values = {
|
||||
moe: 'Bart',
|
||||
[getOwnerNameBy(0)]: 'Foo',
|
||||
[getOwnerAddressBy(0)]: '0x1',
|
||||
[getOwnerNameBy(1)]: 'Bar',
|
||||
[getOwnerAddressBy(1)]: '0x2',
|
||||
[getOwnerNameBy(2)]: 'Baz',
|
||||
[getOwnerAddressBy(2)]: '0x3',
|
||||
}
|
||||
|
||||
const indexToRemove = 1
|
||||
const initialValues = calculateValuesAfterRemoving(indexToRemove, numOwners, values)
|
||||
|
||||
expect(initialValues).toEqual({
|
||||
moe: 'Bart',
|
||||
[getOwnerNameBy(0)]: 'Foo',
|
||||
[getOwnerAddressBy(0)]: '0x1',
|
||||
[getOwnerNameBy(1)]: 'Baz',
|
||||
[getOwnerAddressBy(1)]: '0x3',
|
||||
})
|
||||
})
|
||||
|
||||
it('adds owner without increasing the threshold', async () => {
|
||||
// GIVEN
|
||||
const numOwners = 2
|
||||
const threshold = 1
|
||||
const store = aNewStore()
|
||||
const address = await aMinedSafe(store, numOwners, threshold)
|
||||
const accounts = await getWeb3().eth.getAccounts()
|
||||
const gnosisSafe = await getGnosisSafeInstanceAt(address)
|
||||
|
||||
const values = {
|
||||
[NAME_PARAM]: 'Adol 3 Metamask',
|
||||
[OWNER_ADDRESS_PARAM]: accounts[2],
|
||||
[INCREASE_PARAM]: false,
|
||||
}
|
||||
|
||||
// WHEN
|
||||
let safe = getSafeFrom(store.getState(), address)
|
||||
await addOwner(values, safe, threshold, accounts[0])
|
||||
|
||||
// THEN
|
||||
await assureThresholdIs(gnosisSafe, 1)
|
||||
await assureOwnersAre(gnosisSafe, accounts[2], accounts[0], accounts[1])
|
||||
|
||||
await store.dispatch(fetchSafe(safe.get('address')))
|
||||
safe = getSafeFrom(store.getState(), address)
|
||||
expect(safe.get('owners').count()).toBe(3)
|
||||
await assureOwnersAre(gnosisSafe, ...getAddressesFrom(safe))
|
||||
})
|
||||
|
||||
it('adds owner increasing the threshold', async () => {
|
||||
// GIVEN
|
||||
const numOwners = 2
|
||||
const threshold = 1
|
||||
const store = aNewStore()
|
||||
const address = await aMinedSafe(store, numOwners, threshold)
|
||||
const accounts = await getWeb3().eth.getAccounts()
|
||||
const gnosisSafe = await getGnosisSafeInstanceAt(address)
|
||||
|
||||
const values = {
|
||||
[NAME_PARAM]: 'Adol 3 Metamask',
|
||||
[OWNER_ADDRESS_PARAM]: accounts[2],
|
||||
[INCREASE_PARAM]: true,
|
||||
}
|
||||
|
||||
// WHEN
|
||||
let safe = getSafeFrom(store.getState(), address)
|
||||
await addOwner(values, safe, threshold, accounts[0])
|
||||
|
||||
// THEN
|
||||
await assureThresholdIs(gnosisSafe, 2)
|
||||
await assureOwnersAre(gnosisSafe, accounts[2], accounts[0], accounts[1])
|
||||
|
||||
await store.dispatch(fetchSafe(safe.get('address')))
|
||||
safe = getSafeFrom(store.getState(), address)
|
||||
expect(safe.get('owners').count()).toBe(3)
|
||||
await assureOwnersAre(gnosisSafe, ...getAddressesFrom(safe))
|
||||
})
|
||||
|
||||
it('remove owner decreasing owner automatically', async () => {
|
||||
if (!allowedRemoveSenderInTxHistoryService()) {
|
||||
return
|
||||
}
|
||||
|
||||
const numOwners = 2
|
||||
const threshold = 2
|
||||
const store = aNewStore()
|
||||
const address = await aMinedSafe(store, numOwners, threshold)
|
||||
const accounts = await getWeb3().eth.getAccounts()
|
||||
const gnosisSafe = await getGnosisSafeInstanceAt(address)
|
||||
|
||||
const decrease = shouldDecrease(numOwners, threshold)
|
||||
const values = initialValuesFrom(decrease)
|
||||
expect(values[DECREASE_PARAM]).toBe(true)
|
||||
|
||||
let safe = getSafeFrom(store.getState(), address)
|
||||
await removeOwner(values, safe, threshold, accounts[1], 'Adol Metamask 2', accounts[0])
|
||||
await store.dispatch(fetchTransactions(address))
|
||||
await processOwnerModification(store, address, accounts[1], 2, List([accounts[0]]))
|
||||
|
||||
await assureThresholdIs(gnosisSafe, 1)
|
||||
await assureOwnersAre(gnosisSafe, accounts[0])
|
||||
|
||||
await store.dispatch(fetchSafe(safe.get('address')))
|
||||
safe = getSafeFrom(store.getState(), address)
|
||||
expect(safe.get('owners').count()).toBe(1)
|
||||
await assureOwnersAre(gnosisSafe, ...getAddressesFrom(safe))
|
||||
})
|
||||
|
||||
it('remove owner decreasing threshold', async () => {
|
||||
const numOwners = 3
|
||||
const threshold = 2
|
||||
const store = aNewStore()
|
||||
const address = await aMinedSafe(store, numOwners, threshold)
|
||||
const accounts = await getWeb3().eth.getAccounts()
|
||||
const gnosisSafe = await getGnosisSafeInstanceAt(address)
|
||||
|
||||
const decrease = true
|
||||
const values = initialValuesFrom(decrease)
|
||||
|
||||
let safe = getSafeFrom(store.getState(), address)
|
||||
await removeOwner(values, safe, threshold, accounts[2], 'Adol Metamask 3', accounts[0])
|
||||
await store.dispatch(fetchTransactions(address))
|
||||
await processOwnerModification(store, address, accounts[1], 2, List([accounts[0]]))
|
||||
|
||||
await assureThresholdIs(gnosisSafe, 1)
|
||||
await assureOwnersAre(gnosisSafe, accounts[0], accounts[1])
|
||||
|
||||
await store.dispatch(fetchSafe(safe.get('address')))
|
||||
safe = getSafeFrom(store.getState(), address)
|
||||
expect(safe.get('owners').count()).toBe(2)
|
||||
await assureOwnersAre(gnosisSafe, ...getAddressesFrom(safe))
|
||||
})
|
||||
|
||||
it('remove owner without decreasing threshold', async () => {
|
||||
const numOwners = 3
|
||||
const threshold = 2
|
||||
const store = aNewStore()
|
||||
const address = await aMinedSafe(store, numOwners, threshold)
|
||||
const accounts = await getWeb3().eth.getAccounts()
|
||||
const gnosisSafe = await getGnosisSafeInstanceAt(address)
|
||||
|
||||
const decrease = shouldDecrease(numOwners, threshold)
|
||||
const values = initialValuesFrom(decrease)
|
||||
expect(values[DECREASE_PARAM]).toBe(false)
|
||||
|
||||
let safe = getSafeFrom(store.getState(), address)
|
||||
await removeOwner(values, safe, threshold, accounts[2], 'Adol Metamask 3', accounts[0])
|
||||
await store.dispatch(fetchTransactions(address))
|
||||
await processOwnerModification(store, address, accounts[1], 2, List([accounts[0]]))
|
||||
|
||||
await assureThresholdIs(gnosisSafe, 2)
|
||||
await assureOwnersAre(gnosisSafe, accounts[0], accounts[1])
|
||||
|
||||
await store.dispatch(fetchSafe(safe.get('address')))
|
||||
safe = getSafeFrom(store.getState(), address)
|
||||
expect(safe.get('owners').count()).toBe(2)
|
||||
await assureOwnersAre(gnosisSafe, ...getAddressesFrom(safe))
|
||||
})
|
||||
})
|
|
@ -1,178 +0,0 @@
|
|||
// @flow
|
||||
import { List } from 'immutable'
|
||||
import { createTransaction } from '~/logic/safe/safeFrontendOperations'
|
||||
import { getGnosisSafeInstanceAt } from '~/logic/contracts/safeContracts'
|
||||
import { type Safe } from '~/routes/safe/store/models/safe'
|
||||
import { makeOwner } from '~/routes/safe/store/models/owner'
|
||||
import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions'
|
||||
import { makeConfirmation } from '~/routes/safe/store/models/confirmation'
|
||||
import { aNewStore } from '~/store'
|
||||
import { aMinedSafe } from '~/test/builder/safe.redux.builder'
|
||||
import { getSafeFrom } from '~/test/utils/safeHelper'
|
||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||
import { safeTransactionsSelector } from '~/routes/safe/store/selectors'
|
||||
import fetchSafe from '~/routes/safe/store/actions/fetchSafe'
|
||||
import { testTransactionFrom, testSizeOfTransactions } from './utils/historyServiceHelper'
|
||||
|
||||
describe('Transactions Suite', () => {
|
||||
let store: Store
|
||||
let safeAddress: string
|
||||
let accounts: string[]
|
||||
beforeAll(async () => {
|
||||
accounts = await getWeb3().eth.getAccounts()
|
||||
})
|
||||
beforeEach(async () => {
|
||||
localStorage.clear()
|
||||
|
||||
store = aNewStore()
|
||||
safeAddress = await aMinedSafe(store)
|
||||
})
|
||||
|
||||
it('retrieves tx info from service having subject available', async () => {
|
||||
let safe: Safe = getSafeFrom(store.getState(), safeAddress)
|
||||
const gnosisSafe = await getGnosisSafeInstanceAt(safeAddress)
|
||||
const firstTxData = gnosisSafe.contract.methods.addOwnerWithThreshold(accounts[1], 2).encodeABI()
|
||||
const executor = accounts[0]
|
||||
const nonce = await gnosisSafe.nonce()
|
||||
const firstTxHash = await createTransaction(
|
||||
safe,
|
||||
'Add Owner Second account',
|
||||
safeAddress,
|
||||
'0',
|
||||
nonce,
|
||||
executor,
|
||||
firstTxData,
|
||||
)
|
||||
await store.dispatch(fetchSafe(safe.get('address')))
|
||||
safe = getSafeFrom(store.getState(), safeAddress)
|
||||
|
||||
const secondTxData = gnosisSafe.contract.methods.addOwnerWithThreshold(accounts[2], 2).encodeABI()
|
||||
const secondTxHash = await createTransaction(
|
||||
safe,
|
||||
'Add Owner Third account',
|
||||
safeAddress,
|
||||
'0',
|
||||
nonce + 100,
|
||||
executor,
|
||||
secondTxData,
|
||||
)
|
||||
await store.dispatch(fetchSafe(safe.get('address')))
|
||||
safe = getSafeFrom(store.getState(), safeAddress)
|
||||
|
||||
// WHEN
|
||||
await store.dispatch(fetchTransactions(safeAddress))
|
||||
let transactions = safeTransactionsSelector(store.getState(), { safeAddress })
|
||||
testSizeOfTransactions(transactions, 2)
|
||||
|
||||
// THEN
|
||||
const firstTxConfirmations = List([
|
||||
makeConfirmation({
|
||||
owner: makeOwner({ address: getWeb3().toChecksumAddress(executor), name: 'Adol 1 Eth Account' }),
|
||||
type: 'execution',
|
||||
hash: firstTxHash,
|
||||
}),
|
||||
])
|
||||
testTransactionFrom(
|
||||
transactions,
|
||||
0,
|
||||
'Add Owner Second account',
|
||||
nonce,
|
||||
0,
|
||||
safeAddress,
|
||||
firstTxData,
|
||||
true,
|
||||
firstTxConfirmations,
|
||||
)
|
||||
|
||||
const secondTxConfirmations = List([
|
||||
makeConfirmation({
|
||||
owner: makeOwner({ address: getWeb3().toChecksumAddress(accounts[0]), name: 'Adol 1 Eth Account' }),
|
||||
type: 'confirmation',
|
||||
hash: secondTxHash,
|
||||
}),
|
||||
])
|
||||
testTransactionFrom(
|
||||
transactions,
|
||||
1,
|
||||
'Add Owner Third account',
|
||||
nonce + 100,
|
||||
0,
|
||||
safeAddress,
|
||||
secondTxData,
|
||||
false,
|
||||
secondTxConfirmations,
|
||||
)
|
||||
|
||||
localStorage.clear()
|
||||
|
||||
await store.dispatch(fetchTransactions(safeAddress))
|
||||
transactions = safeTransactionsSelector(store.getState(), { safeAddress })
|
||||
|
||||
testSizeOfTransactions(transactions, 2)
|
||||
const firstTxConfWithoutStorage = List([
|
||||
makeConfirmation({
|
||||
owner: makeOwner({ address: getWeb3().toChecksumAddress(executor), name: 'UNKNOWN' }),
|
||||
type: 'execution',
|
||||
hash: firstTxHash,
|
||||
}),
|
||||
])
|
||||
testTransactionFrom(transactions, 0, 'Unknown', nonce, 0, safeAddress, firstTxData, true, firstTxConfWithoutStorage)
|
||||
const secondTxConfWithoutStorage = List([
|
||||
makeConfirmation({
|
||||
owner: makeOwner({ address: getWeb3().toChecksumAddress(executor), name: 'UNKNOWN' }),
|
||||
type: 'confirmation',
|
||||
hash: secondTxHash,
|
||||
}),
|
||||
])
|
||||
testTransactionFrom(
|
||||
transactions,
|
||||
1,
|
||||
'Unknown',
|
||||
nonce + 100,
|
||||
0,
|
||||
safeAddress,
|
||||
secondTxData,
|
||||
false,
|
||||
secondTxConfWithoutStorage,
|
||||
)
|
||||
})
|
||||
|
||||
it('returns empty list of trnsactions when safe is not configured', async () => {
|
||||
// routes/safe/transactions.selector.js the 4 cases
|
||||
// confirmations.selector.js the last one
|
||||
})
|
||||
|
||||
it('pending transactions are treated correctly', async () => {
|
||||
// create a safe 3 owners 3 threshold
|
||||
// create a tx adding 4th owner
|
||||
// confirm tx and check on every step
|
||||
})
|
||||
|
||||
it('returns count of confirmed but not executed txs', async () => {
|
||||
// pendingTransactionSelector
|
||||
})
|
||||
|
||||
it('returns count of executed txs', async () => {
|
||||
// confirmationsTransactionSelector
|
||||
})
|
||||
|
||||
it('returns correctly transaction list when safe is not available', async () => {
|
||||
// routes/safe/test/transactions.selector.js
|
||||
})
|
||||
|
||||
it('process only updated txs', async () => {
|
||||
// Basically I would like when I call the GET TXs endpoint to retrieve those transactions ORDERED based on
|
||||
// when they have been updated (just created, or just added another extra confirmation).
|
||||
// In that way I do not need to parse and threat all txs in client side and also we mitigate the risk of
|
||||
// do not get old txs updates. For doing that I would need to keep stored a number indicating
|
||||
// if the tx has been updated in DB.
|
||||
// For instance:
|
||||
/*
|
||||
create tx1 ---> [{ tx:1, updated: 1 }]
|
||||
create tx2 ---> [{ tx:2, updated: 1 }, { tx:1, updated: 1 }]
|
||||
user 2 confirms tx1 ---> [{ tx:1, updated: 2 }, { tx:2, updated: 1 }]
|
||||
|
||||
In that way I keep stored tx1 -> 1 and if I see tx2 -> 2 I do not skip it
|
||||
*/
|
||||
})
|
||||
})
|
|
@ -1,64 +0,0 @@
|
|||
// @flow
|
||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||
import { type Match } from 'react-router-dom'
|
||||
import { getFirstTokenContract, getSecondTokenContract } from '~/test/utils/tokenMovements'
|
||||
import { aNewStore } from '~/store'
|
||||
import { aMinedSafe } from '~/test/builder/safe.redux.builder'
|
||||
import { renderSafeView } from '~/test/builder/safe.dom.utils'
|
||||
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
|
||||
import { testToken } from '~/test/builder/tokens.dom.utils'
|
||||
import * as fetchTokensModule from '~/logic/tokens/store/actions/fetchTokens'
|
||||
import * as enhancedFetchModule from '~/utils/fetch'
|
||||
import addToken from '~/logic/tokens/store/actions/addToken'
|
||||
|
||||
describe('DOM > Feature > Add new ERC 20 Tokens', () => {
|
||||
// let web3
|
||||
// let accounts
|
||||
// let firstErc20Token
|
||||
// let secondErc20Token
|
||||
// beforeAll(async () => {
|
||||
// web3 = getWeb3()
|
||||
// accounts = await web3.eth.getAccounts()
|
||||
// firstErc20Token = await getFirstTokenContract(web3, accounts[0])
|
||||
// secondErc20Token = await getSecondTokenContract(web3, accounts[0])
|
||||
// // $FlowFixMe
|
||||
// enhancedFetchModule.enhancedFetch = jest.fn()
|
||||
// enhancedFetchModule.enhancedFetch.mockImplementation(() => Promise.resolve({
|
||||
// results: [
|
||||
// {
|
||||
// address: firstErc20Token.address,
|
||||
// name: 'First Token Example',
|
||||
// symbol: 'FTE',
|
||||
// decimals: 18,
|
||||
// logoUri: 'https://upload.wikimedia.org/wikipedia/commons/c/c0/Earth_simple_icon.png',
|
||||
// },
|
||||
// ],
|
||||
// }))
|
||||
// })
|
||||
// it('persist added custom ERC 20 tokens as active when reloading the page', async () => {
|
||||
// // GIVEN
|
||||
// const store = aNewStore()
|
||||
// const safeAddress = await aMinedSafe(store)
|
||||
// await store.dispatch(fetchTokensModule.fetchTokens(safeAddress))
|
||||
// const values = {
|
||||
// [TOKEN_ADRESS_PARAM]: secondErc20Token.address,
|
||||
// [TOKEN_NAME_PARAM]: 'Custom ERC20 Token',
|
||||
// [TOKEN_SYMBOL_PARAM]: 'CTS',
|
||||
// [TOKEN_DECIMALS_PARAM]: '10',
|
||||
// [TOKEN_LOGO_URL_PARAM]: 'https://example.com',
|
||||
// }
|
||||
// const customAddTokensFn: any = (...args) => store.dispatch(addToken(...args))
|
||||
// await addTokenFnc(values, customAddTokensFn, safeAddress)
|
||||
// renderSafeView(store, safeAddress)
|
||||
// // WHEN
|
||||
// const reloadedStore = aNewStore()
|
||||
// await reloadedStore.dispatch(fetchTokensModule.fetchTokens(safeAddress))
|
||||
// renderSafeView(reloadedStore, safeAddress) // reload
|
||||
// // THEN
|
||||
// const match: Match = buildMathPropsFrom(safeAddress)
|
||||
// const activeTokenList = activeTokensSelector(reloadedStore.getState(), { match })
|
||||
// expect(activeTokenList.count()).toBe(2)
|
||||
// testToken(activeTokenList.get(0), 'CTS', true)
|
||||
// testToken(activeTokenList.get(1), 'ETH', true)
|
||||
// })
|
||||
})
|
|
@ -1,83 +0,0 @@
|
|||
// @flow
|
||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||
import { type Match } from 'react-router-dom'
|
||||
import { getFirstTokenContract, getSecondTokenContract } from '~/test/utils/tokenMovements'
|
||||
import { aNewStore } from '~/store'
|
||||
import { aMinedSafe } from '~/test/builder/safe.redux.builder'
|
||||
import { renderSafeView } from '~/test/builder/safe.dom.utils'
|
||||
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
|
||||
import { testToken } from '~/test/builder/tokens.dom.utils'
|
||||
import * as fetchTokensModule from '~/logic/tokens/store/actions/fetchTokens'
|
||||
import * as enhancedFetchModule from '~/utils/fetch'
|
||||
import addToken from '~/logic/tokens/store/actions/addToken'
|
||||
import removeTokenAction from '~/logic/tokens/store/actions/removeToken'
|
||||
import { makeToken } from '~/logic/tokens/store/model/token'
|
||||
|
||||
describe('DOM > Feature > Add new ERC 20 Tokens', () => {
|
||||
// let web3
|
||||
// let accounts
|
||||
// let firstErc20Token
|
||||
// let secondErc20Token
|
||||
// beforeAll(async () => {
|
||||
// web3 = getWeb3()
|
||||
// accounts = await web3.eth.getAccounts()
|
||||
// firstErc20Token = await getFirstTokenContract(web3, accounts[0])
|
||||
// secondErc20Token = await getSecondTokenContract(web3, accounts[0])
|
||||
// // $FlowFixMe
|
||||
// enhancedFetchModule.enhancedFetch = jest.fn()
|
||||
// enhancedFetchModule.enhancedFetch.mockImplementation(() => Promise.resolve({
|
||||
// results: [
|
||||
// {
|
||||
// address: firstErc20Token.address,
|
||||
// name: 'First Token Example',
|
||||
// symbol: 'FTE',
|
||||
// decimals: 18,
|
||||
// logoUri: 'https://upload.wikimedia.org/wikipedia/commons/c/c0/Earth_simple_icon.png',
|
||||
// },
|
||||
// ],
|
||||
// }))
|
||||
// })
|
||||
// const checkTokensOf = (store: Store, safeAddress: string) => {
|
||||
// const match: Match = buildMathPropsFrom(safeAddress)
|
||||
// const activeTokenList = activeTokensSelector(store.getState(), { match })
|
||||
// expect(activeTokenList.count()).toBe(1)
|
||||
// testToken(activeTokenList.get(0), 'ETH', true)
|
||||
// const tokenList = tokenListSelector(store.getState(), { match })
|
||||
// expect(tokenList.count()).toBe(2)
|
||||
// testToken(tokenList.get(0), 'FTE', false)
|
||||
// testToken(tokenList.get(1), 'ETH', true)
|
||||
// }
|
||||
// it('removes custom ERC 20 including page reload', async () => {
|
||||
// // GIVEN
|
||||
// const store = aNewStore()
|
||||
// const safeAddress = await aMinedSafe(store)
|
||||
// await store.dispatch(fetchTokensModule.fetchTokens(safeAddress))
|
||||
// const values = {
|
||||
// [TOKEN_ADRESS_PARAM]: secondErc20Token.address,
|
||||
// [TOKEN_NAME_PARAM]: 'Custom ERC20 Token',
|
||||
// [TOKEN_SYMBOL_PARAM]: 'CTS',
|
||||
// [TOKEN_DECIMALS_PARAM]: '10',
|
||||
// [TOKEN_LOGO_URL_PARAM]: 'https://example.com',
|
||||
// }
|
||||
// const customAddTokensFn: any = (...args) => store.dispatch(addToken(...args))
|
||||
// await addTokenFnc(values, customAddTokensFn, safeAddress)
|
||||
// const token = makeToken({
|
||||
// address: secondErc20Token.address,
|
||||
// name: 'Custom ERC20 Token',
|
||||
// symbol: 'CTS',
|
||||
// decimals: 10,
|
||||
// logoUri: 'https://example.com',
|
||||
// status: true,
|
||||
// removable: true,
|
||||
// })
|
||||
// const customRemoveTokensFnc: any = (...args) => store.dispatch(removeTokenAction(...args))
|
||||
// await removeToken(safeAddress, token, customRemoveTokensFnc)
|
||||
// checkTokensOf(store, safeAddress)
|
||||
// // WHEN
|
||||
// const reloadedStore = aNewStore()
|
||||
// await reloadedStore.dispatch(fetchTokensModule.fetchTokens(safeAddress))
|
||||
// renderSafeView(reloadedStore, safeAddress) // reload
|
||||
// // THEN
|
||||
// checkTokensOf(reloadedStore, safeAddress)
|
||||
// })
|
||||
})
|
Loading…
Reference in New Issue