diff --git a/package.json b/package.json index 7a8b575b..2a0eef9b 100644 --- a/package.json +++ b/package.json @@ -104,7 +104,7 @@ "classnames": "^2.2.5", "css-loader": "3.0.0", "detect-port": "^1.2.2", - "eslint": "6.0.1", + "eslint": "5.16.0", "eslint-config-airbnb": "17.1.1", "eslint-plugin-flowtype": "3.11.1", "eslint-plugin-import": "2.18.0", diff --git a/readme.md b/readme.md index e1785137..79e939fd 100644 --- a/readme.md +++ b/readme.md @@ -37,7 +37,7 @@ yarn start To run the test, you'll need to migrate contracts `safe-contracts` to the local ganache-cli -1. Migrating Safe Contracts: +1. Migrate Safe Contracts: ``` git clone https://github.com/gnosis/safe-contracts.git cd safe-contracts @@ -50,7 +50,15 @@ Inside `safe-react` directory ``` npx truffle migrate ``` -3. Run the tests: +3. Run `transaction-history-service` +``` +git clone https://github.com/gnosis/safe-transaction-history.git +cd safe-transaction-history +git checkout develop +docker-compose build +docker-compose up -d +``` +4. Run the tests: ``` yarn test ``` diff --git a/src/config/development.js b/src/config/development.js index e8b284ab..97098783 100644 --- a/src/config/development.js +++ b/src/config/development.js @@ -1,14 +1,12 @@ // @flow import { TX_SERVICE_HOST, - ENABLED_TX_SERVICE_REMOVAL_SENDER, SIGNATURES_VIA_METAMASK, RELAY_API_URL, } from '~/config/names' const devConfig = { [TX_SERVICE_HOST]: 'https://safe-transaction-service.dev.gnosisdev.com/api/v1/', - [ENABLED_TX_SERVICE_REMOVAL_SENDER]: false, [SIGNATURES_VIA_METAMASK]: false, [RELAY_API_URL]: 'https://safe-relay.staging.gnosisdev.com/api/v1/', } diff --git a/src/config/index.js b/src/config/index.js index 4e8e8756..5eebb734 100644 --- a/src/config/index.js +++ b/src/config/index.js @@ -2,7 +2,6 @@ import { ensureOnce } from '~/utils/singleton' import { TX_SERVICE_HOST, - ENABLED_TX_SERVICE_REMOVAL_SENDER, SIGNATURES_VIA_METAMASK, RELAY_API_URL, } from '~/config/names' @@ -34,12 +33,6 @@ export const getTxServiceUriFrom = (safeAddress: string) => `safes/${safeAddress export const getRelayUrl = () => getConfig()[RELAY_API_URL] -export const allowedRemoveSenderInTxHistoryService = () => { - const config = getConfig() - - return config[ENABLED_TX_SERVICE_REMOVAL_SENDER] -} - export const signaturesViaMetamask = () => { const config = getConfig() diff --git a/src/config/names.js b/src/config/names.js index 89e44160..92d82cdd 100644 --- a/src/config/names.js +++ b/src/config/names.js @@ -1,6 +1,5 @@ // @flow export const TX_SERVICE_HOST = 'tsh' -export const ENABLED_TX_SERVICE_REMOVAL_SENDER = 'trs' export const SIGNATURES_VIA_METAMASK = 'svm' export const RELAY_API_URL = 'rau' diff --git a/src/config/production.js b/src/config/production.js index 6dc2ebf8..0eb827a1 100644 --- a/src/config/production.js +++ b/src/config/production.js @@ -1,14 +1,12 @@ // @flow import { TX_SERVICE_HOST, - ENABLED_TX_SERVICE_REMOVAL_SENDER, SIGNATURES_VIA_METAMASK, RELAY_API_URL, } from '~/config/names' const prodConfig = { [TX_SERVICE_HOST]: 'https://safe-transaction-service.dev.gnosisdev.com/api/v1/', - [ENABLED_TX_SERVICE_REMOVAL_SENDER]: false, [SIGNATURES_VIA_METAMASK]: false, [RELAY_API_URL]: 'https://safe-relay.staging.gnosisdev.com/api/v1/', } diff --git a/src/config/testing.js b/src/config/testing.js index d2e6de7e..a43f6f8e 100644 --- a/src/config/testing.js +++ b/src/config/testing.js @@ -1,14 +1,12 @@ // @flow import { TX_SERVICE_HOST, - ENABLED_TX_SERVICE_REMOVAL_SENDER, SIGNATURES_VIA_METAMASK, RELAY_API_URL, } from '~/config/names' const testConfig = { - [TX_SERVICE_HOST]: 'https://safe-transaction-service.dev.gnosisdev.com/api/v1/', - [ENABLED_TX_SERVICE_REMOVAL_SENDER]: false, + [TX_SERVICE_HOST]: 'http://localhost:8000/api/v1/', [SIGNATURES_VIA_METAMASK]: false, [RELAY_API_URL]: 'https://safe-relay.staging.gnosisdev.com/api/v1', } diff --git a/src/logic/safe/transactions/send.js b/src/logic/safe/transactions/send.js index 1d98901e..abe2920d 100644 --- a/src/logic/safe/transactions/send.js +++ b/src/logic/safe/transactions/send.js @@ -39,19 +39,17 @@ export const approveTransaction = async ( ) const receipt = await safeInstance.approveHash(contractTxHash, { from: sender }) - if (process.env.NODE_ENV !== 'test') { - await saveTxToHistory( - safeInstance, - to, - valueInWei, - data, - operation, - nonce, - receipt.tx, // tx hash, - sender, - TX_TYPE_CONFIRMATION, - ) - } + await saveTxToHistory( + safeInstance, + to, + valueInWei, + data, + operation, + nonce, + receipt.tx, // tx hash, + sender, + TX_TYPE_CONFIRMATION, + ) return receipt } @@ -91,19 +89,17 @@ export const executeTransaction = async ( { from: sender }, ) - if (process.env.NODE_ENV !== 'test') { - await saveTxToHistory( - safeInstance, - to, - valueInWei, - data, - operation, - nonce, - receipt.tx, // tx hash, - sender, - TX_TYPE_EXECUTION, - ) - } + await saveTxToHistory( + safeInstance, + to, + valueInWei, + data, + operation, + nonce, + receipt.tx, // tx hash, + sender, + TX_TYPE_EXECUTION, + ) return receipt } catch (error) { diff --git a/src/routes/safe/store/actions/fetchTransactions.js b/src/routes/safe/store/actions/fetchTransactions.js index 5c571e73..01fd9d3e 100644 --- a/src/routes/safe/store/actions/fetchTransactions.js +++ b/src/routes/safe/store/actions/fetchTransactions.js @@ -38,7 +38,7 @@ type TxServiceModel = { isExecuted: boolean, } -const buildTransactionFrom = async (safeAddress: string, tx: TxServiceModel, safeSubjects: Map) => { +export const buildTransactionFrom = async (safeAddress: string, tx: TxServiceModel, safeSubjects: Map) => { const name = safeSubjects.get(String(tx.nonce)) || 'Unknown' const storedOwners = await getOwners(safeAddress) const confirmations = List( diff --git a/src/test/safe.dom.funds.threshold>1.test.js b/src/test/safe.dom.funds.threshold>1.test.js index 46e7f7c0..b8a3c6d4 100644 --- a/src/test/safe.dom.funds.threshold>1.test.js +++ b/src/test/safe.dom.funds.threshold>1.test.js @@ -1 +1,80 @@ // @flow +import { fireEvent, cleanup } from '@testing-library/react' +import { List } from 'immutable' +import { aNewStore } from '~/store' +import { aMinedSafe } from '~/test/builder/safe.redux.builder' +import { sendTokenTo, sendEtherTo } from '~/test/utils/tokenMovements' +import { renderSafeView } from '~/test/builder/safe.dom.utils' +import { getWeb3, getBalanceInEtherOf } from '~/logic/wallets/getWeb3' +import { dispatchAddTokenToList } from '~/test/utils/transactions/moveTokens.helper' +import { sleep } from '~/utils/timer' +import TokenBalanceRecord from '~/routes/safe/store/models/tokenBalance' +import { calculateBalanceOf } from '~/routes/safe/store/actions/fetchTokenBalances' +import updateActiveTokens from '~/routes/safe/store/actions/updateActiveTokens' +import { addTransactions } from '~/routes/safe/store/actions/addTransactions' +import { buildTransactionFrom } from '~/routes/safe/store/actions/fetchTransactions' +import '@testing-library/jest-dom/extend-expect' +import updateSafe from '~/routes/safe/store/actions/updateSafe' +import { BALANCE_ROW_TEST_ID } from '~/routes/safe/components/Balances' +import { fillAndSubmitSendFundsForm } from './utils/transactions' +import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'; + +afterEach(cleanup) + +describe('DOM > Feature > Sending Funds', () => { + let store + let safeAddress: string + let accounts + beforeEach(async () => { + store = aNewStore() + // using 4th account because other accounts were used in other tests and paid gas + safeAddress = await aMinedSafe(store, 2, 2) + accounts = await getWeb3().eth.getAccounts() + }) + + it('Sends ETH with threshold = 2', async () => { + // GIVEN + const ethAmount = '5' + await sendEtherTo(safeAddress, ethAmount) + const balanceAfterSendingEthToSafe = await getBalanceInEtherOf(accounts[0]) + + // WHEN + const SafeDom = renderSafeView(store, safeAddress) + await sleep(1300) + + // Open send funds modal + const balanceRows = SafeDom.getAllByTestId(BALANCE_ROW_TEST_ID) + expect(balanceRows[0]).toHaveTextContent(`${ethAmount} ETH`) + const sendButton = SafeDom.getByTestId('balance-send-btn') + fireEvent.click(sendButton) + + await fillAndSubmitSendFundsForm(SafeDom, sendButton, ethAmount, accounts[0]) + + // CONFIRM TX + const transaction = { + to: accounts[0], + value: parseInt(ethAmount, 10) * (10 ** 18), + data: EMPTY_DATA, + operation: 0, + nonce: 0, + submissionDate: new Date().toISOString(), + executionDate: null, + isExecuted: false, + confirmations: [ + owner: accounts[0], + submissionDate: new Date().toISOString(), + + ] + } + + // THEN + const safeFunds = await getBalanceInEtherOf(safeAddress) + expect(Number(safeFunds)).toBe(0) + + const receiverFunds = await getBalanceInEtherOf(accounts[0]) + const ESTIMATED_GASCOSTS = 0.3 + expect(Number(parseInt(receiverFunds, 10) - parseInt(balanceAfterSendingEthToSafe, 10))).toBeGreaterThan( + parseInt(ethAmount, 10) - ESTIMATED_GASCOSTS, + ) + }) +}) diff --git a/src/test/safe.dom.transactions.test.js b/src/test/safe.dom.transactions.test.js deleted file mode 100644 index cf6474da..00000000 --- a/src/test/safe.dom.transactions.test.js +++ /dev/null @@ -1,11 +0,0 @@ -// @flow - -// TBD - -describe('DOM > Feature > SAFE MULTISIG Transactions', () => { - it.only('mines correctly all multisig txs in a 1 owner & 1 threshold safe', async () => {}) - - it.only('mines withdraw process correctly all multisig txs in a 2 owner & 2 threshold safe', async () => {}) - - it.only('approves and executes pending transactions', async () => {}) -}) diff --git a/yarn.lock b/yarn.lock index 5f68481f..a700fa2c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4207,14 +4207,14 @@ bignumber.js@^7.2.1: resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f" integrity sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ== +"bignumber.js@git+https://github.com/debris/bignumber.js#master": + version "2.0.7" + resolved "git+https://github.com/debris/bignumber.js#c7a38de919ed75e6fb6ba38051986e294b328df9" + "bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2": version "2.0.7" resolved "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2" -"bignumber.js@git+https://github.com/debris/bignumber.js.git#master": - version "2.0.7" - resolved "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9" - "bignumber.js@git+https://github.com/frozeman/bignumber.js-nolookahead.git": version "2.0.7" resolved "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" @@ -6820,49 +6820,7 @@ eslint-visitor-keys@^1.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== -eslint@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.0.1.tgz#4a32181d72cb999d6f54151df7d337131f81cda7" - integrity sha512-DyQRaMmORQ+JsWShYsSg4OPTjY56u1nCjAmICrE8vLWqyLKxhFXOthwMj1SA8xwfrv0CofLNVnqbfyhwCkaO0w== - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.10.0" - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^4.0.1" - doctrine "^3.0.0" - eslint-scope "^4.0.3" - eslint-utils "^1.3.1" - eslint-visitor-keys "^1.0.0" - espree "^6.0.0" - esquery "^1.0.1" - esutils "^2.0.2" - file-entry-cache "^5.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^3.1.0" - globals "^11.7.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - inquirer "^6.2.2" - is-glob "^4.0.0" - js-yaml "^3.13.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.11" - minimatch "^3.0.4" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.2" - progress "^2.0.0" - regexpp "^2.0.1" - semver "^5.5.1" - strip-ansi "^4.0.0" - strip-json-comments "^2.0.1" - table "^5.2.3" - text-table "^0.2.0" - -eslint@^5.0.0, eslint@^5.5.0: +eslint@5.16.0, eslint@^5.0.0, eslint@^5.5.0: version "5.16.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== @@ -6921,15 +6879,6 @@ espree@^5.0.1: acorn-jsx "^5.0.0" eslint-visitor-keys "^1.0.0" -espree@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.0.0.tgz#716fc1f5a245ef5b9a7fdb1d7b0d3f02322e75f6" - integrity sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q== - dependencies: - acorn "^6.0.7" - acorn-jsx "^5.0.0" - eslint-visitor-keys "^1.0.0" - esprima@^3.1.3, esprima@~3.1.0: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"