1 // Copyright (c) 2014-2017 The btcsuite developers
2 // Copyright (c) 2015-2017 The Decred developers
3 // Use of this source code is governed by an ISC
4 // license that can be found in the LICENSE file.
15 "github.com/btcsuite/btcd/btcjson"
18 // TestChainSvrWsNtfns tests all of the chain server websocket-specific
19 // notifications marshal and unmarshal into valid results include handling of
20 // optional fields being omitted in the marshalled command, while optional
21 // fields with defaults have the default assigned on unmarshalled commands.
22 func TestChainSvrWsNtfns(t *testing.T) {
27 newNtfn func() (interface{}, error)
28 staticNtfn func() interface{}
30 unmarshalled interface{}
33 name: "blockconnected",
34 newNtfn: func() (interface{}, error) {
35 return btcjson.NewCmd("blockconnected", "123", 100000, 123456789)
37 staticNtfn: func() interface{} {
38 return btcjson.NewBlockConnectedNtfn("123", 100000, 123456789)
40 marshalled: `{"jsonrpc":"1.0","method":"blockconnected","params":["123",100000,123456789],"id":null}`,
41 unmarshalled: &btcjson.BlockConnectedNtfn{
48 name: "blockdisconnected",
49 newNtfn: func() (interface{}, error) {
50 return btcjson.NewCmd("blockdisconnected", "123", 100000, 123456789)
52 staticNtfn: func() interface{} {
53 return btcjson.NewBlockDisconnectedNtfn("123", 100000, 123456789)
55 marshalled: `{"jsonrpc":"1.0","method":"blockdisconnected","params":["123",100000,123456789],"id":null}`,
56 unmarshalled: &btcjson.BlockDisconnectedNtfn{
63 name: "filteredblockconnected",
64 newNtfn: func() (interface{}, error) {
65 return btcjson.NewCmd("filteredblockconnected", 100000, "header", []string{"tx0", "tx1"})
67 staticNtfn: func() interface{} {
68 return btcjson.NewFilteredBlockConnectedNtfn(100000, "header", []string{"tx0", "tx1"})
70 marshalled: `{"jsonrpc":"1.0","method":"filteredblockconnected","params":[100000,"header",["tx0","tx1"]],"id":null}`,
71 unmarshalled: &btcjson.FilteredBlockConnectedNtfn{
74 SubscribedTxs: []string{"tx0", "tx1"},
78 name: "filteredblockdisconnected",
79 newNtfn: func() (interface{}, error) {
80 return btcjson.NewCmd("filteredblockdisconnected", 100000, "header")
82 staticNtfn: func() interface{} {
83 return btcjson.NewFilteredBlockDisconnectedNtfn(100000, "header")
85 marshalled: `{"jsonrpc":"1.0","method":"filteredblockdisconnected","params":[100000,"header"],"id":null}`,
86 unmarshalled: &btcjson.FilteredBlockDisconnectedNtfn{
93 newNtfn: func() (interface{}, error) {
94 return btcjson.NewCmd("recvtx", "001122", `{"height":100000,"hash":"123","index":0,"time":12345678}`)
96 staticNtfn: func() interface{} {
97 blockDetails := btcjson.BlockDetails{
103 return btcjson.NewRecvTxNtfn("001122", &blockDetails)
105 marshalled: `{"jsonrpc":"1.0","method":"recvtx","params":["001122",{"height":100000,"hash":"123","index":0,"time":12345678}],"id":null}`,
106 unmarshalled: &btcjson.RecvTxNtfn{
108 Block: &btcjson.BlockDetails{
118 newNtfn: func() (interface{}, error) {
119 return btcjson.NewCmd("redeemingtx", "001122", `{"height":100000,"hash":"123","index":0,"time":12345678}`)
121 staticNtfn: func() interface{} {
122 blockDetails := btcjson.BlockDetails{
128 return btcjson.NewRedeemingTxNtfn("001122", &blockDetails)
130 marshalled: `{"jsonrpc":"1.0","method":"redeemingtx","params":["001122",{"height":100000,"hash":"123","index":0,"time":12345678}],"id":null}`,
131 unmarshalled: &btcjson.RedeemingTxNtfn{
133 Block: &btcjson.BlockDetails{
142 name: "rescanfinished",
143 newNtfn: func() (interface{}, error) {
144 return btcjson.NewCmd("rescanfinished", "123", 100000, 12345678)
146 staticNtfn: func() interface{} {
147 return btcjson.NewRescanFinishedNtfn("123", 100000, 12345678)
149 marshalled: `{"jsonrpc":"1.0","method":"rescanfinished","params":["123",100000,12345678],"id":null}`,
150 unmarshalled: &btcjson.RescanFinishedNtfn{
157 name: "rescanprogress",
158 newNtfn: func() (interface{}, error) {
159 return btcjson.NewCmd("rescanprogress", "123", 100000, 12345678)
161 staticNtfn: func() interface{} {
162 return btcjson.NewRescanProgressNtfn("123", 100000, 12345678)
164 marshalled: `{"jsonrpc":"1.0","method":"rescanprogress","params":["123",100000,12345678],"id":null}`,
165 unmarshalled: &btcjson.RescanProgressNtfn{
173 newNtfn: func() (interface{}, error) {
174 return btcjson.NewCmd("txaccepted", "123", 1.5)
176 staticNtfn: func() interface{} {
177 return btcjson.NewTxAcceptedNtfn("123", 1.5)
179 marshalled: `{"jsonrpc":"1.0","method":"txaccepted","params":["123",1.5],"id":null}`,
180 unmarshalled: &btcjson.TxAcceptedNtfn{
186 name: "txacceptedverbose",
187 newNtfn: func() (interface{}, error) {
188 return btcjson.NewCmd("txacceptedverbose", `{"hex":"001122","txid":"123","version":1,"locktime":4294967295,"vin":null,"vout":null,"confirmations":0}`)
190 staticNtfn: func() interface{} {
191 txResult := btcjson.TxRawResult{
195 LockTime: 4294967295,
200 return btcjson.NewTxAcceptedVerboseNtfn(txResult)
202 marshalled: `{"jsonrpc":"1.0","method":"txacceptedverbose","params":[{"hex":"001122","txid":"123","version":1,"locktime":4294967295,"vin":null,"vout":null}],"id":null}`,
203 unmarshalled: &btcjson.TxAcceptedVerboseNtfn{
204 RawTx: btcjson.TxRawResult{
208 LockTime: 4294967295,
216 name: "relevanttxaccepted",
217 newNtfn: func() (interface{}, error) {
218 return btcjson.NewCmd("relevanttxaccepted", "001122")
220 staticNtfn: func() interface{} {
221 return btcjson.NewRelevantTxAcceptedNtfn("001122")
223 marshalled: `{"jsonrpc":"1.0","method":"relevanttxaccepted","params":["001122"],"id":null}`,
224 unmarshalled: &btcjson.RelevantTxAcceptedNtfn{
225 Transaction: "001122",
230 t.Logf("Running %d tests", len(tests))
231 for i, test := range tests {
232 // Marshal the notification as created by the new static
233 // creation function. The ID is nil for notifications.
234 marshalled, err := btcjson.MarshalCmd(nil, test.staticNtfn())
236 t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i,
241 if !bytes.Equal(marshalled, []byte(test.marshalled)) {
242 t.Errorf("Test #%d (%s) unexpected marshalled data - "+
243 "got %s, want %s", i, test.name, marshalled,
248 // Ensure the notification is created without error via the
249 // generic new notification creation function.
250 cmd, err := test.newNtfn()
252 t.Errorf("Test #%d (%s) unexpected NewCmd error: %v ",
256 // Marshal the notification as created by the generic new
257 // notification creation function. The ID is nil for
259 marshalled, err = btcjson.MarshalCmd(nil, cmd)
261 t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i,
266 if !bytes.Equal(marshalled, []byte(test.marshalled)) {
267 t.Errorf("Test #%d (%s) unexpected marshalled data - "+
268 "got %s, want %s", i, test.name, marshalled,
273 var request btcjson.Request
274 if err := json.Unmarshal(marshalled, &request); err != nil {
275 t.Errorf("Test #%d (%s) unexpected error while "+
276 "unmarshalling JSON-RPC request: %v", i,
281 cmd, err = btcjson.UnmarshalCmd(&request)
283 t.Errorf("UnmarshalCmd #%d (%s) unexpected error: %v", i,
288 if !reflect.DeepEqual(cmd, test.unmarshalled) {
289 t.Errorf("Test #%d (%s) unexpected unmarshalled command "+
290 "- got %s, want %s", i, test.name,
291 fmt.Sprintf("(%T) %+[1]v", cmd),
292 fmt.Sprintf("(%T) %+[1]v\n", test.unmarshalled))