Merge pull request #7803 from MetaMask/Version-v7.7.2

Version v7.7.2 RC
feature/default_network_editable
Thomas Huang 5 years ago committed by GitHub
commit 0dad516b9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      CHANGELOG.md
  2. 2
      app/manifest.json
  3. 4
      package.json
  4. 19
      test/e2e/metamask-ui.spec.js
  5. 16
      test/integration/lib/confirm-sig-requests.js
  6. 2
      ui/app/components/ui/token-input/token-input.component.js
  7. 2
      ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.js
  8. 12
      ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js
  9. 2
      ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.container.js
  10. 2
      ui/app/pages/confirm-transaction/confirm-transaction.container.js
  11. 7
      ui/app/pages/send/send-content/send-amount-row/send-amount-row.component.js
  12. 12
      ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js
  13. 5
      ui/app/pages/send/send-footer/send-footer.component.js
  14. 2
      ui/app/pages/send/send-footer/send-footer.container.js
  15. 14
      ui/app/pages/send/send-footer/tests/send-footer-component.test.js
  16. 28
      ui/app/pages/send/send-footer/tests/send-footer-container.test.js
  17. 2
      ui/index.js
  18. 30
      yarn.lock

@ -2,6 +2,10 @@
## Current Develop Branch
## 7.7.2 Fri Jan 10 2020
- [#7753](https://github.com/MetaMask/metamask-extension/pull/7753): Fix gas estimate for tokens
- [#7473](https://github.com/MetaMask/metamask-extension/pull/7473): Fix transaction order on transaction confirmation screen
## 7.7.1 Wed Dec 04 2019
- [#7488](https://github.com/MetaMask/metamask-extension/pull/7488): Fix text overlap when expanding transaction
- [#7491](https://github.com/MetaMask/metamask-extension/pull/7491): Update gas when asset is changed on send screen

@ -1,7 +1,7 @@
{
"name": "__MSG_appName__",
"short_name": "__MSG_appName__",
"version": "7.7.1",
"version": "7.7.2",
"manifest_version": 2,
"author": "https://metamask.io",
"description": "__MSG_appDescription__",

@ -92,7 +92,7 @@
"eth-json-rpc-errors": "^1.1.0",
"eth-json-rpc-filters": "^4.1.1",
"eth-json-rpc-infura": "^4.0.1",
"eth-json-rpc-middleware": "^4.2.0",
"eth-json-rpc-middleware": "^4.4.0",
"eth-keyring-controller": "^5.3.0",
"eth-ledger-bridge-keyring": "^0.2.0",
"eth-method-registry": "^1.2.0",
@ -117,7 +117,7 @@
"gaba": "^1.9.0",
"human-standard-token-abi": "^2.0.0",
"jazzicon": "^1.2.0",
"json-rpc-engine": "^5.1.5",
"json-rpc-engine": "^5.1.6",
"json-rpc-middleware-stream": "^2.1.1",
"jsonschema": "^1.2.4",
"lodash.debounce": "^4.0.8",

@ -553,11 +553,11 @@ describe('MetaMask', function () {
await delay(regularDelayMs)
let transactions = await findElements(driver, By.css('.transaction-list-item'))
await transactions[3].click()
await transactions[0].click()
await delay(regularDelayMs)
try {
transactions = await findElements(driver, By.css('.transaction-list-item'), 1000)
await transactions[3].click()
await transactions[0].click()
} catch (e) {
console.log(e)
}
@ -631,24 +631,24 @@ describe('MetaMask', function () {
navigationElement = await findElement(driver, By.css('.confirm-page-container-navigation'))
navigationText = await navigationElement.getText()
assert.equal(navigationText.includes('3'), true, 'correct transaction in focus')
assert.equal(navigationText.includes('2'), true, 'correct (same) transaction in focus')
})
it('confirms a transaction', async () => {
it('rejects a transaction', async () => {
await delay(tinyDelayMs)
const confirmButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Confirm')]`), 10000)
const confirmButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Reject')]`), 10000)
await confirmButton.click()
await delay(largeDelayMs * 2)
const navigationElement = await findElement(driver, By.css('.confirm-page-container-navigation'))
await delay(tinyDelayMs)
const navigationText = await navigationElement.getText()
assert.equal(navigationText.includes('4'), true, 'transaction confirmed')
assert.equal(navigationText.includes('4'), true, 'transaction rejected')
})
it('rejects a transaction', async () => {
it('confirms a transaction', async () => {
await delay(tinyDelayMs / 2)
const rejectButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Reject')]`), 10000)
const rejectButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Confirm')]`), 10000)
await delay(tinyDelayMs / 2)
await rejectButton.click()
await delay(regularDelayMs)
@ -657,7 +657,7 @@ describe('MetaMask', function () {
await delay(tinyDelayMs / 2)
const navigationText = await navigationElement.getText()
await delay(tinyDelayMs / 2)
assert.equal(navigationText.includes('3'), true, 'transaction rejected')
assert.equal(navigationText.includes('3'), true, 'transaction confirmed')
})
it('rejects the rest of the transactions', async () => {
@ -965,6 +965,7 @@ describe('MetaMask', function () {
// Continue to next screen
const nextScreen = await findElement(driver, By.xpath(`//button[contains(text(), 'Next')]`))
await driver.wait(until.elementIsEnabled(nextScreen))
await nextScreen.click()
await delay(regularDelayMs)
})

@ -38,8 +38,8 @@ async function runConfirmSigRequestsTest (assert) {
const pendingRequestItem = $.find('.transaction-list-item .transaction-list-item__grid')
if (pendingRequestItem[2]) {
pendingRequestItem[2].click()
if (pendingRequestItem[0]) {
pendingRequestItem[0].click()
}
await timeout(1000)
@ -47,11 +47,9 @@ async function runConfirmSigRequestsTest (assert) {
let confirmSigHeadline = await queryAsync($, '.request-signature__headline')
assert.equal(confirmSigHeadline[0].textContent, 'Your signature is being requested')
const confirmSigMessage = await queryAsync($, '.request-signature__notice')
assert.ok(confirmSigMessage[0].textContent.match(/^Signing\sthis\smessage/))
let confirmSigRowValue = await queryAsync($, '.request-signature__row-value')
assert.equal(confirmSigRowValue[0].textContent, '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0')
assert.equal(confirmSigRowValue[0].textContent, 'Hi, Alice!')
assert.equal(confirmSigRowValue[1].textContent, '1337')
let confirmSigSignButton = await queryAsync($, 'button.btn-secondary.btn--large')
confirmSigSignButton[0].click()
@ -68,9 +66,11 @@ async function runConfirmSigRequestsTest (assert) {
confirmSigHeadline = await queryAsync($, '.request-signature__headline')
assert.equal(confirmSigHeadline[0].textContent, 'Your signature is being requested')
const confirmSigMessage = await queryAsync($, '.request-signature__notice')
assert.ok(confirmSigMessage[0].textContent.match(/^Signing\sthis\smessage/))
confirmSigRowValue = await queryAsync($, '.request-signature__row-value')
assert.equal(confirmSigRowValue[0].textContent, 'Hi, Alice!')
assert.equal(confirmSigRowValue[1].textContent, '1337')
assert.equal(confirmSigRowValue[0].textContent, '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0')
confirmSigSignButton = await queryAsync($, 'button.btn-secondary.btn--large')
confirmSigSignButton[0].click()

@ -78,7 +78,7 @@ export default class TokenInput extends PureComponent {
}
handleBlur = () => {
this.props.onBlur(this.state.hexValue)
this.props.onBlur && this.props.onBlur(this.state.hexValue)
}
renderConversionComponent () {

@ -557,7 +557,7 @@ export default class ConfirmTransactionBase extends Component {
getNavigateTxData () {
const { currentNetworkUnapprovedTxs, txData: { id } = {} } = this.props
const enumUnapprovedTxs = Object.keys(currentNetworkUnapprovedTxs).reverse()
const enumUnapprovedTxs = Object.keys(currentNetworkUnapprovedTxs)
const currentPosition = enumUnapprovedTxs.indexOf(id ? id.toString() : '')
return {

@ -1,7 +1,6 @@
import { connect } from 'react-redux'
import { compose } from 'recompose'
import { withRouter } from 'react-router-dom'
import R from 'ramda'
import contractMap from 'eth-contract-metadata'
import ConfirmTransactionBase from './confirm-transaction-base.component'
import {
@ -72,7 +71,9 @@ const mapStateToProps = (state, ownProps) => {
nonce,
} = confirmTransaction
const { txParams = {}, lastGasPrice, id: transactionId, transactionCategory } = txData
const transaction = R.find(({ id }) => id === (transactionId || Number(paramsTransactionId)))(selectedAddressTxList) || {}
const transaction = Object.values(selectedAddressTxList).find(
({ id }) => id === (transactionId || Number(paramsTransactionId))
) || {}
const {
from: fromAddress,
to: txParamsToAddress,
@ -118,10 +119,9 @@ const mapStateToProps = (state, ownProps) => {
txData.simulationFails = transaction.simulationFails
}
const currentNetworkUnapprovedTxs = R.filter(
({ metamaskNetworkId }) => metamaskNetworkId === network,
unapprovedTxs,
)
const currentNetworkUnapprovedTxs = Object.keys(unapprovedTxs)
.filter(key => unapprovedTxs[key].metamaskNetworkId === network)
.reduce((acc, key) => ({ ...acc, [key]: unapprovedTxs[key] }), {})
const unapprovedTxCount = valuesFor(currentNetworkUnapprovedTxs).length
const insufficientBalance = !isBalanceSufficient({

@ -18,7 +18,7 @@ const mapStateToProps = (state, ownProps) => {
const unconfirmedTransactions = unconfirmedTransactionsListSelector(state)
const totalUnconfirmed = unconfirmedTransactions.length
const transaction = totalUnconfirmed
? unapprovedTxs[transactionId] || unconfirmedTransactions[totalUnconfirmed - 1]
? unapprovedTxs[transactionId] || unconfirmedTransactions[0]
: {}
return {

@ -35,7 +35,7 @@ const mapStateToProps = (state, ownProps) => {
const unconfirmedTransactions = unconfirmedTransactionsListSelector(state)
const totalUnconfirmed = unconfirmedTransactions.length
const transaction = totalUnconfirmed
? unapprovedTxs[id] || unconfirmedTransactions[totalUnconfirmed - 1]
? unapprovedTxs[id] || unconfirmedTransactions[0]
: {}
const { id: transactionId, transactionCategory } = transaction

@ -1,5 +1,6 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import debounce from 'lodash.debounce'
import SendRowWrapper from '../send-row-wrapper'
import AmountMaxButton from './amount-max-button'
import UserPreferencedCurrencyInput from '../../../../components/app/user-preferenced-currency-input'
@ -32,6 +33,8 @@ export default class SendAmountRow extends Component {
t: PropTypes.func,
}
updateGas = debounce(this.updateGas.bind(this), 500)
validateAmount (amount) {
const {
amountConversionRate,
@ -90,8 +93,8 @@ export default class SendAmountRow extends Component {
return (
<Component
onChange={newAmount => this.validateAmount(newAmount)}
onBlur={newAmount => {
onChange={newAmount => {
this.validateAmount(newAmount)
this.updateGas(newAmount)
this.updateAmount(newAmount)
}}

@ -8,6 +8,8 @@ import SendRowWrapper from '../../send-row-wrapper/send-row-wrapper.component'
import AmountMaxButton from '../amount-max-button/amount-max-button.container'
import UserPreferencedTokenInput from '../../../../../components/app/user-preferenced-token-input'
import timeout from '../../../../../../lib/test-timeout'
const propsMethodSpies = {
setMaxModeTo: sinon.spy(),
updateSendAmount: sinon.spy(),
@ -153,9 +155,8 @@ describe('SendAmountRow Component', function () {
assert(wrapper.find(SendRowWrapper).childAt(1).is(UserPreferencedTokenInput))
})
it('should render the UserPreferencedTokenInput with the correct props', () => {
it('should render the UserPreferencedTokenInput with the correct props', async () => {
const {
onBlur,
onChange,
error,
value,
@ -164,8 +165,9 @@ describe('SendAmountRow Component', function () {
assert.equal(value, 'mockAmount')
assert.equal(SendAmountRow.prototype.updateGas.callCount, 0)
assert.equal(SendAmountRow.prototype.updateAmount.callCount, 0)
onBlur('mockNewAmount')
assert.equal(SendAmountRow.prototype.updateGas.callCount, 1)
assert.equal(SendAmountRow.prototype.validateAmount.callCount, 0)
onChange('mockNewAmount')
await timeout(501)
assert.deepEqual(
SendAmountRow.prototype.updateGas.getCall(0).args,
['mockNewAmount']
@ -175,8 +177,6 @@ describe('SendAmountRow Component', function () {
SendAmountRow.prototype.updateAmount.getCall(0).args,
['mockNewAmount']
)
assert.equal(SendAmountRow.prototype.validateAmount.callCount, 0)
onChange('mockNewAmount')
assert.equal(SendAmountRow.prototype.validateAmount.callCount, 1)
assert.deepEqual(
SendAmountRow.prototype.validateAmount.getCall(0).args,

@ -28,6 +28,7 @@ export default class SendFooter extends Component {
update: PropTypes.func,
sendErrors: PropTypes.object,
gasEstimateType: PropTypes.string,
gasIsLoading: PropTypes.bool,
}
static contextTypes = {
@ -102,10 +103,10 @@ export default class SendFooter extends Component {
}
formShouldBeDisabled () {
const { data, inError, selectedToken, tokenBalance, gasTotal, to, gasLimit } = this.props
const { data, inError, selectedToken, tokenBalance, gasTotal, to, gasLimit, gasIsLoading } = this.props
const missingTokenBalance = selectedToken && !tokenBalance
const gasLimitTooLow = gasLimit < 5208 // 5208 is hex value of 21000, minimum gas limit
const shouldBeDisabled = inError || !gasTotal || missingTokenBalance || !(data || to) || gasLimitTooLow
const shouldBeDisabled = inError || !gasTotal || missingTokenBalance || !(data || to) || gasLimitTooLow || gasIsLoading
return shouldBeDisabled
}

@ -23,6 +23,7 @@ import {
getUnapprovedTxs,
getSendErrors,
} from '../send.selectors'
import { getGasIsLoading } from '../../../selectors/selectors'
import {
isSendFormInError,
} from './send-footer.selectors'
@ -62,6 +63,7 @@ function mapStateToProps (state) {
unapprovedTxs: getUnapprovedTxs(state),
sendErrors: getSendErrors(state),
gasEstimateType,
gasIsLoading: getGasIsLoading(state),
}
}

@ -81,22 +81,34 @@ describe('SendFooter Component', function () {
'should return true if inError is truthy': {
inError: true,
expectedResult: true,
gasIsLoading: false,
},
'should return true if gasTotal is falsy': {
inError: false,
gasTotal: false,
expectedResult: true,
gasIsLoading: false,
},
'should return true if to is truthy': {
to: '0xsomevalidAddress',
inError: false,
gasTotal: false,
expectedResult: true,
gasIsLoading: false,
},
'should return true if selectedToken is truthy and tokenBalance is falsy': {
selectedToken: true,
tokenBalance: null,
expectedResult: true,
gasIsLoading: false,
},
'should return true if gasIsLoading is truthy but all other params are falsy': {
inError: false,
gasTotal: null,
selectedToken: null,
tokenBalance: 0,
expectedResult: true,
gasIsLoading: true,
},
'should return false if inError is false and all other params are truthy': {
inError: false,
@ -104,7 +116,9 @@ describe('SendFooter Component', function () {
selectedToken: true,
tokenBalance: 123,
expectedResult: false,
gasIsLoading: false,
},
}
Object.entries(config).map(([description, obj]) => {
it(description, () => {

@ -2,7 +2,6 @@ import assert from 'assert'
import proxyquire from 'proxyquire'
import sinon from 'sinon'
let mapStateToProps
let mapDispatchToProps
const actionSpies = {
@ -22,8 +21,7 @@ const utilsStubs = {
proxyquire('../send-footer.container.js', {
'react-redux': {
connect: (ms, md) => {
mapStateToProps = ms
connect: (_, md) => {
mapDispatchToProps = md
return () => ({})
},
@ -55,30 +53,6 @@ proxyquire('../send-footer.container.js', {
describe('send-footer container', () => {
describe('mapStateToProps()', () => {
it('should map the correct properties to props', () => {
assert.deepEqual(mapStateToProps('mockState'), {
amount: 'mockAmount:mockState',
data: 'mockHexData:mockState',
selectedToken: 'mockSelectedToken:mockState',
editingTransactionId: 'mockEditingTransactionId:mockState',
from: 'mockFromObject:mockState',
gasLimit: 'mockGasLimit:mockState',
gasPrice: 'mockGasPrice:mockState',
gasTotal: 'mockGasTotal:mockState',
inError: 'mockInError:mockState',
to: 'mockTo:mockState',
toAccounts: 'mockToAccounts:mockState',
tokenBalance: 'mockTokenBalance:mockState',
unapprovedTxs: 'mockUnapprovedTxs:mockState',
sendErrors: 'mockSendErrors:mockState',
gasEstimateType: 'mockGasEstimateType:mockState',
})
})
})
describe('mapDispatchToProps()', () => {
let dispatchSpy
let mapDispatchToPropsObject

@ -61,7 +61,7 @@ async function startApp (metamaskState, backgroundConnection, opts) {
const numberOfUnapprivedTx = unapprovedTxsAll.length
if (numberOfUnapprivedTx > 0) {
store.dispatch(actions.showConfTxPage({
id: unapprovedTxsAll[numberOfUnapprivedTx - 1].id,
id: unapprovedTxsAll[0].id,
}))
}

@ -10140,7 +10140,7 @@ eth-json-rpc-middleware@^1.5.0:
promise-to-callback "^1.0.0"
tape "^4.6.3"
eth-json-rpc-middleware@^4.1.4, eth-json-rpc-middleware@^4.1.5, eth-json-rpc-middleware@^4.2.0:
eth-json-rpc-middleware@^4.1.4, eth-json-rpc-middleware@^4.1.5:
version "4.2.0"
resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-4.2.0.tgz#cfb77c5056cb8001548c6c7d54f4af5fce04d489"
integrity sha512-90LljqRyJhkg7fOwKunh1lu1Mr5bspXMBDitaTGyGPPNiFTbMrhtfbf9fteYlXRFCbq+aIFWwl/X+P7nkrdkLg==
@ -10160,6 +10160,26 @@ eth-json-rpc-middleware@^4.1.4, eth-json-rpc-middleware@^4.1.5, eth-json-rpc-mid
pify "^3.0.0"
safe-event-emitter "^1.0.1"
eth-json-rpc-middleware@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-4.4.0.tgz#ef63b783b48dcbea9c1fe25c79e6ea01510e5877"
integrity sha512-IeOsil/XiHsybJO9nFf86+1+YIqGQWPPfiTEp3WLkpLZhJm97kw6tFM7GttIZXIcwtaO3zEXgY6PWAH1jkB3ag==
dependencies:
btoa "^1.2.1"
clone "^2.1.1"
eth-json-rpc-errors "^1.0.1"
eth-query "^2.1.2"
eth-sig-util "^1.4.2"
ethereumjs-block "^1.6.0"
ethereumjs-tx "^1.3.7"
ethereumjs-util "^5.1.2"
ethereumjs-vm "^2.6.0"
fetch-ponyfill "^4.0.0"
json-rpc-engine "^5.1.3"
json-stable-stringify "^1.0.1"
pify "^3.0.0"
safe-event-emitter "^1.0.1"
eth-keyring-controller@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/eth-keyring-controller/-/eth-keyring-controller-5.3.0.tgz#8d85a67b894360ab7d601222ca71df8ed5f456c6"
@ -15861,10 +15881,10 @@ json-rpc-engine@^3.4.0, json-rpc-engine@^3.6.0:
promise-to-callback "^1.0.0"
safe-event-emitter "^1.0.1"
json-rpc-engine@^5.1.3, json-rpc-engine@^5.1.5:
version "5.1.5"
resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-5.1.5.tgz#a5f9915356ea916d5305716354080723c63dede7"
integrity sha512-HTT9HixG4j8vHYrmJIckgbISW9Q8tCkySv7x7Q8zjMpcw10wSe/dZSQ0w08VkDm3y195K4074UlvD3hxaznvlw==
json-rpc-engine@^5.1.3, json-rpc-engine@^5.1.6:
version "5.1.6"
resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-5.1.6.tgz#3823c1e227657ac5f22a36351db5bb76fa70cf38"
integrity sha512-9nDeIIu6o7cvzWRrHNuNi+TiGe+YWOp3ZQkHtpPnQzXuX8Y5ZU2Oot3FDI+DaQyXIqQ6SjtM6rixDOJTjjA8NA==
dependencies:
async "^2.0.1"
eth-json-rpc-errors "^2.0.0"

Loading…
Cancel
Save