blockbook/server/public_test.go

247 lines
7.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// build unittest
package server
import (
"blockbook/bchain"
"blockbook/bchain/coins/btc"
"blockbook/common"
"blockbook/db"
"blockbook/tests/dbtestdata"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"strings"
"testing"
"github.com/golang/glog"
"github.com/jakm/btcutil/chaincfg"
)
func TestMain(m *testing.M) {
// set the current directory to blockbook root so that ./static/ works
if err := os.Chdir(".."); err != nil {
glog.Fatal("Chdir error:", err)
}
c := m.Run()
chaincfg.ResetParams()
os.Exit(c)
}
func setupRocksDB(t *testing.T, parser bchain.BlockChainParser) (*db.RocksDB, *common.InternalState, string) {
tmp, err := ioutil.TempDir("", "testdb")
if err != nil {
t.Fatal(err)
}
d, err := db.NewRocksDB(tmp, 100000, -1, parser, nil)
if err != nil {
t.Fatal(err)
}
is, err := d.LoadInternalState("btc-testnet")
if err != nil {
t.Fatal(err)
}
d.SetInternalState(is)
// import data
if err := d.ConnectBlock(dbtestdata.GetTestUTXOBlock1(parser)); err != nil {
t.Fatal(err)
}
if err := d.ConnectBlock(dbtestdata.GetTestUTXOBlock2(parser)); err != nil {
t.Fatal(err)
}
return d, is, tmp
}
func setupPublicHTTPServer(t *testing.T) (*PublicServer, string) {
parser := btc.NewBitcoinParser(
btc.GetChainParams("test"),
&btc.Configuration{BlockAddressesToKeep: 1})
d, is, path := setupRocksDB(t, parser)
is.Coin = "Testnet"
is.CoinLabel = "Bitcoin Testnet"
is.CoinShortcut = "TEST"
metrics, err := common.GetMetrics("Testnet")
if err != nil {
glog.Fatal("metrics: ", err)
}
chain, err := dbtestdata.NewFakeBlockChain(parser)
if err != nil {
glog.Fatal("fakechain: ", err)
}
txCache, err := db.NewTxCache(d, chain, metrics, is, true)
if err != nil {
glog.Fatal("txCache: ", err)
}
// s.Run is never called, binding can be to any port
s, err := NewPublicServer("localhost:12345", "", d, chain, txCache, "", metrics, is, false)
if err != nil {
t.Fatal(err)
}
return s, path
}
func closeAndDestroyPublicServer(t *testing.T, s *PublicServer, dbpath string) {
// destroy db
if err := s.db.Close(); err != nil {
t.Fatal(err)
}
os.RemoveAll(dbpath)
}
func newGetRequest(url string, body io.Reader) *http.Request {
r, err := http.NewRequest("GET", url, body)
if err != nil {
glog.Fatal(err)
}
return r
}
func Test_PublicServer_UTXO(t *testing.T) {
s, dbpath := setupPublicHTTPServer(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()
tests := []struct {
name string
r *http.Request
status int
contentType string
body []string
}{
{
name: "explorerTx",
r: newGetRequest(ts.URL+"/tx/fdd824a780cbb718eeb766eb05d83fdefc793a27082cd5e67f856d69798cf7db", nil),
status: http.StatusOK,
contentType: "text/html; charset=utf-8",
body: []string{
`<a href="/" class="nav-link">Bitcoin Testnet Explorer</a>`,
`<h1>Transaction</h1>`,
`<span class="data">fdd824a780cbb718eeb766eb05d83fdefc793a27082cd5e67f856d69798cf7db</span>`,
`td class="data">0 TEST</td>`,
`<a href="/address/mzVznVsCHkVHX9UN8WPFASWUUHtxnNn4Jj">mzVznVsCHkVHX9UN8WPFASWUUHtxnNn4Jj</a>`,
`13.60030331 TEST`,
`<td><span class="float-left">No Inputs (Newly Generated Coins)</span></td>`,
`</html>`,
},
},
{
name: "explorerAddress",
r: newGetRequest(ts.URL+"/address/mtGXQvBowMkBpnhLckhxhbwYK44Gs9eEtz", nil),
status: http.StatusOK,
contentType: "text/html; charset=utf-8",
body: []string{
`<a href="/" class="nav-link">Bitcoin Testnet Explorer</a>`,
`<h1>Address`,
`<small class="text-muted">0 TEST</small>`,
`<span class="data">mtGXQvBowMkBpnhLckhxhbwYK44Gs9eEtz</span>`,
`<td class="data">0.00012345 TEST</td>`,
`<a href="/tx/7c3be24063f268aaa1ed81b64776798f56088757641a34fb156c4f51ed2e9d25">7c3be24063f268aaa1ed81b64776798f56088757641a34fb156c4f51ed2e9d25</a>`,
`3172.83951061 TEST <a class="text-danger" href="/spending/7c3be24063f268aaa1ed81b64776798f56088757641a34fb156c4f51ed2e9d25/0" title="Spent">➡</a></span>`,
`<td><span class="ellipsis float-left"><a href="/address/mtR97eM2HPWVM6c8FGLGcukgaHHQv7THoL">mtR97eM2HPWVM6c8FGLGcukgaHHQv7THoL</a></span><span class="float-right">`,
`td><span class="ellipsis float-left"><a href="/address/mtR97eM2HPWVM6c8FGLGcukgaHHQv7THoL">mtR97eM2HPWVM6c8FGLGcukgaHHQv7THoL</a></span><span class="float-right">`,
`9172.83951061 TEST <span class="text-success" title="Unspent"> <b>×</b></span></span>`,
`<a href="/tx/00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840">00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840</a>`,
`</html>`,
},
},
{
name: "explorerSpendingTx",
r: newGetRequest(ts.URL+"/spending/7c3be24063f268aaa1ed81b64776798f56088757641a34fb156c4f51ed2e9d25/0", nil),
status: http.StatusOK,
contentType: "text/html; charset=utf-8",
body: []string{
`<a href="/" class="nav-link">Bitcoin Testnet Explorer</a>`,
`<h1>Transaction</h1>`,
`<span class="data">3d90d15ed026dc45e19ffb52875ed18fa9e8012ad123d7f7212176e2b0ebdb71</span>`,
`<td class="data">0.00000062 TEST</td>`,
`</html>`,
},
},
{
name: "explorerBlocks",
r: newGetRequest(ts.URL+"/blocks", nil),
status: http.StatusOK,
contentType: "text/html; charset=utf-8",
body: []string{
`<a href="/" class="nav-link">Bitcoin Testnet Explorer</a>`,
`<h1>Blocks`,
`<td><a href="/block/225494">225494</a></td>`,
`<td class="ellipsis">00000000eb0443fd7dc4a1ed5c686a8e995057805f9a161d9a5a77a95e72b7b6</td>`,
`<td class="ellipsis">0000000076fbbed90fd75b0e18856aa35baa984e9c9d444cf746ad85e94e2997</td>`,
`<td>Tue, 21 Aug 2018 15:27:01 CEST</td>`,
`<td class="text-right">2</td>`,
`<td class="text-right">1234567</td>`,
`</html>`,
},
},
{
name: "explorerBlock",
r: newGetRequest(ts.URL+"/block/225494", nil),
status: http.StatusOK,
contentType: "text/html; charset=utf-8",
body: []string{
`<a href="/" class="nav-link">Bitcoin Testnet Explorer</a>`,
`<h1>Block 225494</h1>`,
`<span class="data">00000000eb0443fd7dc4a1ed5c686a8e995057805f9a161d9a5a77a95e72b7b6</span>`,
`<td class="data">4</td>`, // number of transactions
`<a href="/address/mtR97eM2HPWVM6c8FGLGcukgaHHQv7THoL">mtR97eM2HPWVM6c8FGLGcukgaHHQv7THoL</a>`,
`9172.83951061 TEST`,
`<a href="/tx/fdd824a780cbb718eeb766eb05d83fdefc793a27082cd5e67f856d69798cf7db">fdd824a780cbb718eeb766eb05d83fdefc793a27082cd5e67f856d69798cf7db</a>`,
`</html>`,
},
},
{
name: "explorerIndex",
r: newGetRequest(ts.URL+"/", nil),
status: http.StatusOK,
contentType: "text/html; charset=utf-8",
body: []string{
`<a href="/" class="nav-link">Bitcoin Testnet Explorer</a>`,
`<h1>Application status</h1>`,
`<h3 class="bg-warning text-white" style="padding: 20px;">Synchronization with backend is disabled, the state of index is not up to date.</h3>`,
`<a href="/block/225494">225494</a>`,
`<td class="data">/Satoshi:0.16.3/</td>`,
`</html>`,
},
},
// explorerSearch
}
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("Page body does not contain %v, body %v", c, b)
break
}
}
})
}
}