mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Add tests for TransactionActivityLog. Make changes to rendering events
This commit is contained in:
parent
8143f7725a
commit
084158f1a2
@ -860,6 +860,9 @@
|
||||
"save": {
|
||||
"message": "Save"
|
||||
},
|
||||
"speedUp": {
|
||||
"message": "speed up"
|
||||
},
|
||||
"speedUpTitle": {
|
||||
"message": "Speed Up Transaction"
|
||||
},
|
||||
@ -1088,6 +1091,24 @@
|
||||
"total": {
|
||||
"message": "Total"
|
||||
},
|
||||
"transaction": {
|
||||
"message": "transaction"
|
||||
},
|
||||
"transactionConfirmed": {
|
||||
"message": "Transaction confirmed."
|
||||
},
|
||||
"transactionCreated": {
|
||||
"message": "Transaction created with a value of $1."
|
||||
},
|
||||
"transactionDropped": {
|
||||
"message": "Transaction dropped."
|
||||
},
|
||||
"transactionSubmitted": {
|
||||
"message": "Transaction submitted."
|
||||
},
|
||||
"transactionUpdatedGas": {
|
||||
"message": "Transaction updated with a gas price of $1."
|
||||
},
|
||||
"transactions": {
|
||||
"message": "transactions"
|
||||
},
|
||||
@ -1134,6 +1155,9 @@
|
||||
"unavailable": {
|
||||
"message": "Unavailable"
|
||||
},
|
||||
"units": {
|
||||
"message": "units"
|
||||
},
|
||||
"unknown": {
|
||||
"message": "Unknown"
|
||||
},
|
||||
|
@ -1 +1 @@
|
||||
export { default } from './transaction-activity-log.component'
|
||||
export { default } from './transaction-activity-log.container'
|
||||
|
@ -1,6 +1,7 @@
|
||||
.transaction-activity-log {
|
||||
&__card {
|
||||
background: $white;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&__activities-container {
|
||||
@ -47,6 +48,11 @@
|
||||
font-size: .75rem;
|
||||
}
|
||||
|
||||
&__value {
|
||||
display: inline;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
b {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
import React from 'react'
|
||||
import assert from 'assert'
|
||||
import { shallow } from 'enzyme'
|
||||
import TransactionActivityLog from '../transaction-activity-log.component'
|
||||
import Card from '../../card'
|
||||
|
||||
describe('TransactionActivityLog Component', () => {
|
||||
it('should render properly', () => {
|
||||
const transaction = {
|
||||
history: [],
|
||||
id: 1,
|
||||
status: 'confirmed',
|
||||
txParams: {
|
||||
from: '0x1',
|
||||
gas: '0x5208',
|
||||
gasPrice: '0x3b9aca00',
|
||||
nonce: '0xa4',
|
||||
to: '0x2',
|
||||
value: '0x2386f26fc10000',
|
||||
},
|
||||
}
|
||||
|
||||
const wrapper = shallow(
|
||||
<TransactionActivityLog
|
||||
transaction={transaction}
|
||||
className="test-class"
|
||||
/>,
|
||||
{ context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }
|
||||
)
|
||||
|
||||
assert.ok(wrapper.hasClass('transaction-activity-log'))
|
||||
assert.ok(wrapper.hasClass('test-class'))
|
||||
assert.equal(wrapper.find(Card).length, 1)
|
||||
})
|
||||
})
|
@ -0,0 +1,27 @@
|
||||
import assert from 'assert'
|
||||
import proxyquire from 'proxyquire'
|
||||
|
||||
let mapStateToProps
|
||||
|
||||
proxyquire('../transaction-activity-log.container.js', {
|
||||
'react-redux': {
|
||||
connect: ms => {
|
||||
mapStateToProps = ms
|
||||
return () => ({})
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
describe('TransactionActivityLog container', () => {
|
||||
describe('mapStateToProps()', () => {
|
||||
it('should return the correct props', () => {
|
||||
const mockState = {
|
||||
metamask: {
|
||||
conversionRate: 280.45,
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(mapStateToProps(mockState), { conversionRate: 280.45 })
|
||||
})
|
||||
})
|
||||
})
|
@ -0,0 +1,208 @@
|
||||
import assert from 'assert'
|
||||
import { getActivities } from '../transaction-activity-log.util'
|
||||
|
||||
describe('getActivities', () => {
|
||||
it('should return no activities for an empty history', () => {
|
||||
const transaction = {
|
||||
history: [],
|
||||
id: 1,
|
||||
status: 'confirmed',
|
||||
txParams: {
|
||||
from: '0x1',
|
||||
gas: '0x5208',
|
||||
gasPrice: '0x3b9aca00',
|
||||
nonce: '0xa4',
|
||||
to: '0x2',
|
||||
value: '0x2386f26fc10000',
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(getActivities(transaction), [])
|
||||
})
|
||||
|
||||
it('should return activities for a transaction\'s history', () => {
|
||||
const transaction = {
|
||||
history: [
|
||||
{
|
||||
id: 5559712943815343,
|
||||
loadingDefaults: true,
|
||||
metamaskNetworkId: '3',
|
||||
status: 'unapproved',
|
||||
time: 1535507561452,
|
||||
txParams: {
|
||||
from: '0x1',
|
||||
gas: '0x5208',
|
||||
gasPrice: '0x3b9aca00',
|
||||
nonce: '0xa4',
|
||||
to: '0x2',
|
||||
value: '0x2386f26fc10000',
|
||||
},
|
||||
},
|
||||
[
|
||||
{
|
||||
op: 'replace',
|
||||
path: '/loadingDefaults',
|
||||
timestamp: 1535507561515,
|
||||
value: false,
|
||||
},
|
||||
{
|
||||
op: 'add',
|
||||
path: '/gasPriceSpecified',
|
||||
value: true,
|
||||
},
|
||||
{
|
||||
op: 'add',
|
||||
path: '/gasLimitSpecified',
|
||||
value: true,
|
||||
},
|
||||
{
|
||||
op: 'add',
|
||||
path: '/estimatedGas',
|
||||
value: '0x5208',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
note: '#newUnapprovedTransaction - adding the origin',
|
||||
op: 'add',
|
||||
path: '/origin',
|
||||
timestamp: 1535507561516,
|
||||
value: 'MetaMask',
|
||||
},
|
||||
[],
|
||||
],
|
||||
[
|
||||
{
|
||||
note: 'confTx: user approved transaction',
|
||||
op: 'replace',
|
||||
path: '/txParams/gasPrice',
|
||||
timestamp: 1535664571504,
|
||||
value: '0x77359400',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
note: 'txStateManager: setting status to approved',
|
||||
op: 'replace',
|
||||
path: '/status',
|
||||
timestamp: 1535507564302,
|
||||
value: 'approved',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
note: 'transactions#approveTransaction',
|
||||
op: 'add',
|
||||
path: '/txParams/nonce',
|
||||
timestamp: 1535507564439,
|
||||
value: '0xa4',
|
||||
},
|
||||
{
|
||||
op: 'add',
|
||||
path: '/nonceDetails',
|
||||
value: {
|
||||
local: {},
|
||||
network: {},
|
||||
params: {},
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
note: 'transactions#publishTransaction',
|
||||
op: 'replace',
|
||||
path: '/status',
|
||||
timestamp: 1535507564518,
|
||||
value: 'signed',
|
||||
},
|
||||
{
|
||||
op: 'add',
|
||||
path: '/rawTx',
|
||||
value: '0xf86b81a4843b9aca008252089450a9d56c2b8ba9a5c7f2c08c3d26e0499f23a706872386f26fc10000802aa007b30119fc4fc5954fad727895b7e3ba80a78d197e95703cc603bcf017879151a01c50beda40ffaee541da9c05b9616247074f25f392800e0ad6c7a835d5366edf',
|
||||
},
|
||||
],
|
||||
[],
|
||||
[
|
||||
{
|
||||
note: 'transactions#setTxHash',
|
||||
op: 'add',
|
||||
path: '/hash',
|
||||
timestamp: 1535507564658,
|
||||
value: '0x7acc4987b5c0dfa8d423798a8c561138259de1f98a62e3d52e7e83c0e0dd9fb7',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
note: 'txStateManager - add submitted time stamp',
|
||||
op: 'add',
|
||||
path: '/submittedTime',
|
||||
timestamp: 1535507564660,
|
||||
value: 1535507564660,
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
note: 'txStateManager: setting status to submitted',
|
||||
op: 'replace',
|
||||
path: '/status',
|
||||
timestamp: 1535507564665,
|
||||
value: 'submitted',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
note: 'transactions/pending-tx-tracker#event: tx:block-update',
|
||||
op: 'add',
|
||||
path: '/firstRetryBlockNumber',
|
||||
timestamp: 1535507575476,
|
||||
value: '0x3bf624',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
note: 'txStateManager: setting status to confirmed',
|
||||
op: 'replace',
|
||||
path: '/status',
|
||||
timestamp: 1535507615993,
|
||||
value: 'confirmed',
|
||||
},
|
||||
],
|
||||
],
|
||||
id: 1,
|
||||
status: 'confirmed',
|
||||
txParams: {
|
||||
from: '0x1',
|
||||
gas: '0x5208',
|
||||
gasPrice: '0x3b9aca00',
|
||||
nonce: '0xa4',
|
||||
to: '0x2',
|
||||
value: '0x2386f26fc10000',
|
||||
},
|
||||
}
|
||||
|
||||
const expectedResult = [
|
||||
{
|
||||
'eventKey': 'transactionCreated',
|
||||
'timestamp': 1535507561452,
|
||||
'value': '0x2386f26fc10000',
|
||||
},
|
||||
{
|
||||
'eventKey': 'transactionUpdatedGas',
|
||||
'timestamp': 1535664571504,
|
||||
'value': '0x77359400',
|
||||
},
|
||||
{
|
||||
'eventKey': 'transactionSubmitted',
|
||||
'timestamp': 1535507564665,
|
||||
'value': undefined,
|
||||
},
|
||||
{
|
||||
'eventKey': 'transactionConfirmed',
|
||||
'timestamp': 1535507615993,
|
||||
'value': undefined,
|
||||
},
|
||||
]
|
||||
|
||||
assert.deepEqual(getActivities(transaction), expectedResult)
|
||||
})
|
||||
})
|
@ -1,7 +1,10 @@
|
||||
import React, { PureComponent } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import classnames from 'classnames'
|
||||
import { getActivities } from './transaction-activity-log.util'
|
||||
import Card from '../card'
|
||||
import { getEthConversionFromWeiHex } from '../../helpers/conversions.util'
|
||||
import { ETH } from '../../constants/common'
|
||||
|
||||
export default class TransactionActivityLog extends PureComponent {
|
||||
static contextTypes = {
|
||||
@ -10,6 +13,8 @@ export default class TransactionActivityLog extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
transaction: PropTypes.object,
|
||||
className: PropTypes.string,
|
||||
conversionRate: PropTypes.number,
|
||||
}
|
||||
|
||||
state = {
|
||||
@ -35,54 +40,36 @@ export default class TransactionActivityLog extends PureComponent {
|
||||
}
|
||||
|
||||
renderActivity (activity, index) {
|
||||
const { conversionRate } = this.props
|
||||
const { eventKey, value } = activity
|
||||
const ethValue = getEthConversionFromWeiHex({ value, toCurrency: ETH, conversionRate })
|
||||
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className="transaction-activity-log__activity"
|
||||
>
|
||||
<div className="transaction-activity-log__activity-icon" />
|
||||
{ this.renderActivityText(activity) }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderActivityText (activity) {
|
||||
const { eventKey, value, valueDescriptionKey } = activity
|
||||
|
||||
return (
|
||||
<div className="transaction-activity-log__activity-text">
|
||||
{ `Transaction ` }
|
||||
<b>{ `${eventKey}` }</b>
|
||||
{
|
||||
valueDescriptionKey && value
|
||||
? (
|
||||
<span>
|
||||
{ ` with a ${valueDescriptionKey} of ` }
|
||||
<b>{ value }</b>
|
||||
.
|
||||
</span>
|
||||
) : '.'
|
||||
}
|
||||
<div className="transaction-activity-log__activity-text">
|
||||
{ this.context.t(eventKey, [ethValue]) }
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
render () {
|
||||
const { t } = this.context
|
||||
const { className } = this.props
|
||||
const { activities } = this.state
|
||||
|
||||
return (
|
||||
<div className="transaction-activity-log">
|
||||
<div className={classnames('transaction-activity-log', className)}>
|
||||
<Card
|
||||
title={t('activityLog')}
|
||||
className="transaction-activity-log__card"
|
||||
>
|
||||
<div className="transaction-activity-log__activities-container">
|
||||
{
|
||||
activities.map((activity, index) => (
|
||||
this.renderActivity(activity, index)
|
||||
))
|
||||
}
|
||||
{ activities.map((activity, index) => this.renderActivity(activity, index)) }
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
@ -0,0 +1,11 @@
|
||||
import { connect } from 'react-redux'
|
||||
import TransactionActivityLog from './transaction-activity-log.component'
|
||||
import { conversionRateSelector } from '../../selectors'
|
||||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
conversionRate: conversionRateSelector(state),
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(TransactionActivityLog)
|
@ -3,31 +3,37 @@ const STATUS_PATH = '/status'
|
||||
const GAS_PRICE_PATH = '/txParams/gasPrice'
|
||||
|
||||
// status constants
|
||||
const STATUS_UNAPPROVED = 'unapproved'
|
||||
const STATUS_SUBMITTED = 'submitted'
|
||||
const STATUS_CONFIRMED = 'confirmed'
|
||||
const STATUS_DROPPED = 'dropped'
|
||||
const UNAPPROVED_STATUS = 'unapproved'
|
||||
const SUBMITTED_STATUS = 'submitted'
|
||||
const CONFIRMED_STATUS = 'confirmed'
|
||||
const DROPPED_STATUS = 'dropped'
|
||||
|
||||
// op constants
|
||||
const REPLACE_OP = 'replace'
|
||||
|
||||
// event constants
|
||||
const TRANSACTION_CREATED_EVENT = 'transactionCreated'
|
||||
const TRANSACTION_UPDATED_GAS_EVENT = 'transactionUpdatedGas'
|
||||
const TRANSACTION_SUBMITTED_EVENT = 'transactionSubmitted'
|
||||
const TRANSACTION_CONFIRMED_EVENT = 'transactionConfirmed'
|
||||
const TRANSACTION_DROPPED_EVENT = 'transactionDropped'
|
||||
|
||||
const eventPathsHash = {
|
||||
[STATUS_PATH]: true,
|
||||
[GAS_PRICE_PATH]: true,
|
||||
}
|
||||
|
||||
const statusHash = {
|
||||
[STATUS_SUBMITTED]: true,
|
||||
[STATUS_CONFIRMED]: true,
|
||||
[STATUS_DROPPED]: true,
|
||||
[SUBMITTED_STATUS]: TRANSACTION_SUBMITTED_EVENT,
|
||||
[CONFIRMED_STATUS]: TRANSACTION_CONFIRMED_EVENT,
|
||||
[DROPPED_STATUS]: TRANSACTION_DROPPED_EVENT,
|
||||
}
|
||||
|
||||
function eventCreator (eventKey, timestamp, value, valueDescriptionKey) {
|
||||
function eventCreator (eventKey, timestamp, value) {
|
||||
return {
|
||||
eventKey,
|
||||
timestamp,
|
||||
value,
|
||||
valueDescriptionKey,
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,9 +42,9 @@ export function getActivities (transaction) {
|
||||
|
||||
return history.reduce((acc, base) => {
|
||||
// First history item should be transaction creation
|
||||
if (!Array.isArray(base) && base.status === STATUS_UNAPPROVED && base.txParams) {
|
||||
if (!Array.isArray(base) && base.status === UNAPPROVED_STATUS && base.txParams) {
|
||||
const { time, txParams: { value } = {} } = base
|
||||
return acc.concat(eventCreator('created', time, value, 'value'))
|
||||
return acc.concat(eventCreator(TRANSACTION_CREATED_EVENT, time, value))
|
||||
} else if (Array.isArray(base)) {
|
||||
const events = []
|
||||
|
||||
@ -49,14 +55,14 @@ export function getActivities (transaction) {
|
||||
switch (path) {
|
||||
case STATUS_PATH: {
|
||||
if (value in statusHash) {
|
||||
events.push(eventCreator(value, timestamp))
|
||||
events.push(eventCreator(statusHash[value], timestamp))
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
case GAS_PRICE_PATH: {
|
||||
events.push(eventCreator('updated', timestamp, value, 'gasPrice'))
|
||||
events.push(eventCreator(TRANSACTION_UPDATED_GAS_EVENT, timestamp, value))
|
||||
break
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ BigNumber.config({
|
||||
// Big Number Constants
|
||||
const BIG_NUMBER_WEI_MULTIPLIER = new BigNumber('1000000000000000000')
|
||||
const BIG_NUMBER_GWEI_MULTIPLIER = new BigNumber('1000000000')
|
||||
const BIG_NUMBER_ETH_MULTIPLIER = new BigNumber('1')
|
||||
|
||||
// Individual Setters
|
||||
const convert = R.invoker(1, 'times')
|
||||
@ -52,10 +53,12 @@ const toBigNumber = {
|
||||
const toNormalizedDenomination = {
|
||||
WEI: bigNumber => bigNumber.div(BIG_NUMBER_WEI_MULTIPLIER),
|
||||
GWEI: bigNumber => bigNumber.div(BIG_NUMBER_GWEI_MULTIPLIER),
|
||||
ETH: bigNumber => bigNumber.div(BIG_NUMBER_ETH_MULTIPLIER),
|
||||
}
|
||||
const toSpecifiedDenomination = {
|
||||
WEI: bigNumber => bigNumber.times(BIG_NUMBER_WEI_MULTIPLIER).round(),
|
||||
GWEI: bigNumber => bigNumber.times(BIG_NUMBER_GWEI_MULTIPLIER).round(9),
|
||||
ETH: bigNumber => bigNumber.times(BIG_NUMBER_ETH_MULTIPLIER).round(9),
|
||||
}
|
||||
const baseChange = {
|
||||
hex: n => n.toString(16),
|
||||
|
Loading…
Reference in New Issue
Block a user