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 // TestChainSvrWsCmds tests all of the chain server websocket-specific commands
19 // marshal and unmarshal into valid results include handling of optional fields
20 // being omitted in the marshalled command, while optional fields with defaults
21 // have the default assigned on unmarshalled commands.
22 func TestChainSvrWsCmds(t *testing.T) {
28 newCmd func() (interface{}, error)
29 staticCmd func() interface{}
31 unmarshalled interface{}
35 newCmd: func() (interface{}, error) {
36 return btcjson.NewCmd("authenticate", "user", "pass")
38 staticCmd: func() interface{} {
39 return btcjson.NewAuthenticateCmd("user", "pass")
41 marshalled: `{"jsonrpc":"1.0","method":"authenticate","params":["user","pass"],"id":1}`,
42 unmarshalled: &btcjson.AuthenticateCmd{Username: "user", Passphrase: "pass"},
46 newCmd: func() (interface{}, error) {
47 return btcjson.NewCmd("notifyblocks")
49 staticCmd: func() interface{} {
50 return btcjson.NewNotifyBlocksCmd()
52 marshalled: `{"jsonrpc":"1.0","method":"notifyblocks","params":[],"id":1}`,
53 unmarshalled: &btcjson.NotifyBlocksCmd{},
56 name: "stopnotifyblocks",
57 newCmd: func() (interface{}, error) {
58 return btcjson.NewCmd("stopnotifyblocks")
60 staticCmd: func() interface{} {
61 return btcjson.NewStopNotifyBlocksCmd()
63 marshalled: `{"jsonrpc":"1.0","method":"stopnotifyblocks","params":[],"id":1}`,
64 unmarshalled: &btcjson.StopNotifyBlocksCmd{},
67 name: "notifynewtransactions",
68 newCmd: func() (interface{}, error) {
69 return btcjson.NewCmd("notifynewtransactions")
71 staticCmd: func() interface{} {
72 return btcjson.NewNotifyNewTransactionsCmd(nil)
74 marshalled: `{"jsonrpc":"1.0","method":"notifynewtransactions","params":[],"id":1}`,
75 unmarshalled: &btcjson.NotifyNewTransactionsCmd{
76 Verbose: btcjson.Bool(false),
80 name: "notifynewtransactions optional",
81 newCmd: func() (interface{}, error) {
82 return btcjson.NewCmd("notifynewtransactions", true)
84 staticCmd: func() interface{} {
85 return btcjson.NewNotifyNewTransactionsCmd(btcjson.Bool(true))
87 marshalled: `{"jsonrpc":"1.0","method":"notifynewtransactions","params":[true],"id":1}`,
88 unmarshalled: &btcjson.NotifyNewTransactionsCmd{
89 Verbose: btcjson.Bool(true),
93 name: "stopnotifynewtransactions",
94 newCmd: func() (interface{}, error) {
95 return btcjson.NewCmd("stopnotifynewtransactions")
97 staticCmd: func() interface{} {
98 return btcjson.NewStopNotifyNewTransactionsCmd()
100 marshalled: `{"jsonrpc":"1.0","method":"stopnotifynewtransactions","params":[],"id":1}`,
101 unmarshalled: &btcjson.StopNotifyNewTransactionsCmd{},
104 name: "notifyreceived",
105 newCmd: func() (interface{}, error) {
106 return btcjson.NewCmd("notifyreceived", []string{"1Address"})
108 staticCmd: func() interface{} {
109 return btcjson.NewNotifyReceivedCmd([]string{"1Address"})
111 marshalled: `{"jsonrpc":"1.0","method":"notifyreceived","params":[["1Address"]],"id":1}`,
112 unmarshalled: &btcjson.NotifyReceivedCmd{
113 Addresses: []string{"1Address"},
117 name: "stopnotifyreceived",
118 newCmd: func() (interface{}, error) {
119 return btcjson.NewCmd("stopnotifyreceived", []string{"1Address"})
121 staticCmd: func() interface{} {
122 return btcjson.NewStopNotifyReceivedCmd([]string{"1Address"})
124 marshalled: `{"jsonrpc":"1.0","method":"stopnotifyreceived","params":[["1Address"]],"id":1}`,
125 unmarshalled: &btcjson.StopNotifyReceivedCmd{
126 Addresses: []string{"1Address"},
131 newCmd: func() (interface{}, error) {
132 return btcjson.NewCmd("notifyspent", `[{"hash":"123","index":0}]`)
134 staticCmd: func() interface{} {
135 ops := []btcjson.OutPoint{{Hash: "123", Index: 0}}
136 return btcjson.NewNotifySpentCmd(ops)
138 marshalled: `{"jsonrpc":"1.0","method":"notifyspent","params":[[{"hash":"123","index":0}]],"id":1}`,
139 unmarshalled: &btcjson.NotifySpentCmd{
140 OutPoints: []btcjson.OutPoint{{Hash: "123", Index: 0}},
144 name: "stopnotifyspent",
145 newCmd: func() (interface{}, error) {
146 return btcjson.NewCmd("stopnotifyspent", `[{"hash":"123","index":0}]`)
148 staticCmd: func() interface{} {
149 ops := []btcjson.OutPoint{{Hash: "123", Index: 0}}
150 return btcjson.NewStopNotifySpentCmd(ops)
152 marshalled: `{"jsonrpc":"1.0","method":"stopnotifyspent","params":[[{"hash":"123","index":0}]],"id":1}`,
153 unmarshalled: &btcjson.StopNotifySpentCmd{
154 OutPoints: []btcjson.OutPoint{{Hash: "123", Index: 0}},
159 newCmd: func() (interface{}, error) {
160 return btcjson.NewCmd("rescan", "123", `["1Address"]`, `[{"hash":"0000000000000000000000000000000000000000000000000000000000000123","index":0}]`)
162 staticCmd: func() interface{} {
163 addrs := []string{"1Address"}
164 ops := []btcjson.OutPoint{{
165 Hash: "0000000000000000000000000000000000000000000000000000000000000123",
168 return btcjson.NewRescanCmd("123", addrs, ops, nil)
170 marshalled: `{"jsonrpc":"1.0","method":"rescan","params":["123",["1Address"],[{"hash":"0000000000000000000000000000000000000000000000000000000000000123","index":0}]],"id":1}`,
171 unmarshalled: &btcjson.RescanCmd{
173 Addresses: []string{"1Address"},
174 OutPoints: []btcjson.OutPoint{{Hash: "0000000000000000000000000000000000000000000000000000000000000123", Index: 0}},
179 name: "rescan optional",
180 newCmd: func() (interface{}, error) {
181 return btcjson.NewCmd("rescan", "123", `["1Address"]`, `[{"hash":"123","index":0}]`, "456")
183 staticCmd: func() interface{} {
184 addrs := []string{"1Address"}
185 ops := []btcjson.OutPoint{{Hash: "123", Index: 0}}
186 return btcjson.NewRescanCmd("123", addrs, ops, btcjson.String("456"))
188 marshalled: `{"jsonrpc":"1.0","method":"rescan","params":["123",["1Address"],[{"hash":"123","index":0}],"456"],"id":1}`,
189 unmarshalled: &btcjson.RescanCmd{
191 Addresses: []string{"1Address"},
192 OutPoints: []btcjson.OutPoint{{Hash: "123", Index: 0}},
193 EndBlock: btcjson.String("456"),
197 name: "loadtxfilter",
198 newCmd: func() (interface{}, error) {
199 return btcjson.NewCmd("loadtxfilter", false, `["1Address"]`, `[{"hash":"0000000000000000000000000000000000000000000000000000000000000123","index":0}]`)
201 staticCmd: func() interface{} {
202 addrs := []string{"1Address"}
203 ops := []btcjson.OutPoint{{
204 Hash: "0000000000000000000000000000000000000000000000000000000000000123",
207 return btcjson.NewLoadTxFilterCmd(false, addrs, ops)
209 marshalled: `{"jsonrpc":"1.0","method":"loadtxfilter","params":[false,["1Address"],[{"hash":"0000000000000000000000000000000000000000000000000000000000000123","index":0}]],"id":1}`,
210 unmarshalled: &btcjson.LoadTxFilterCmd{
212 Addresses: []string{"1Address"},
213 OutPoints: []btcjson.OutPoint{{Hash: "0000000000000000000000000000000000000000000000000000000000000123", Index: 0}},
217 name: "rescanblocks",
218 newCmd: func() (interface{}, error) {
219 return btcjson.NewCmd("rescanblocks", `["0000000000000000000000000000000000000000000000000000000000000123"]`)
221 staticCmd: func() interface{} {
222 blockhashes := []string{"0000000000000000000000000000000000000000000000000000000000000123"}
223 return btcjson.NewRescanBlocksCmd(blockhashes)
225 marshalled: `{"jsonrpc":"1.0","method":"rescanblocks","params":[["0000000000000000000000000000000000000000000000000000000000000123"]],"id":1}`,
226 unmarshalled: &btcjson.RescanBlocksCmd{
227 BlockHashes: []string{"0000000000000000000000000000000000000000000000000000000000000123"},
232 t.Logf("Running %d tests", len(tests))
233 for i, test := range tests {
234 // Marshal the command as created by the new static command
235 // creation function.
236 marshalled, err := btcjson.MarshalCmd(testID, test.staticCmd())
238 t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i,
243 if !bytes.Equal(marshalled, []byte(test.marshalled)) {
244 t.Errorf("Test #%d (%s) unexpected marshalled data - "+
245 "got %s, want %s", i, test.name, marshalled,
250 // Ensure the command is created without error via the generic
251 // new command creation function.
252 cmd, err := test.newCmd()
254 t.Errorf("Test #%d (%s) unexpected NewCmd error: %v ",
258 // Marshal the command as created by the generic new command
259 // creation function.
260 marshalled, err = btcjson.MarshalCmd(testID, cmd)
262 t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i,
267 if !bytes.Equal(marshalled, []byte(test.marshalled)) {
268 t.Errorf("Test #%d (%s) unexpected marshalled data - "+
269 "got %s, want %s", i, test.name, marshalled,
274 var request btcjson.Request
275 if err := json.Unmarshal(marshalled, &request); err != nil {
276 t.Errorf("Test #%d (%s) unexpected error while "+
277 "unmarshalling JSON-RPC request: %v", i,
282 cmd, err = btcjson.UnmarshalCmd(&request)
284 t.Errorf("UnmarshalCmd #%d (%s) unexpected error: %v", i,
289 if !reflect.DeepEqual(cmd, test.unmarshalled) {
290 t.Errorf("Test #%d (%s) unexpected unmarshalled command "+
291 "- got %s, want %s", i, test.name,
292 fmt.Sprintf("(%T) %+[1]v", cmd),
293 fmt.Sprintf("(%T) %+[1]v\n", test.unmarshalled))