Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
F
fether
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
20
Issues
20
List
Boards
Labels
Service Desk
Milestones
Iterations
Merge Requests
1
Merge Requests
1
Requirements
Requirements
List
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Test Cases
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issue
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
parity
fether
Commits
f9250b71
Commit
f9250b71
authored
Jul 02, 2018
by
Amaury Martiny
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add tests for sendStore
parent
d5949886
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
234 additions
and
26 deletions
+234
-26
packages/fether-react/src/Send/Send.js
packages/fether-react/src/Send/Send.js
+2
-2
packages/fether-react/src/Send/Signer/Signer.js
packages/fether-react/src/Send/Signer/Signer.js
+4
-2
packages/fether-react/src/Send/TxForm/TxForm.js
packages/fether-react/src/Send/TxForm/TxForm.js
+8
-3
packages/fether-react/src/stores/sendStore.js
packages/fether-react/src/stores/sendStore.js
+6
-7
packages/fether-react/src/stores/sendStore.spec.js
packages/fether-react/src/stores/sendStore.spec.js
+202
-8
packages/fether-react/src/utils/testHelpers/storeTests.js
packages/fether-react/src/utils/testHelpers/storeTests.js
+12
-4
No files found.
packages/fether-react/src/Send/Send.js
View file @
f9250b71
...
...
@@ -16,12 +16,12 @@ import TxForm from './TxForm';
class
Send
extends
Component
{
render
()
{
const
{
sendStore
:
{
token
}
sendStore
:
{
token
Address
}
}
=
this
.
props
;
// We only show then Send components if we have already selected a token to
// send.
if
(
!
token
)
{
if
(
!
token
Address
)
{
return
<
Redirect
to
=
'
/
'
/>
;
}
...
...
packages/fether-react/src/Send/Signer/Signer.js
View file @
f9250b71
...
...
@@ -12,7 +12,7 @@ import ReactTooltip from 'react-tooltip';
import
TokenBalance
from
'
../../Tokens/TokensList/TokenBalance
'
;
@
inject
(
'
sendStore
'
)
@
inject
(
'
sendStore
'
,
'
tokensStore
'
)
@
observer
class
Signer
extends
Component
{
state
=
{
...
...
@@ -58,9 +58,11 @@ class Signer extends Component {
render
()
{
const
{
sendStore
:
{
token
,
tx
}
sendStore
:
{
tokenAddress
,
tx
},
tokensStore
}
=
this
.
props
;
const
{
error
,
isSending
,
password
}
=
this
.
state
;
const
token
=
tokensStore
.
tokens
[
tokenAddress
];
return
(
<
div
>
...
...
packages/fether-react/src/Send/TxForm/TxForm.js
View file @
f9250b71
...
...
@@ -18,8 +18,11 @@ import withBalance from '../../utils/withBalance';
const
MAX_GAS_PRICE
=
40
;
// In Gwei
const
MIN_GAS_PRICE
=
3
;
// Safelow gas price from GasStation, in Gwei
@
inject
(
'
sendStore
'
)
@
withBalance
(({
sendStore
:
{
token
}
})
=>
token
)
@
inject
(
'
sendStore
'
,
'
tokensStore
'
)
@
withBalance
(
({
sendStore
:
{
tokenAddress
},
tokensStore
})
=>
tokensStore
.
tokens
[
tokenAddress
]
)
@
observer
class
Send
extends
Component
{
state
=
{
...
...
@@ -106,10 +109,12 @@ class Send extends Component {
render
()
{
const
{
sendStore
:
{
token
}
sendStore
:
{
tokenAddress
},
tokensStore
}
=
this
.
props
;
const
{
amount
,
gasPrice
,
maxAmount
,
to
}
=
this
.
state
;
const
token
=
tokensStore
.
tokens
[
tokenAddress
];
const
error
=
this
.
hasError
();
return
(
...
...
packages/fether-react/src/stores/sendStore.js
View file @
f9250b71
...
...
@@ -19,7 +19,7 @@ const debug = Debug('sendStore');
const
DEFAULT_GAS
=
new
BigNumber
(
21000
);
// Default gas amount to show
const
GAS_MULT_FACTOR
=
1.33
;
// Since estimateGas is not always accurate, we add a 33% factor for buffer.
class
SendStore
{
export
class
SendStore
{
@
observable
blockNumber
;
// Current block number, used to calculate tx confirmations.
@
observable
estimated
=
DEFAULT_GAS
;
// Estimated gas amount for this transaction.
@
observable
tokenAddress
;
// 'ETH', or the token contract address
...
...
@@ -70,6 +70,10 @@ class SendStore {
* Estimate the amount of gas for our transaction.
*/
estimateGas
=
()
=>
{
if
(
!
this
.
tx
||
!
Object
.
keys
(
this
.
tx
).
length
)
{
return
;
}
if
(
this
.
tokenAddress
===
'
ETH
'
)
{
return
this
.
estimateGasForEth
(
this
.
txForEth
);
}
else
{
...
...
@@ -130,11 +134,6 @@ class SendStore {
});
};
@
computed
get
token
()
{
return
tokensStore
.
tokens
[
this
.
tokenAddress
];
}
/**
* This.tx is a user-friendly tx object. We convert it now as it can be
* passed to makeContract$(...).
...
...
@@ -145,7 +144,7 @@ class SendStore {
args
:
[
this
.
tx
.
to
,
new
BigNumber
(
this
.
tx
.
amount
).
mul
(
new
BigNumber
(
10
).
pow
(
t
his
.
token
.
decimals
)
new
BigNumber
(
10
).
pow
(
t
okensStore
.
tokens
[
this
.
tokenAddress
]
.
decimals
)
)
],
options
:
{
...
...
packages/fether-react/src/stores/sendStore.spec.js
View file @
f9250b71
...
...
@@ -5,28 +5,222 @@
/* eslint-env jest */
import
sendStore
from
'
./sendStore
'
;
import
abi
from
'
@parity/shared/lib/contracts/abi/eip20
'
;
import
BigNumber
from
'
bignumber.js
'
;
import
lightJs
from
'
@parity/light.js
'
;
// Mocked
import
parityStore
from
'
./parityStore
'
;
import
{
SendStore
}
from
'
./sendStore
'
;
import
*
as
storeTests
from
'
../utils/testHelpers/storeTests
'
;
storeTests
.
setterTest
(
sendStore
,
'
blockNumber
'
);
storeTests
.
setterTest
(
sendStore
,
'
tokenAddress
'
);
storeTests
.
setterTest
(
sendStore
,
'
tx
'
);
storeTests
.
setterTest
(
sendStore
,
'
txStatus
'
);
jest
.
mock
(
'
@parity/light.js
'
,
()
=>
({
blockNumber
$
:
jest
.
fn
(()
=>
({
subscribe
:
()
=>
jest
.
fn
(()
=>
({
unsubscribe
:
jest
.
fn
()
}))
})),
makeContract
$
:
jest
.
fn
(()
=>
({
contractObject
:
{
instance
:
{
transfer
:
{
estimateGas
:
jest
.
fn
(()
=>
Promise
.
resolve
(
123
))
}
}
},
transfer
$
:
jest
.
fn
(()
=>
({
subscribe
:
jest
.
fn
()
}))
})),
post
$
:
jest
.
fn
(()
=>
({
subscribe
:
jest
.
fn
()
}))
}));
jest
.
mock
(
'
./parityStore
'
,
()
=>
({
api
:
{
eth
:
{
estimateGas
:
jest
.
fn
(()
=>
Promise
.
resolve
(
123
))
},
signer
:
{
confirmRequest
:
jest
.
fn
(()
=>
Promise
.
resolve
(
true
))
}
}
}));
jest
.
mock
(
'
./tokensStore
'
,
()
=>
({
tokens
:
{
ETH
:
{
decimals
:
18
},
foo
:
{
decimals
:
18
}
}
}));
const
mockTx
=
{
amount
:
0.01
,
// In Ether or in token
gasPrice
:
4
,
// in Gwei
to
:
'
0x123
'
};
let
sendStore
;
// Will hold the newly created instance of SendStore in each test
beforeEach
(()
=>
{
sendStore
=
new
SendStore
();
});
describe
(
'
method acceptRequest
'
,
()
=>
{
test
(
'
should call api.signer.confirmRequest
'
,
()
=>
{
sendStore
.
acceptRequest
(
1
,
'
foo
'
);
expect
(
parityStore
.
api
.
signer
.
confirmRequest
).
toHaveBeenCalledWith
(
1
,
null
,
'
foo
'
);
});
test
(
'
should set a subscription on blockNumber$
'
,
()
=>
{
sendStore
.
acceptRequest
(
1
,
'
foo
'
);
expect
(
lightJs
.
blockNumber$
).
toHaveBeenCalled
();
});
});
describe
(
'
method clear
'
,
()
=>
{
test
(
'
should clear tx
'
,
()
=>
{
sendStore
.
setTx
(
mockTx
);
sendStore
.
clear
();
expect
(
sendStore
.
tx
).
toEqual
({});
});
});
describe
(
'
@computed confirmations
'
,
()
=>
{
test
(
'
return correct value if txStatus is not set
'
,
()
=>
{
test
(
'
should
return correct value if txStatus is not set
'
,
()
=>
{
sendStore
.
setTxStatus
(
null
);
expect
(
sendStore
.
confirmations
).
toBe
(
-
1
);
});
test
(
'
return correct value if txStatus is not `confirmed`
'
,
()
=>
{
test
(
'
should
return correct value if txStatus is not `confirmed`
'
,
()
=>
{
sendStore
.
setTxStatus
({
estimating
:
true
});
expect
(
sendStore
.
confirmations
).
toBe
(
-
1
);
});
test
(
'
return correct value if txStatus is `confirmed`
'
,
()
=>
{
test
(
'
should
return correct value if txStatus is `confirmed`
'
,
()
=>
{
sendStore
.
setBlockNumber
(
5
);
sendStore
.
setTxStatus
({
confirmed
:
{
blockNumber
:
4
}
});
expect
(
sendStore
.
confirmations
).
toBe
(
1
);
});
});
describe
(
'
@computed contract
'
,
()
=>
{
test
(
'
should create a contract with correct token address if the current token Erc20
'
,
()
=>
{
sendStore
.
setTokenAddress
(
'
foo
'
);
sendStore
.
contract
;
// eslint-disable-line
expect
(
lightJs
.
makeContract$
).
toHaveBeenCalledWith
(
'
foo
'
,
abi
);
});
test
(
'
should return null if the current token is ETH
'
,
()
=>
{
sendStore
.
setTokenAddress
(
'
ETH
'
);
expect
(
sendStore
.
contract
).
toBe
(
null
);
});
});
describe
(
'
method estimateGas
'
,
()
=>
{
test
(
'
should not estimate if no tx is set
'
,
()
=>
{
sendStore
.
estimateGasForErc20
=
jest
.
fn
();
sendStore
.
estimateGasForEth
=
jest
.
fn
();
expect
(
sendStore
.
estimateGas
()).
toBe
(
undefined
);
expect
(
sendStore
.
estimateGasForErc20
).
not
.
toHaveBeenCalled
();
expect
(
sendStore
.
estimateGasForEth
).
not
.
toHaveBeenCalled
();
});
test
(
'
should call estimateGasForErc20 if the current token is Erc20
'
,
()
=>
{
sendStore
.
estimateGasForErc20
=
jest
.
fn
(()
=>
'
estimateGasForErc20
'
);
sendStore
.
setTokenAddress
(
'
foo
'
);
sendStore
.
setTx
(
mockTx
);
expect
(
sendStore
.
estimateGas
()).
toBe
(
'
estimateGasForErc20
'
);
expect
(
sendStore
.
estimateGasForErc20
).
toHaveBeenCalled
();
});
test
(
'
should call estimateGasForEth if the current token is ETH
'
,
()
=>
{
sendStore
.
estimateGasForEth
=
jest
.
fn
(()
=>
'
estimateGasForEth
'
);
sendStore
.
setTokenAddress
(
'
ETH
'
);
sendStore
.
setTx
(
mockTx
);
expect
(
sendStore
.
estimateGas
()).
toBe
(
'
estimateGasForEth
'
);
expect
(
sendStore
.
estimateGasForEth
).
toHaveBeenCalled
();
});
});
describe
(
'
method estimateGasForErc20
'
,
()
=>
{
beforeEach
(()
=>
{
sendStore
.
setTokenAddress
(
'
foo
'
);
});
test
(
'
should call the transfer method on the contract
'
,
()
=>
{
sendStore
.
estimateGasForErc20
(
mockTx
);
expect
(
sendStore
.
contract
.
contractObject
.
instance
.
transfer
.
estimateGas
).
toHaveBeenCalledWith
(
mockTx
);
});
test
(
'
should memoize result
'
,
()
=>
{
const
a
=
sendStore
.
estimateGasForErc20
(
mockTx
);
const
b
=
sendStore
.
estimateGasForErc20
(
mockTx
);
expect
(
a
).
toBe
(
b
);
});
});
describe
(
'
method estimateGasForEth
'
,
()
=>
{
beforeEach
(()
=>
{
sendStore
.
setTokenAddress
(
'
ETH
'
);
});
test
(
'
should call api.eth.estimateGas
'
,
()
=>
{
sendStore
.
estimateGasForEth
(
mockTx
);
expect
(
parityStore
.
api
.
eth
.
estimateGas
).
toHaveBeenCalledWith
(
mockTx
);
});
test
(
'
should memoize result
'
,
()
=>
{
const
a
=
sendStore
.
estimateGasForEth
(
mockTx
);
const
b
=
sendStore
.
estimateGasForEth
(
mockTx
);
expect
(
a
).
toBe
(
b
);
});
});
describe
(
'
method send
'
,
()
=>
{
beforeEach
(()
=>
{
sendStore
.
setTx
(
mockTx
);
});
test
(
'
should call transfer$ if the token is Erc20 and subscribe to it
'
,
()
=>
{
sendStore
.
setTokenAddress
(
'
foo
'
);
sendStore
.
send
();
expect
(
sendStore
.
contract
.
transfer$
).
toHaveBeenCalledWith
(
sendStore
.
txForErc20
);
});
test
(
'
should call post$ if the token is ETH and subscribe to it
'
,
()
=>
{
sendStore
.
setTokenAddress
(
'
ETH
'
);
sendStore
.
send
();
expect
(
lightJs
.
post$
).
toHaveBeenCalledWith
(
sendStore
.
txForEth
);
});
});
describe
(
'
@computed txForErc20
'
,
()
=>
{
test
(
'
should return correct value
'
,
()
=>
{
sendStore
.
setTokenAddress
(
'
foo
'
);
sendStore
.
setTx
(
mockTx
);
expect
(
sendStore
.
txForErc20
).
toEqual
({
args
:
[
'
0x123
'
,
new
BigNumber
(
'
10000000000000000
'
)],
options
:
{
gasPrice
:
new
BigNumber
(
'
4000000000
'
)
}
});
});
});
describe
(
'
@computed txForEth
'
,
()
=>
{
test
(
'
should return correct value
'
,
()
=>
{
sendStore
.
setTokenAddress
(
'
foo
'
);
sendStore
.
setTx
(
mockTx
);
expect
(
sendStore
.
txForEth
).
toEqual
({
gasPrice
:
new
BigNumber
(
'
4000000000
'
),
to
:
'
0x123
'
,
value
:
new
BigNumber
(
'
10000000000000000
'
)
});
});
});
storeTests
.
setterTest
(
SendStore
,
'
blockNumber
'
);
storeTests
.
setterTest
(
SendStore
,
'
tokenAddress
'
);
storeTests
.
setterTest
(
SendStore
,
'
tx
'
);
storeTests
.
setterTest
(
SendStore
,
'
txStatus
'
);
packages/fether-react/src/utils/testHelpers/storeTests.js
View file @
f9250b71
...
...
@@ -7,8 +7,16 @@
import
capitalize
from
'
capitalize
'
;
export
const
setterTest
=
(
store
,
variableName
)
=>
test
(
`should correctly set
${
variableName
}
`
,
()
=>
{
store
[
`set
${
capitalize
(
variableName
)}
`
](
'
foo
'
);
expect
(
store
[
variableName
]).
toEqual
(
'
foo
'
);
let
store
;
export
const
setterTest
=
(
Store
,
variableName
)
=>
describe
(
`setter
${
variableName
}
`
,
()
=>
{
beforeEach
(()
=>
{
store
=
new
Store
();
});
test
(
`should correctly set
${
variableName
}
`
,
()
=>
{
store
[
`set
${
capitalize
(
variableName
)}
`
](
'
foo
'
);
expect
(
store
[
variableName
]).
toEqual
(
'
foo
'
);
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment