mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Merge pull request #6021 from MetaMask/i5943-shapeshift-tx
Order shapeshift transactions by time within the transactions list
This commit is contained in:
commit
ab9c20db5b
File diff suppressed because one or more lines are too long
@ -635,7 +635,7 @@ describe('MetaMask', function () {
|
|||||||
await confirmButton.click()
|
await confirmButton.click()
|
||||||
await delay(largeDelayMs)
|
await delay(largeDelayMs)
|
||||||
|
|
||||||
driver.wait(async () => {
|
await driver.wait(async () => {
|
||||||
const confirmedTxes = await findElements(driver, By.css('.transaction-list__completed-transactions .transaction-list-item'))
|
const confirmedTxes = await findElements(driver, By.css('.transaction-list__completed-transactions .transaction-list-item'))
|
||||||
return confirmedTxes.length === 4
|
return confirmedTxes.length === 4
|
||||||
}, 10000)
|
}, 10000)
|
||||||
@ -695,7 +695,7 @@ describe('MetaMask', function () {
|
|||||||
await confirmButton.click()
|
await confirmButton.click()
|
||||||
await delay(regularDelayMs)
|
await delay(regularDelayMs)
|
||||||
|
|
||||||
driver.wait(async () => {
|
await driver.wait(async () => {
|
||||||
const confirmedTxes = await findElements(driver, By.css('.transaction-list__completed-transactions .transaction-list-item'))
|
const confirmedTxes = await findElements(driver, By.css('.transaction-list__completed-transactions .transaction-list-item'))
|
||||||
return confirmedTxes.length === 5
|
return confirmedTxes.length === 5
|
||||||
}, 10000)
|
}, 10000)
|
||||||
@ -727,7 +727,7 @@ describe('MetaMask', function () {
|
|||||||
await confirmButton.click()
|
await confirmButton.click()
|
||||||
await delay(regularDelayMs)
|
await delay(regularDelayMs)
|
||||||
|
|
||||||
driver.wait(async () => {
|
await driver.wait(async () => {
|
||||||
const confirmedTxes = await findElements(driver, By.css('.transaction-list__completed-transactions .transaction-list-item'))
|
const confirmedTxes = await findElements(driver, By.css('.transaction-list__completed-transactions .transaction-list-item'))
|
||||||
return confirmedTxes.length === 6
|
return confirmedTxes.length === 6
|
||||||
}, 10000)
|
}, 10000)
|
||||||
@ -911,7 +911,7 @@ describe('MetaMask', function () {
|
|||||||
await driver.wait(until.elementTextMatches(txValues[0], /-50\s*TST/), 10000)
|
await driver.wait(until.elementTextMatches(txValues[0], /-50\s*TST/), 10000)
|
||||||
}
|
}
|
||||||
|
|
||||||
driver.wait(async () => {
|
await driver.wait(async () => {
|
||||||
const confirmedTxes = await findElements(driver, By.css('.transaction-list__completed-transactions .transaction-list-item'))
|
const confirmedTxes = await findElements(driver, By.css('.transaction-list__completed-transactions .transaction-list-item'))
|
||||||
return confirmedTxes.length === 1
|
return confirmedTxes.length === 1
|
||||||
}, 10000)
|
}, 10000)
|
||||||
@ -962,26 +962,29 @@ describe('MetaMask', function () {
|
|||||||
const [gasPriceInput, gasLimitInput] = await findElements(driver, By.css('.advanced-tab__gas-edit-row__input'))
|
const [gasPriceInput, gasLimitInput] = await findElements(driver, By.css('.advanced-tab__gas-edit-row__input'))
|
||||||
await gasPriceInput.clear()
|
await gasPriceInput.clear()
|
||||||
await delay(tinyDelayMs)
|
await delay(tinyDelayMs)
|
||||||
|
|
||||||
|
await gasPriceInput.sendKeys(Key.BACK_SPACE)
|
||||||
|
await gasPriceInput.sendKeys(Key.BACK_SPACE)
|
||||||
await gasPriceInput.sendKeys('10')
|
await gasPriceInput.sendKeys('10')
|
||||||
await delay(tinyDelayMs)
|
await delay(tinyDelayMs)
|
||||||
await gasLimitInput.clear()
|
await gasLimitInput.clear()
|
||||||
await delay(tinyDelayMs)
|
await delay(tinyDelayMs)
|
||||||
await gasLimitInput.sendKeys(Key.chord(Key.CONTROL, 'a'))
|
await gasLimitInput.sendKeys(Key.chord(Key.CONTROL, 'a'))
|
||||||
|
await gasLimitInput.sendKeys(Key.BACK_SPACE)
|
||||||
|
await gasLimitInput.sendKeys(Key.BACK_SPACE)
|
||||||
|
await gasLimitInput.sendKeys(Key.BACK_SPACE)
|
||||||
|
await gasLimitInput.sendKeys(Key.BACK_SPACE)
|
||||||
|
await gasLimitInput.sendKeys(Key.BACK_SPACE)
|
||||||
await gasLimitInput.sendKeys('60000')
|
await gasLimitInput.sendKeys('60000')
|
||||||
await gasLimitInput.sendKeys(Key.chord(Key.CONTROL, 'e'))
|
await gasLimitInput.sendKeys(Key.chord(Key.CONTROL, 'e'))
|
||||||
|
|
||||||
// Needed for different behaviour of input in different versions of firefox
|
|
||||||
const gasLimitInputValue = await gasLimitInput.getAttribute('value')
|
|
||||||
if (gasLimitInputValue === '600001') {
|
|
||||||
await gasLimitInput.sendKeys(Key.BACK_SPACE)
|
|
||||||
}
|
|
||||||
|
|
||||||
const save = await findElement(driver, By.css('.page-container__footer-button'))
|
const save = await findElement(driver, By.css('.page-container__footer-button'))
|
||||||
await save.click()
|
await save.click()
|
||||||
await driver.wait(until.stalenessOf(gasModal))
|
await driver.wait(until.stalenessOf(gasModal))
|
||||||
|
|
||||||
const gasFeeInputs = await findElements(driver, By.css('.confirm-detail-row__primary'))
|
const gasFeeInputs = await findElements(driver, By.css('.confirm-detail-row__primary'))
|
||||||
assert.equal(await gasFeeInputs[0].getText(), '0.0006')
|
const renderedGasFee = await gasFeeInputs[0].getText()
|
||||||
|
assert.equal(renderedGasFee, '0.0006')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('submits the transaction', async function () {
|
it('submits the transaction', async function () {
|
||||||
@ -991,7 +994,7 @@ describe('MetaMask', function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('finds the transaction in the transactions list', async function () {
|
it('finds the transaction in the transactions list', async function () {
|
||||||
driver.wait(async () => {
|
await driver.wait(async () => {
|
||||||
const confirmedTxes = await findElements(driver, By.css('.transaction-list__completed-transactions .transaction-list-item'))
|
const confirmedTxes = await findElements(driver, By.css('.transaction-list__completed-transactions .transaction-list-item'))
|
||||||
return confirmedTxes.length === 2
|
return confirmedTxes.length === 2
|
||||||
}, 10000)
|
}, 10000)
|
||||||
@ -1036,7 +1039,7 @@ describe('MetaMask', function () {
|
|||||||
await driver.switchTo().window(extension)
|
await driver.switchTo().window(extension)
|
||||||
await delay(regularDelayMs)
|
await delay(regularDelayMs)
|
||||||
|
|
||||||
driver.wait(async () => {
|
await driver.wait(async () => {
|
||||||
const pendingTxes = await findElements(driver, By.css('.transaction-list__pending-transactions .transaction-list-item'))
|
const pendingTxes = await findElements(driver, By.css('.transaction-list__pending-transactions .transaction-list-item'))
|
||||||
return pendingTxes.length === 1
|
return pendingTxes.length === 1
|
||||||
}, 10000)
|
}, 10000)
|
||||||
@ -1116,7 +1119,7 @@ describe('MetaMask', function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('finds the transaction in the transactions list', async function () {
|
it('finds the transaction in the transactions list', async function () {
|
||||||
driver.wait(async () => {
|
await driver.wait(async () => {
|
||||||
const confirmedTxes = await findElements(driver, By.css('.transaction-list__completed-transactions .transaction-list-item'))
|
const confirmedTxes = await findElements(driver, By.css('.transaction-list__completed-transactions .transaction-list-item'))
|
||||||
return confirmedTxes.length === 3
|
return confirmedTxes.length === 3
|
||||||
}, 10000)
|
}, 10000)
|
||||||
|
@ -16,7 +16,7 @@ QUnit.test('renders list items successfully', (assert) => {
|
|||||||
|
|
||||||
global.ethQuery = global.ethQuery || {}
|
global.ethQuery = global.ethQuery || {}
|
||||||
global.ethQuery.getTransactionCount = (_, cb) => {
|
global.ethQuery.getTransactionCount = (_, cb) => {
|
||||||
cb(null, '0x3')
|
cb(null, '0x4')
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runTxListItemsTest (assert, done) {
|
async function runTxListItemsTest (assert, done) {
|
||||||
@ -30,25 +30,29 @@ async function runTxListItemsTest (assert, done) {
|
|||||||
metamaskLogo[0].click()
|
metamaskLogo[0].click()
|
||||||
|
|
||||||
const txListItems = await queryAsync($, '.transaction-list-item')
|
const txListItems = await queryAsync($, '.transaction-list-item')
|
||||||
assert.equal(txListItems.length, 7, 'all tx list items are rendered')
|
assert.equal(txListItems.length, 8, 'all tx list items are rendered')
|
||||||
|
|
||||||
const approvedTx = txListItems[0]
|
const unapprovedMsg = txListItems[0]
|
||||||
const approvedTxRenderedStatus = await findAsync($(approvedTx), '.transaction-list-item__status')
|
|
||||||
assert.equal(approvedTxRenderedStatus[0].textContent, 'pending', 'approvedTx has correct label')
|
|
||||||
|
|
||||||
const unapprovedMsg = txListItems[1]
|
|
||||||
const unapprovedMsgDescription = await findAsync($(unapprovedMsg), '.transaction-list-item__action')
|
const unapprovedMsgDescription = await findAsync($(unapprovedMsg), '.transaction-list-item__action')
|
||||||
assert.equal(unapprovedMsgDescription[0].textContent, 'Signature Request', 'unapprovedMsg has correct description')
|
assert.equal(unapprovedMsgDescription[0].textContent, 'Signature Request', 'unapprovedMsg has correct description')
|
||||||
|
|
||||||
const shapeShiftTx = txListItems[4]
|
const approvedTx = txListItems[2]
|
||||||
const shapeShiftTxStatus = await findAsync($(shapeShiftTx), '.flex-column div:eq(1)')
|
const approvedTxRenderedStatus = await findAsync($(approvedTx), '.transaction-list-item__status')
|
||||||
assert.equal(shapeShiftTxStatus[0].textContent, 'No deposits received', 'shapeShiftTx has correct status')
|
assert.equal(approvedTxRenderedStatus[0].textContent, 'pending', 'approvedTx has correct label')
|
||||||
|
|
||||||
const rejectedTx = txListItems[5]
|
const confirmedTokenTx1 = txListItems[4]
|
||||||
const rejectedTxRenderedStatus = await findAsync($(rejectedTx), '.transaction-list-item__status')
|
const confirmedTokenTx1Address = await findAsync($(confirmedTokenTx1), '.transaction-list-item__status')
|
||||||
assert.equal(rejectedTxRenderedStatus[0].textContent, 'Rejected', 'rejectedTx has correct label')
|
assert.equal(confirmedTokenTx1Address[0].textContent, 'Confirmed', 'confirmedTokenTx has correct status')
|
||||||
|
|
||||||
const confirmedTokenTx = txListItems[6]
|
const shapeShiftTx1 = txListItems[5]
|
||||||
const confirmedTokenTxAddress = await findAsync($(confirmedTokenTx), '.transaction-list-item__status')
|
const shapeShiftTx1Status = await findAsync($(shapeShiftTx1), '.flex-column div:eq(1)')
|
||||||
assert.equal(confirmedTokenTxAddress[0].textContent, 'Confirmed', 'confirmedTokenTx has correct address')
|
assert.equal(shapeShiftTx1Status[0].textContent, 'No deposits received', 'shapeShiftTx has correct status')
|
||||||
|
|
||||||
|
const confirmedTokenTx2 = txListItems[6]
|
||||||
|
const confirmedTokenTx2Address = await findAsync($(confirmedTokenTx2), '.transaction-list-item__status')
|
||||||
|
assert.equal(confirmedTokenTx2Address[0].textContent, 'Confirmed', 'confirmedTokenTx has correct status')
|
||||||
|
|
||||||
|
const shapeShiftTx2 = txListItems[7]
|
||||||
|
const shapeShiftTx2Address = await findAsync($(shapeShiftTx2), '.flex-column div:eq(1)')
|
||||||
|
assert.equal(shapeShiftTx2Address[0].textContent, 'No deposits received', 'shapeShiftTx has correct status')
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ const insertOrderedNonce = (nonces, nonceToInsert) => {
|
|||||||
for (let i = 0; i < nonces.length; i++) {
|
for (let i = 0; i < nonces.length; i++) {
|
||||||
const nonce = nonces[i]
|
const nonce = nonces[i]
|
||||||
|
|
||||||
if (Number(hexToDecimal(nonce)) < Number(hexToDecimal(nonceToInsert))) {
|
if (Number(hexToDecimal(nonce)) > Number(hexToDecimal(nonceToInsert))) {
|
||||||
insertIndex = i
|
insertIndex = i
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -138,17 +138,17 @@ const insertTransactionByTime = (transactions, transaction) => {
|
|||||||
* @param {transactionGroup[]} transactionGroups - Array of transactionGroup objects.
|
* @param {transactionGroup[]} transactionGroups - Array of transactionGroup objects.
|
||||||
* @param {transactionGroup} transactionGroup - transactionGroup object to be inserted into the
|
* @param {transactionGroup} transactionGroup - transactionGroup object to be inserted into the
|
||||||
* array of transactionGroups.
|
* array of transactionGroups.
|
||||||
* @returns {transactionGroup[]}
|
|
||||||
*/
|
*/
|
||||||
const insertTransactionGroupByTime = (transactionGroups, transactionGroup) => {
|
const insertTransactionGroupByTime = (transactionGroups, transactionGroup) => {
|
||||||
const { primaryTransaction: { time } = {} } = transactionGroup
|
const { primaryTransaction: { time: groupToInsertTime } = {} } = transactionGroup
|
||||||
|
|
||||||
let insertIndex = transactionGroups.length
|
let insertIndex = transactionGroups.length
|
||||||
|
|
||||||
for (let i = 0; i < transactionGroups.length; i++) {
|
for (let i = 0; i < transactionGroups.length; i++) {
|
||||||
const txGroup = transactionGroups[i]
|
const txGroup = transactionGroups[i]
|
||||||
|
const { primaryTransaction: { time } = {} } = txGroup
|
||||||
|
|
||||||
if (txGroup.time > time) {
|
if (time > groupToInsertTime) {
|
||||||
insertIndex = i
|
insertIndex = i
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -157,6 +157,22 @@ const insertTransactionGroupByTime = (transactionGroups, transactionGroup) => {
|
|||||||
transactionGroups.splice(insertIndex, 0, transactionGroup)
|
transactionGroups.splice(insertIndex, 0, transactionGroup)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name mergeShapeshiftTransactionGroups
|
||||||
|
* @private
|
||||||
|
* @description Inserts (mutates) shapeshift transactionGroups into an array of nonce-ordered
|
||||||
|
* transactionGroups by time. Shapeshift transactionGroups need to be sorted by time within the list
|
||||||
|
* of transactions as they do not have nonces.
|
||||||
|
* @param {transactionGroup[]} orderedTransactionGroups - Array of transactionGroups ordered by
|
||||||
|
* nonce.
|
||||||
|
* @param {transactionGroup[]} shapeshiftTransactionGroups - Array of shapeshift transactionGroups
|
||||||
|
*/
|
||||||
|
const mergeShapeshiftTransactionGroups = (orderedTransactionGroups, shapeshiftTransactionGroups) => {
|
||||||
|
shapeshiftTransactionGroups.forEach(shapeshiftGroup => {
|
||||||
|
insertTransactionGroupByTime(orderedTransactionGroups, shapeshiftGroup)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name nonceSortedTransactionsSelector
|
* @name nonceSortedTransactionsSelector
|
||||||
* @description Returns an array of transactionGroups sorted by nonce in ascending order.
|
* @description Returns an array of transactionGroups sorted by nonce in ascending order.
|
||||||
@ -166,11 +182,12 @@ export const nonceSortedTransactionsSelector = createSelector(
|
|||||||
transactionsSelector,
|
transactionsSelector,
|
||||||
(transactions = []) => {
|
(transactions = []) => {
|
||||||
const unapprovedTransactionGroups = []
|
const unapprovedTransactionGroups = []
|
||||||
|
const shapeshiftTransactionGroups = []
|
||||||
const orderedNonces = []
|
const orderedNonces = []
|
||||||
const nonceToTransactionsMap = {}
|
const nonceToTransactionsMap = {}
|
||||||
|
|
||||||
transactions.forEach(transaction => {
|
transactions.forEach(transaction => {
|
||||||
const { txParams: { nonce } = {}, status, type, time: txTime } = transaction
|
const { txParams: { nonce } = {}, status, type, time: txTime, key } = transaction
|
||||||
|
|
||||||
if (typeof nonce === 'undefined') {
|
if (typeof nonce === 'undefined') {
|
||||||
const transactionGroup = {
|
const transactionGroup = {
|
||||||
@ -181,7 +198,11 @@ export const nonceSortedTransactionsSelector = createSelector(
|
|||||||
hasCancelled: false,
|
hasCancelled: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
insertTransactionGroupByTime(unapprovedTransactionGroups, transactionGroup)
|
if (key === 'shapeshift') {
|
||||||
|
shapeshiftTransactionGroups.push(transactionGroup)
|
||||||
|
} else {
|
||||||
|
insertTransactionGroupByTime(unapprovedTransactionGroups, transactionGroup)
|
||||||
|
}
|
||||||
} else if (nonce in nonceToTransactionsMap) {
|
} else if (nonce in nonceToTransactionsMap) {
|
||||||
const nonceProps = nonceToTransactionsMap[nonce]
|
const nonceProps = nonceToTransactionsMap[nonce]
|
||||||
insertTransactionByTime(nonceProps.transactions, transaction)
|
insertTransactionByTime(nonceProps.transactions, transaction)
|
||||||
@ -224,6 +245,7 @@ export const nonceSortedTransactionsSelector = createSelector(
|
|||||||
})
|
})
|
||||||
|
|
||||||
const orderedTransactionGroups = orderedNonces.map(nonce => nonceToTransactionsMap[nonce])
|
const orderedTransactionGroups = orderedNonces.map(nonce => nonceToTransactionsMap[nonce])
|
||||||
|
mergeShapeshiftTransactionGroups(orderedTransactionGroups, shapeshiftTransactionGroups)
|
||||||
return unapprovedTransactionGroups.concat(orderedTransactionGroups)
|
return unapprovedTransactionGroups.concat(orderedTransactionGroups)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -237,9 +259,7 @@ export const nonceSortedTransactionsSelector = createSelector(
|
|||||||
export const nonceSortedPendingTransactionsSelector = createSelector(
|
export const nonceSortedPendingTransactionsSelector = createSelector(
|
||||||
nonceSortedTransactionsSelector,
|
nonceSortedTransactionsSelector,
|
||||||
(transactions = []) => (
|
(transactions = []) => (
|
||||||
transactions
|
transactions.filter(({ primaryTransaction }) => primaryTransaction.status in pendingStatusHash)
|
||||||
.filter(({ primaryTransaction }) => primaryTransaction.status in pendingStatusHash)
|
|
||||||
.reverse()
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -252,9 +272,9 @@ export const nonceSortedPendingTransactionsSelector = createSelector(
|
|||||||
export const nonceSortedCompletedTransactionsSelector = createSelector(
|
export const nonceSortedCompletedTransactionsSelector = createSelector(
|
||||||
nonceSortedTransactionsSelector,
|
nonceSortedTransactionsSelector,
|
||||||
(transactions = []) => (
|
(transactions = []) => (
|
||||||
transactions.filter(({ primaryTransaction }) => {
|
transactions
|
||||||
return !(primaryTransaction.status in pendingStatusHash)
|
.filter(({ primaryTransaction }) => !(primaryTransaction.status in pendingStatusHash))
|
||||||
})
|
.reverse()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user