lbcd/notifications_test.go
Josh Rickmar 2731634dda Implement notifications that actually follow the JSON-RPC spec.
This changes notifications to JSON-RPC Requests, rather than
Responses, that also satisify the btcjson.Cmd interface and are
registered with btcjson's parser.  This prevents issues where JSON-RPC
Response IDs clash due to a client using the same ID as what an old
notification used.

As this changes the API, and thus, requires notification handlers to
be modified, the remaining missing notifications used by btcwallet
have been implemented.  Applications parsing these notifications, such
as btcgui, can now use a common handler function signature for all
notifications.

Test coverage for all notifications has been added (excluding testing
for badly-marshaled notifications with wrong numbers of parameters, or
wrong types).

Fixes #2.
2013-12-13 10:59:09 -05:00

161 lines
3.8 KiB
Go

// Copyright (c) 2013 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcws_test
import (
"github.com/conformal/btcjson"
"github.com/conformal/btcws"
"github.com/davecgh/go-spew/spew"
"reflect"
"testing"
)
var ntfntests = []struct {
name string
f func() btcjson.Cmd
result btcjson.Cmd // after marshal and unmarshal
}{
{
name: "accountbalance",
f: func() btcjson.Cmd {
return btcws.NewAccountBalanceNtfn("abcde", 1.2345, true)
},
result: &btcws.AccountBalanceNtfn{
Account: "abcde",
Balance: 1.2345,
Confirmed: true,
},
},
{
name: "blockconnected",
f: func() btcjson.Cmd {
return btcws.NewBlockConnectedNtfn(
"000000004811dda1c320ad5d0ea184a20a53acd92292c5f1cb926c3ee82abf70",
153469)
},
result: &btcws.BlockConnectedNtfn{
Hash: "000000004811dda1c320ad5d0ea184a20a53acd92292c5f1cb926c3ee82abf70",
Height: 153469,
},
},
{
name: "blockdisconnected",
f: func() btcjson.Cmd {
return btcws.NewBlockDisconnectedNtfn(
"000000004811dda1c320ad5d0ea184a20a53acd92292c5f1cb926c3ee82abf70",
153469)
},
result: &btcws.BlockDisconnectedNtfn{
Hash: "000000004811dda1c320ad5d0ea184a20a53acd92292c5f1cb926c3ee82abf70",
Height: 153469,
},
},
{
name: "btcdconnected",
f: func() btcjson.Cmd {
return btcws.NewBtcdConnectedNtfn(true)
},
result: &btcws.BtcdConnectedNtfn{
Connected: true,
},
},
{
name: "txmined",
f: func() btcjson.Cmd {
return btcws.NewTxMinedNtfn(
"062f2b5f7d28c787e0f3aee382132241cd590efb7b83bd2c7f506de5aa4ef275",
"000000004811dda1c320ad5d0ea184a20a53acd92292c5f1cb926c3ee82abf70",
153469,
1386944019,
0)
},
result: &btcws.TxMinedNtfn{
TxID: "062f2b5f7d28c787e0f3aee382132241cd590efb7b83bd2c7f506de5aa4ef275",
BlockHash: "000000004811dda1c320ad5d0ea184a20a53acd92292c5f1cb926c3ee82abf70",
BlockHeight: 153469,
BlockTime: 1386944019,
Index: 0,
},
},
{
name: "newtx",
f: func() btcjson.Cmd {
details := map[string]interface{}{
"key1": float64(12345),
"key2": true,
"key3": "lalala",
"key4": []interface{}{"abcde", float64(12345)},
}
return btcws.NewTxNtfn("abcde", details)
},
result: &btcws.TxNtfn{
Account: "abcde",
Details: map[string]interface{}{
"key1": float64(12345),
"key2": true,
"key3": "lalala",
"key4": []interface{}{"abcde", float64(12345)},
},
},
},
{
name: "walletlockstate",
f: func() btcjson.Cmd {
return btcws.NewWalletLockStateNtfn("abcde", true)
},
result: &btcws.WalletLockStateNtfn{
Account: "abcde",
Locked: true,
},
},
}
func TestNtfns(t *testing.T) {
for _, test := range ntfntests {
// create notification.
n := test.f()
// verify that id is nil.
if n.Id() != nil {
t.Error("%s: notification should not have non-nil id %v",
test.name, n.Id())
continue
}
mn, err := n.MarshalJSON()
if err != nil {
t.Errorf("%s: failed to marshal notification: %v",
test.name, err)
continue
}
n2, err := btcjson.ParseMarshaledCmd(mn)
if err != nil {
t.Errorf("%s: failed to ummarshal cmd: %v",
test.name, err)
continue
}
if !reflect.DeepEqual(test.result, n2) {
t.Errorf("%s: unmarshal not as expected. "+
"got %v wanted %v", test.name, spew.Sdump(n2),
spew.Sdump(test.result))
}
if !reflect.DeepEqual(n, n2) {
t.Errorf("%s: unmarshal not as we started with. "+
"got %v wanted %v", test.name, spew.Sdump(n2),
spew.Sdump(n))
}
// Read marshaled notification back into n. Should still
// match result.
n.UnmarshalJSON(mn)
if !reflect.DeepEqual(test.result, n) {
t.Errorf("%s: unmarshal not as expected. "+
"got %v wanted %v", test.name, spew.Sdump(n),
spew.Sdump(test.result))
}
}
}