Add public server unit tests for ethereum type coins
This commit is contained in:
parent
e3bb706ea2
commit
89b1e75641
60
server/public_ethereumtype_test.go
Normal file
60
server/public_ethereumtype_test.go
Normal file
@ -0,0 +1,60 @@
|
||||
//go:build unittest
|
||||
// +build unittest
|
||||
|
||||
package server
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/trezor/blockbook/bchain/coins/eth"
|
||||
"github.com/trezor/blockbook/tests/dbtestdata"
|
||||
)
|
||||
|
||||
func httpTestsEthereumType(t *testing.T, ts *httptest.Server) {
|
||||
tests := []httpTests{
|
||||
{
|
||||
name: "apiIndex",
|
||||
r: newGetRequest(ts.URL + "/api"),
|
||||
status: http.StatusOK,
|
||||
contentType: "application/json; charset=utf-8",
|
||||
body: []string{
|
||||
`{"blockbook":{"coin":"Fakecoin"`,
|
||||
`"bestHeight":4321001`,
|
||||
`"decimals":18`,
|
||||
`"backend":{"chain":"fakecoin","blocks":2,"headers":2,"bestBlockHash":"0x2b57e15e93a0ed197417a34c2498b7187df79099572c04a6b6e6ff418f74e6ee"`,
|
||||
`"version":"001001","subversion":"/Fakecoin:0.0.1/"`,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "apiAddress EthAddr4b",
|
||||
r: newGetRequest(ts.URL + "/api/v2/address/" + dbtestdata.EthAddr4b),
|
||||
status: http.StatusOK,
|
||||
contentType: "application/json; charset=utf-8",
|
||||
body: []string{
|
||||
`{"page":1,"totalPages":1,"itemsOnPage":1000,"address":"0x4Bda106325C335dF99eab7fE363cAC8A0ba2a24D","balance":"123450075","unconfirmedBalance":"0","unconfirmedTxs":0,"txs":1,"nonTokenTxs":1,"txids":["0xc92919ad24ffd58f760b18df7949f06e1190cf54a50a0e3745a385608ed3cbf2"],"nonce":"75","tokens":[{"type":"ERC20","name":"Contract 13","contract":"0x0d0F936Ee4c93e25944694D6C121de94D9760F11","transfers":2,"symbol":"S13","decimals":18},{"type":"ERC20","name":"Contract 74","contract":"0x4af4114F73d1c1C903aC9E0361b379D1291808A2","transfers":2,"symbol":"S74","decimals":18}],"erc20Contract":{"contract":"0x4Bda106325C335dF99eab7fE363cAC8A0ba2a24D","name":"Contract 75","symbol":"S75","decimals":18}}`,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
performHttpTests(tests, t, ts)
|
||||
}
|
||||
|
||||
func Test_PublicServer_EthereumType(t *testing.T) {
|
||||
parser := eth.NewEthereumParser(1)
|
||||
chain, err := dbtestdata.NewFakeBlockChainEthereumType(parser)
|
||||
if err != nil {
|
||||
glog.Fatal("fakechain: ", err)
|
||||
}
|
||||
|
||||
s, dbpath := setupPublicHTTPServer(parser, chain, t)
|
||||
defer closeAndDestroyPublicServer(t, s, dbpath)
|
||||
s.ConnectFullPublicInterface()
|
||||
// take the handler of the public server and pass it to the test server
|
||||
ts := httptest.NewServer(s.https.Handler)
|
||||
defer ts.Close()
|
||||
|
||||
httpTestsEthereumType(t, ts)
|
||||
}
|
||||
@ -36,7 +36,7 @@ func TestMain(m *testing.M) {
|
||||
os.Exit(c)
|
||||
}
|
||||
|
||||
func setupRocksDB(t *testing.T, parser bchain.BlockChainParser) (*db.RocksDB, *common.InternalState, string) {
|
||||
func setupRocksDB(parser bchain.BlockChainParser, chain bchain.BlockChain, t *testing.T) (*db.RocksDB, *common.InternalState, string) {
|
||||
tmp, err := ioutil.TempDir("", "testdb")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -50,7 +50,15 @@ func setupRocksDB(t *testing.T, parser bchain.BlockChainParser) (*db.RocksDB, *c
|
||||
t.Fatal(err)
|
||||
}
|
||||
d.SetInternalState(is)
|
||||
block1 := dbtestdata.GetTestBitcoinTypeBlock1(parser)
|
||||
// there are 2 simulated block, of height bestBlockHeight-1 and bestBlockHeight
|
||||
bestHeight, err := chain.GetBestBlockHeight()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
block1, err := chain.GetBlock("", bestHeight-1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// setup internal state BlockTimes
|
||||
for i := uint32(0); i < block1.Height; i++ {
|
||||
is.BlockTimes = append(is.BlockTimes, 0)
|
||||
@ -59,7 +67,10 @@ func setupRocksDB(t *testing.T, parser bchain.BlockChainParser) (*db.RocksDB, *c
|
||||
if err := d.ConnectBlock(block1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
block2 := dbtestdata.GetTestBitcoinTypeBlock2(parser)
|
||||
block2, err := chain.GetBlock("", bestHeight)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := d.ConnectBlock(block2); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -70,31 +81,22 @@ func setupRocksDB(t *testing.T, parser bchain.BlockChainParser) (*db.RocksDB, *c
|
||||
return d, is, tmp
|
||||
}
|
||||
|
||||
func setupPublicHTTPServer(t *testing.T) (*PublicServer, string) {
|
||||
parser := btc.NewBitcoinParser(
|
||||
btc.GetChainParams("test"),
|
||||
&btc.Configuration{
|
||||
BlockAddressesToKeep: 1,
|
||||
XPubMagic: 70617039,
|
||||
XPubMagicSegwitP2sh: 71979618,
|
||||
XPubMagicSegwitNative: 73342198,
|
||||
Slip44: 1,
|
||||
})
|
||||
var metrics *common.Metrics
|
||||
|
||||
d, is, path := setupRocksDB(t, parser)
|
||||
func setupPublicHTTPServer(parser bchain.BlockChainParser, chain bchain.BlockChain, t *testing.T) (*PublicServer, string) {
|
||||
d, is, path := setupRocksDB(parser, chain, t)
|
||||
// setup internal state and match BestHeight to test data
|
||||
is.Coin = "Fakecoin"
|
||||
is.CoinLabel = "Fake Coin"
|
||||
is.CoinShortcut = "FAKE"
|
||||
|
||||
metrics, err := common.GetMetrics("Fakecoin")
|
||||
if err != nil {
|
||||
glog.Fatal("metrics: ", err)
|
||||
}
|
||||
|
||||
chain, err := dbtestdata.NewFakeBlockChain(parser)
|
||||
if err != nil {
|
||||
glog.Fatal("fakechain: ", err)
|
||||
var err error
|
||||
// metrics can be setup only once
|
||||
if metrics == nil {
|
||||
metrics, err = common.GetMetrics("Fakecoin")
|
||||
if err != nil {
|
||||
glog.Fatal("metrics: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
mempool, err := chain.CreateMempool(chain)
|
||||
@ -204,14 +206,45 @@ func InitTestFiatRates(d *db.RocksDB) error {
|
||||
}, d)
|
||||
}
|
||||
|
||||
type httpTests struct {
|
||||
name string
|
||||
r *http.Request
|
||||
status int
|
||||
contentType string
|
||||
body []string
|
||||
}
|
||||
|
||||
func performHttpTests(tests []httpTests, t *testing.T, ts *httptest.Server) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
resp, err := http.DefaultClient.Do(tt.r)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != tt.status {
|
||||
t.Errorf("StatusCode = %v, want %v", resp.StatusCode, tt.status)
|
||||
}
|
||||
if resp.Header["Content-Type"][0] != tt.contentType {
|
||||
t.Errorf("Content-Type = %v, want %v", resp.Header["Content-Type"][0], tt.contentType)
|
||||
}
|
||||
bb, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b := string(bb)
|
||||
for _, c := range tt.body {
|
||||
if !strings.Contains(b, c) {
|
||||
t.Errorf("got %v, want to contain %v", b, c)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func httpTestsBitcoinType(t *testing.T, ts *httptest.Server) {
|
||||
tests := []struct {
|
||||
name string
|
||||
r *http.Request
|
||||
status int
|
||||
contentType string
|
||||
body []string
|
||||
}{
|
||||
tests := []httpTests{
|
||||
{
|
||||
name: "explorerTx",
|
||||
r: newGetRequest(ts.URL + "/tx/fdd824a780cbb718eeb766eb05d83fdefc793a27082cd5e67f856d69798cf7db"),
|
||||
@ -947,33 +980,7 @@ func httpTestsBitcoinType(t *testing.T, ts *httptest.Server) {
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
resp, err := http.DefaultClient.Do(tt.r)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != tt.status {
|
||||
t.Errorf("StatusCode = %v, want %v", resp.StatusCode, tt.status)
|
||||
}
|
||||
if resp.Header["Content-Type"][0] != tt.contentType {
|
||||
t.Errorf("Content-Type = %v, want %v", resp.Header["Content-Type"][0], tt.contentType)
|
||||
}
|
||||
bb, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b := string(bb)
|
||||
for _, c := range tt.body {
|
||||
if !strings.Contains(b, c) {
|
||||
t.Errorf("got %v, want to contain %v", b, c)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
performHttpTests(tests, t, ts)
|
||||
}
|
||||
|
||||
func socketioTestsBitcoinType(t *testing.T, ts *httptest.Server) {
|
||||
@ -1558,7 +1565,22 @@ func websocketTestsBitcoinType(t *testing.T, ts *httptest.Server) {
|
||||
}
|
||||
|
||||
func Test_PublicServer_BitcoinType(t *testing.T) {
|
||||
s, dbpath := setupPublicHTTPServer(t)
|
||||
parser := btc.NewBitcoinParser(
|
||||
btc.GetChainParams("test"),
|
||||
&btc.Configuration{
|
||||
BlockAddressesToKeep: 1,
|
||||
XPubMagic: 70617039,
|
||||
XPubMagicSegwitP2sh: 71979618,
|
||||
XPubMagicSegwitNative: 73342198,
|
||||
Slip44: 1,
|
||||
})
|
||||
|
||||
chain, err := dbtestdata.NewFakeBlockChain(parser)
|
||||
if err != nil {
|
||||
glog.Fatal("fakechain: ", err)
|
||||
}
|
||||
|
||||
s, dbpath := setupPublicHTTPServer(parser, chain, t)
|
||||
defer closeAndDestroyPublicServer(t, s, dbpath)
|
||||
s.ConnectFullPublicInterface()
|
||||
// take the handler of the public server and pass it to the test server
|
||||
|
||||
128
tests/dbtestdata/fakechain_ethereumtype.go
Normal file
128
tests/dbtestdata/fakechain_ethereumtype.go
Normal file
@ -0,0 +1,128 @@
|
||||
package dbtestdata
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
"strconv"
|
||||
|
||||
"github.com/trezor/blockbook/bchain"
|
||||
)
|
||||
|
||||
type fakeBlockChainEthereumType struct {
|
||||
*fakeBlockChain
|
||||
}
|
||||
|
||||
// NewFakeBlockChainEthereumType returns mocked blockchain RPC interface used for tests
|
||||
func NewFakeBlockChainEthereumType(parser bchain.BlockChainParser) (bchain.BlockChain, error) {
|
||||
return &fakeBlockChainEthereumType{&fakeBlockChain{&bchain.BaseChain{Parser: parser}}}, nil
|
||||
}
|
||||
|
||||
func (c *fakeBlockChainEthereumType) CreateMempool(chain bchain.BlockChain) (bchain.Mempool, error) {
|
||||
return bchain.NewMempoolEthereumType(chain, 1, false), nil
|
||||
}
|
||||
|
||||
func (c *fakeBlockChainEthereumType) GetChainInfo() (v *bchain.ChainInfo, err error) {
|
||||
return &bchain.ChainInfo{
|
||||
Chain: c.GetNetworkName(),
|
||||
Blocks: 2,
|
||||
Headers: 2,
|
||||
Bestblockhash: GetTestEthereumTypeBlock2(c.Parser).BlockHeader.Hash,
|
||||
Version: "001001",
|
||||
Subversion: c.GetSubversion(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *fakeBlockChainEthereumType) GetBestBlockHash() (v string, err error) {
|
||||
return GetTestEthereumTypeBlock2(c.Parser).BlockHeader.Hash, nil
|
||||
}
|
||||
|
||||
func (c *fakeBlockChainEthereumType) GetBestBlockHeight() (v uint32, err error) {
|
||||
return GetTestEthereumTypeBlock2(c.Parser).BlockHeader.Height, nil
|
||||
}
|
||||
|
||||
func (c *fakeBlockChainEthereumType) GetBlockHash(height uint32) (v string, err error) {
|
||||
b1 := GetTestEthereumTypeBlock1(c.Parser)
|
||||
if height == b1.BlockHeader.Height {
|
||||
return b1.BlockHeader.Hash, nil
|
||||
}
|
||||
b2 := GetTestEthereumTypeBlock2(c.Parser)
|
||||
if height == b2.BlockHeader.Height {
|
||||
return b2.BlockHeader.Hash, nil
|
||||
}
|
||||
return "", bchain.ErrBlockNotFound
|
||||
}
|
||||
|
||||
func (c *fakeBlockChainEthereumType) GetBlockHeader(hash string) (v *bchain.BlockHeader, err error) {
|
||||
b1 := GetTestEthereumTypeBlock1(c.Parser)
|
||||
if hash == b1.BlockHeader.Hash {
|
||||
return &b1.BlockHeader, nil
|
||||
}
|
||||
b2 := GetTestEthereumTypeBlock2(c.Parser)
|
||||
if hash == b2.BlockHeader.Hash {
|
||||
return &b2.BlockHeader, nil
|
||||
}
|
||||
return nil, bchain.ErrBlockNotFound
|
||||
}
|
||||
|
||||
func (c *fakeBlockChainEthereumType) GetBlock(hash string, height uint32) (v *bchain.Block, err error) {
|
||||
b1 := GetTestEthereumTypeBlock1(c.Parser)
|
||||
if hash == b1.BlockHeader.Hash || height == b1.BlockHeader.Height {
|
||||
return b1, nil
|
||||
}
|
||||
b2 := GetTestEthereumTypeBlock2(c.Parser)
|
||||
if hash == b2.BlockHeader.Hash || height == b2.BlockHeader.Height {
|
||||
return b2, nil
|
||||
}
|
||||
return nil, bchain.ErrBlockNotFound
|
||||
}
|
||||
|
||||
func (c *fakeBlockChainEthereumType) GetBlockInfo(hash string) (v *bchain.BlockInfo, err error) {
|
||||
b1 := GetTestEthereumTypeBlock1(c.Parser)
|
||||
if hash == b1.BlockHeader.Hash {
|
||||
return getBlockInfo(b1), nil
|
||||
}
|
||||
b2 := GetTestEthereumTypeBlock2(c.Parser)
|
||||
if hash == b2.BlockHeader.Hash {
|
||||
return getBlockInfo(b2), nil
|
||||
}
|
||||
return nil, bchain.ErrBlockNotFound
|
||||
}
|
||||
|
||||
func (c *fakeBlockChainEthereumType) GetTransaction(txid string) (v *bchain.Tx, err error) {
|
||||
v = getTxInBlock(GetTestEthereumTypeBlock1(c.Parser), txid)
|
||||
if v == nil {
|
||||
v = getTxInBlock(GetTestEthereumTypeBlock2(c.Parser), txid)
|
||||
}
|
||||
if v != nil {
|
||||
return v, nil
|
||||
}
|
||||
return nil, bchain.ErrTxNotFound
|
||||
}
|
||||
|
||||
func (c *fakeBlockChainEthereumType) GetTransactionSpecific(tx *bchain.Tx) (v json.RawMessage, err error) {
|
||||
txS, _ := tx.CoinSpecificData.(bchain.EthereumSpecificData)
|
||||
|
||||
rm, err := json.Marshal(txS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.RawMessage(rm), nil
|
||||
}
|
||||
|
||||
func (c *fakeBlockChainEthereumType) EthereumTypeGetBalance(addrDesc bchain.AddressDescriptor) (*big.Int, error) {
|
||||
return big.NewInt(123450000 + int64(addrDesc[0])), nil
|
||||
}
|
||||
|
||||
func (c *fakeBlockChainEthereumType) EthereumTypeGetNonce(addrDesc bchain.AddressDescriptor) (uint64, error) {
|
||||
return uint64(addrDesc[0]), nil
|
||||
}
|
||||
|
||||
func (c *fakeBlockChainEthereumType) EthereumTypeGetErc20ContractInfo(contractDesc bchain.AddressDescriptor) (*bchain.Erc20Contract, error) {
|
||||
addresses, _, _ := c.Parser.GetAddressesFromAddrDesc(contractDesc)
|
||||
return &bchain.Erc20Contract{
|
||||
Contract: addresses[0],
|
||||
Name: "Contract " + strconv.Itoa(int(contractDesc[0])),
|
||||
Symbol: "S" + strconv.Itoa(int(contractDesc[0])),
|
||||
Decimals: 18,
|
||||
}, nil
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user