github.com/btcsuite/btcd@v0.24.0/btcjson/chainsvrwsntfns_test.go (about) 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. 5 6 package btcjson_test 7 8 import ( 9 "bytes" 10 "encoding/json" 11 "fmt" 12 "reflect" 13 "testing" 14 15 "github.com/btcsuite/btcd/btcjson" 16 ) 17 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) { 23 t.Parallel() 24 25 tests := []struct { 26 name string 27 newNtfn func() (interface{}, error) 28 staticNtfn func() interface{} 29 marshalled string 30 unmarshalled interface{} 31 }{ 32 { 33 name: "blockconnected", 34 newNtfn: func() (interface{}, error) { 35 return btcjson.NewCmd("blockconnected", "123", 100000, 123456789) 36 }, 37 staticNtfn: func() interface{} { 38 return btcjson.NewBlockConnectedNtfn("123", 100000, 123456789) 39 }, 40 marshalled: `{"jsonrpc":"1.0","method":"blockconnected","params":["123",100000,123456789],"id":null}`, 41 unmarshalled: &btcjson.BlockConnectedNtfn{ 42 Hash: "123", 43 Height: 100000, 44 Time: 123456789, 45 }, 46 }, 47 { 48 name: "blockdisconnected", 49 newNtfn: func() (interface{}, error) { 50 return btcjson.NewCmd("blockdisconnected", "123", 100000, 123456789) 51 }, 52 staticNtfn: func() interface{} { 53 return btcjson.NewBlockDisconnectedNtfn("123", 100000, 123456789) 54 }, 55 marshalled: `{"jsonrpc":"1.0","method":"blockdisconnected","params":["123",100000,123456789],"id":null}`, 56 unmarshalled: &btcjson.BlockDisconnectedNtfn{ 57 Hash: "123", 58 Height: 100000, 59 Time: 123456789, 60 }, 61 }, 62 { 63 name: "filteredblockconnected", 64 newNtfn: func() (interface{}, error) { 65 return btcjson.NewCmd("filteredblockconnected", 100000, "header", []string{"tx0", "tx1"}) 66 }, 67 staticNtfn: func() interface{} { 68 return btcjson.NewFilteredBlockConnectedNtfn(100000, "header", []string{"tx0", "tx1"}) 69 }, 70 marshalled: `{"jsonrpc":"1.0","method":"filteredblockconnected","params":[100000,"header",["tx0","tx1"]],"id":null}`, 71 unmarshalled: &btcjson.FilteredBlockConnectedNtfn{ 72 Height: 100000, 73 Header: "header", 74 SubscribedTxs: []string{"tx0", "tx1"}, 75 }, 76 }, 77 { 78 name: "filteredblockdisconnected", 79 newNtfn: func() (interface{}, error) { 80 return btcjson.NewCmd("filteredblockdisconnected", 100000, "header") 81 }, 82 staticNtfn: func() interface{} { 83 return btcjson.NewFilteredBlockDisconnectedNtfn(100000, "header") 84 }, 85 marshalled: `{"jsonrpc":"1.0","method":"filteredblockdisconnected","params":[100000,"header"],"id":null}`, 86 unmarshalled: &btcjson.FilteredBlockDisconnectedNtfn{ 87 Height: 100000, 88 Header: "header", 89 }, 90 }, 91 { 92 name: "recvtx", 93 newNtfn: func() (interface{}, error) { 94 return btcjson.NewCmd("recvtx", "001122", `{"height":100000,"hash":"123","index":0,"time":12345678}`) 95 }, 96 staticNtfn: func() interface{} { 97 blockDetails := btcjson.BlockDetails{ 98 Height: 100000, 99 Hash: "123", 100 Index: 0, 101 Time: 12345678, 102 } 103 return btcjson.NewRecvTxNtfn("001122", &blockDetails) 104 }, 105 marshalled: `{"jsonrpc":"1.0","method":"recvtx","params":["001122",{"height":100000,"hash":"123","index":0,"time":12345678}],"id":null}`, 106 unmarshalled: &btcjson.RecvTxNtfn{ 107 HexTx: "001122", 108 Block: &btcjson.BlockDetails{ 109 Height: 100000, 110 Hash: "123", 111 Index: 0, 112 Time: 12345678, 113 }, 114 }, 115 }, 116 { 117 name: "redeemingtx", 118 newNtfn: func() (interface{}, error) { 119 return btcjson.NewCmd("redeemingtx", "001122", `{"height":100000,"hash":"123","index":0,"time":12345678}`) 120 }, 121 staticNtfn: func() interface{} { 122 blockDetails := btcjson.BlockDetails{ 123 Height: 100000, 124 Hash: "123", 125 Index: 0, 126 Time: 12345678, 127 } 128 return btcjson.NewRedeemingTxNtfn("001122", &blockDetails) 129 }, 130 marshalled: `{"jsonrpc":"1.0","method":"redeemingtx","params":["001122",{"height":100000,"hash":"123","index":0,"time":12345678}],"id":null}`, 131 unmarshalled: &btcjson.RedeemingTxNtfn{ 132 HexTx: "001122", 133 Block: &btcjson.BlockDetails{ 134 Height: 100000, 135 Hash: "123", 136 Index: 0, 137 Time: 12345678, 138 }, 139 }, 140 }, 141 { 142 name: "rescanfinished", 143 newNtfn: func() (interface{}, error) { 144 return btcjson.NewCmd("rescanfinished", "123", 100000, 12345678) 145 }, 146 staticNtfn: func() interface{} { 147 return btcjson.NewRescanFinishedNtfn("123", 100000, 12345678) 148 }, 149 marshalled: `{"jsonrpc":"1.0","method":"rescanfinished","params":["123",100000,12345678],"id":null}`, 150 unmarshalled: &btcjson.RescanFinishedNtfn{ 151 Hash: "123", 152 Height: 100000, 153 Time: 12345678, 154 }, 155 }, 156 { 157 name: "rescanprogress", 158 newNtfn: func() (interface{}, error) { 159 return btcjson.NewCmd("rescanprogress", "123", 100000, 12345678) 160 }, 161 staticNtfn: func() interface{} { 162 return btcjson.NewRescanProgressNtfn("123", 100000, 12345678) 163 }, 164 marshalled: `{"jsonrpc":"1.0","method":"rescanprogress","params":["123",100000,12345678],"id":null}`, 165 unmarshalled: &btcjson.RescanProgressNtfn{ 166 Hash: "123", 167 Height: 100000, 168 Time: 12345678, 169 }, 170 }, 171 { 172 name: "txaccepted", 173 newNtfn: func() (interface{}, error) { 174 return btcjson.NewCmd("txaccepted", "123", 1.5) 175 }, 176 staticNtfn: func() interface{} { 177 return btcjson.NewTxAcceptedNtfn("123", 1.5) 178 }, 179 marshalled: `{"jsonrpc":"1.0","method":"txaccepted","params":["123",1.5],"id":null}`, 180 unmarshalled: &btcjson.TxAcceptedNtfn{ 181 TxID: "123", 182 Amount: 1.5, 183 }, 184 }, 185 { 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}`) 189 }, 190 staticNtfn: func() interface{} { 191 txResult := btcjson.TxRawResult{ 192 Hex: "001122", 193 Txid: "123", 194 Version: 1, 195 LockTime: 4294967295, 196 Vin: nil, 197 Vout: nil, 198 Confirmations: 0, 199 } 200 return btcjson.NewTxAcceptedVerboseNtfn(txResult) 201 }, 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{ 205 Hex: "001122", 206 Txid: "123", 207 Version: 1, 208 LockTime: 4294967295, 209 Vin: nil, 210 Vout: nil, 211 Confirmations: 0, 212 }, 213 }, 214 }, 215 { 216 name: "relevanttxaccepted", 217 newNtfn: func() (interface{}, error) { 218 return btcjson.NewCmd("relevanttxaccepted", "001122") 219 }, 220 staticNtfn: func() interface{} { 221 return btcjson.NewRelevantTxAcceptedNtfn("001122") 222 }, 223 marshalled: `{"jsonrpc":"1.0","method":"relevanttxaccepted","params":["001122"],"id":null}`, 224 unmarshalled: &btcjson.RelevantTxAcceptedNtfn{ 225 Transaction: "001122", 226 }, 227 }, 228 } 229 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(btcjson.RpcVersion1, nil, test.staticNtfn()) 235 if err != nil { 236 t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i, 237 test.name, err) 238 continue 239 } 240 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, 244 test.marshalled) 245 continue 246 } 247 248 // Ensure the notification is created without error via the 249 // generic new notification creation function. 250 cmd, err := test.newNtfn() 251 if err != nil { 252 t.Errorf("Test #%d (%s) unexpected NewCmd error: %v ", 253 i, test.name, err) 254 } 255 256 // Marshal the notification as created by the generic new 257 // notification creation function. The ID is nil for 258 // notifications. 259 marshalled, err = btcjson.MarshalCmd(btcjson.RpcVersion1, nil, cmd) 260 if err != nil { 261 t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i, 262 test.name, err) 263 continue 264 } 265 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, 269 test.marshalled) 270 continue 271 } 272 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, 277 test.name, err) 278 continue 279 } 280 281 cmd, err = btcjson.UnmarshalCmd(&request) 282 if err != nil { 283 t.Errorf("UnmarshalCmd #%d (%s) unexpected error: %v", i, 284 test.name, err) 285 continue 286 } 287 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)) 293 continue 294 } 295 } 296 }