walletsvrwsntfns_test.go raw
1 package btcjson_test
2
3 import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7 "reflect"
8 "testing"
9
10 "github.com/p9c/p9/pkg/btcjson"
11 )
12
13 // TestWalletSvrWsNtfns tests all of the chain server websocket-specific notifications marshal and unmarshal into valid
14 // results include handling of optional fields being omitted in the marshalled command, while optional fields with
15 // defaults have the default assigned on unmarshalled commands.
16 func TestWalletSvrWsNtfns(t *testing.T) {
17 t.Parallel()
18 tests := []struct {
19 name string
20 newNtfn func() (interface{}, error)
21 staticNtfn func() interface{}
22 marshalled string
23 unmarshalled interface{}
24 }{
25 {
26 name: "accountbalance",
27 newNtfn: func() (interface{}, error) {
28 return btcjson.NewCmd("accountbalance", "acct", 1.25, true)
29 },
30 staticNtfn: func() interface{} {
31 return btcjson.NewAccountBalanceNtfn("acct", 1.25, true)
32 },
33 marshalled: `{"jsonrpc":"1.0","method":"accountbalance","netparams":["acct",1.25,true],"id":null}`,
34 unmarshalled: &btcjson.AccountBalanceNtfn{
35 Account: "acct",
36 Balance: 1.25,
37 Confirmed: true,
38 },
39 },
40 {
41 name: "podconnected",
42 newNtfn: func() (interface{}, error) {
43 return btcjson.NewCmd("podconnected", true)
44 },
45 staticNtfn: func() interface{} {
46 return btcjson.NewPodConnectedNtfn(true)
47 },
48 marshalled: `{"jsonrpc":"1.0","method":"podconnected","netparams":[true],"id":null}`,
49 unmarshalled: &btcjson.PodConnectedNtfn{
50 Connected: true,
51 },
52 },
53 {
54 name: "walletlockstate",
55 newNtfn: func() (interface{}, error) {
56 return btcjson.NewCmd("walletlockstate", true)
57 },
58 staticNtfn: func() interface{} {
59 return btcjson.NewWalletLockStateNtfn(true)
60 },
61 marshalled: `{"jsonrpc":"1.0","method":"walletlockstate","netparams":[true],"id":null}`,
62 unmarshalled: &btcjson.WalletLockStateNtfn{
63 Locked: true,
64 },
65 },
66 {
67 name: "newtx",
68 newNtfn: func() (interface{}, error) {
69 return btcjson.NewCmd("newtx",
70 "acct",
71 `{"account":"acct","address":"1Address","category":"send","amount":1.5,"bip125-replaceable":"unknown","fee":0.0001,"confirmations":1,"trusted":true,"txid":"456","walletconflicts":[],"time":12345678,"timereceived":12345876,"vout":789,"otheraccount":"otheracct"}`,
72 )
73 },
74 staticNtfn: func() interface{} {
75 result := btcjson.ListTransactionsResult{
76 Abandoned: false,
77 Account: "acct",
78 Address: "1Address",
79 Category: "send",
80 Amount: 1.5,
81 Fee: *btcjson.Float64(0.0001),
82 Confirmations: 1,
83 TxID: "456",
84 WalletConflicts: []string{},
85 Time: 12345678,
86 TimeReceived: 12345876,
87 Trusted: true,
88 Vout: 789,
89 OtherAccount: "otheracct",
90 }
91 return btcjson.NewNewTxNtfn("acct", result)
92 },
93 marshalled: `{"jsonrpc":"1.0","method":"newtx","netparams":["acct",{"abandoned":false,"account":"acct","address":"1Address","amount":1.5,"bip125-replaceable":"unknown","category":"send","confirmations":1,"fee":0.0001,"time":12345678,"timereceived":12345876,"trusted":true,"txid":"456","vout":789,"walletconflicts":[],"otheraccount":"otheracct"}],"id":null}`,
94 unmarshalled: &btcjson.NewTxNtfn{
95 Account: "acct",
96 Details: btcjson.ListTransactionsResult{
97 Abandoned: false,
98 Account: "acct",
99 Address: "1Address",
100 Category: "send",
101 Amount: 1.5,
102 Fee: *btcjson.Float64(0.0001),
103 Confirmations: 1,
104 TxID: "456",
105 WalletConflicts: []string{},
106 Time: 12345678,
107 TimeReceived: 12345876,
108 Trusted: true,
109 Vout: 789,
110 OtherAccount: "otheracct",
111 },
112 },
113 },
114 }
115 t.Logf("Running %d tests", len(tests))
116 for i, test := range tests {
117 // Marshal the notification as created by the new static creation function. The ID is nil for notifications.
118 marshalled, e := btcjson.MarshalCmd(nil, test.staticNtfn())
119 if e != nil {
120 t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i,
121 test.name, e,
122 )
123 continue
124 }
125 if !bytes.Equal(marshalled, []byte(test.marshalled)) {
126 t.Errorf("Test #%d (%s) unexpected marshalled data - "+
127 "got %s, want %s", i, test.name, marshalled,
128 test.marshalled,
129 )
130 continue
131 }
132 // Ensure the notification is created without error via the generic new notification creation function.
133 cmd, e := test.newNtfn()
134 if e != nil {
135 t.Errorf("Test #%d (%s) unexpected NewCmd error: %v ",
136 i, test.name, e,
137 )
138 }
139 // Marshal the notification as created by the generic new notification creation function. The ID is nil for
140 // notifications.
141 marshalled, e = btcjson.MarshalCmd(nil, cmd)
142 if e != nil {
143 t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i,
144 test.name, e,
145 )
146 continue
147 }
148 if !bytes.Equal(marshalled, []byte(test.marshalled)) {
149 t.Errorf("Test #%d (%s) unexpected marshalled data - "+
150 "got %s, want %s", i, test.name, marshalled,
151 test.marshalled,
152 )
153 continue
154 }
155 var request btcjson.Request
156 if e = json.Unmarshal(marshalled, &request); E.Chk(e) {
157 t.Errorf("Test #%d (%s) unexpected error while "+
158 "unmarshalling JSON-RPC request: %v", i,
159 test.name, e,
160 )
161 continue
162 }
163 cmd, e = btcjson.UnmarshalCmd(&request)
164 if e != nil {
165 t.Errorf("UnmarshalCmd #%d (%s) unexpected error: %v", i,
166 test.name, e,
167 )
168 continue
169 }
170 if !reflect.DeepEqual(cmd, test.unmarshalled) {
171 t.Errorf("Test #%d (%s) unexpected unmarshalled command "+
172 "- got %s, want %s", i, test.name,
173 fmt.Sprintf("(%T) %+[1]v", cmd),
174 fmt.Sprintf("(%T) %+[1]v\n", test.unmarshalled),
175 )
176 continue
177 }
178 }
179 }
180