164 lines
4.4 KiB
Go
164 lines
4.4 KiB
Go
// Copyright (c) 2017-2026 Lethean (https://lt.hn)
|
|
//
|
|
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
|
// SPDX-License-Identifier: EUPL-1.2
|
|
|
|
package rpc
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
)
|
|
|
|
func TestClient_Good_JSONRPCCall(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
// Verify request format.
|
|
if r.Method != http.MethodPost {
|
|
t.Errorf("method: got %s, want POST", r.Method)
|
|
}
|
|
if r.URL.Path != "/json_rpc" {
|
|
t.Errorf("path: got %s, want /json_rpc", r.URL.Path)
|
|
}
|
|
body, _ := io.ReadAll(r.Body)
|
|
var req jsonRPCRequest
|
|
json.Unmarshal(body, &req)
|
|
if req.JSONRPC != "2.0" {
|
|
t.Errorf("jsonrpc: got %q, want %q", req.JSONRPC, "2.0")
|
|
}
|
|
if req.Method != "getblockcount" {
|
|
t.Errorf("method: got %q, want %q", req.Method, "getblockcount")
|
|
}
|
|
|
|
// Return a valid response.
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(jsonRPCResponse{
|
|
JSONRPC: "2.0",
|
|
ID: rawJSON(`"0"`),
|
|
Result: rawJSON(`{"count":6300,"status":"OK"}`),
|
|
})
|
|
}))
|
|
defer srv.Close()
|
|
|
|
c := NewClient(srv.URL)
|
|
var result struct {
|
|
Count uint64 `json:"count"`
|
|
Status string `json:"status"`
|
|
}
|
|
err := c.call("getblockcount", struct{}{}, &result)
|
|
if err != nil {
|
|
t.Fatalf("call: %v", err)
|
|
}
|
|
if result.Count != 6300 {
|
|
t.Errorf("count: got %d, want 6300", result.Count)
|
|
}
|
|
if result.Status != "OK" {
|
|
t.Errorf("status: got %q, want %q", result.Status, "OK")
|
|
}
|
|
}
|
|
|
|
func TestClient_Good_LegacyCall(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path != "/getheight" {
|
|
t.Errorf("path: got %s, want /getheight", r.URL.Path)
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Write([]byte(`{"height":6300,"status":"OK"}`))
|
|
}))
|
|
defer srv.Close()
|
|
|
|
c := NewClient(srv.URL)
|
|
var result struct {
|
|
Height uint64 `json:"height"`
|
|
Status string `json:"status"`
|
|
}
|
|
err := c.legacyCall("/getheight", struct{}{}, &result)
|
|
if err != nil {
|
|
t.Fatalf("legacyCall: %v", err)
|
|
}
|
|
if result.Height != 6300 {
|
|
t.Errorf("height: got %d, want 6300", result.Height)
|
|
}
|
|
}
|
|
|
|
func TestClient_Bad_RPCError(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(jsonRPCResponse{
|
|
JSONRPC: "2.0",
|
|
ID: rawJSON(`"0"`),
|
|
Error: &jsonRPCError{
|
|
Code: -2,
|
|
Message: "TOO_BIG_HEIGHT",
|
|
},
|
|
})
|
|
}))
|
|
defer srv.Close()
|
|
|
|
c := NewClient(srv.URL)
|
|
var result struct{}
|
|
err := c.call("getblockheaderbyheight", struct{ Height uint64 }{999999999}, &result)
|
|
if err == nil {
|
|
t.Fatal("expected error")
|
|
}
|
|
rpcErr, ok := err.(*RPCError)
|
|
if !ok {
|
|
t.Fatalf("expected *RPCError, got %T: %v", err, err)
|
|
}
|
|
if rpcErr.Code != -2 {
|
|
t.Errorf("code: got %d, want -2", rpcErr.Code)
|
|
}
|
|
}
|
|
|
|
func TestClient_Bad_ConnectionRefused(t *testing.T) {
|
|
c := NewClient("http://127.0.0.1:1") // Unlikely to be listening
|
|
var result struct{}
|
|
err := c.call("getblockcount", struct{}{}, &result)
|
|
if err == nil {
|
|
t.Fatal("expected connection error")
|
|
}
|
|
}
|
|
|
|
func TestClient_Good_URLAppendPath(t *testing.T) {
|
|
// NewClient should append /json_rpc if path is empty.
|
|
c := NewClient("http://localhost:46941")
|
|
if c.url != "http://localhost:46941/json_rpc" {
|
|
t.Errorf("url: got %q, want %q", c.url, "http://localhost:46941/json_rpc")
|
|
}
|
|
|
|
// If path already present, leave it alone.
|
|
c2 := NewClient("http://localhost:46941/json_rpc")
|
|
if c2.url != "http://localhost:46941/json_rpc" {
|
|
t.Errorf("url: got %q, want %q", c2.url, "http://localhost:46941/json_rpc")
|
|
}
|
|
}
|
|
|
|
func TestClient_Bad_InvalidJSON(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Write([]byte(`not json`))
|
|
}))
|
|
defer srv.Close()
|
|
|
|
c := NewClient(srv.URL)
|
|
var result struct{}
|
|
err := c.call("getblockcount", struct{}{}, &result)
|
|
if err == nil {
|
|
t.Fatal("expected error for invalid JSON")
|
|
}
|
|
}
|
|
|
|
func TestClient_Bad_HTTP500(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
}))
|
|
defer srv.Close()
|
|
|
|
c := NewClient(srv.URL)
|
|
var result struct{}
|
|
err := c.call("getblockcount", struct{}{}, &result)
|
|
if err == nil {
|
|
t.Fatal("expected error for HTTP 500")
|
|
}
|
|
}
|