-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhandler_test.go
132 lines (117 loc) · 3.86 KB
/
handler_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package booze
import (
"context"
"net/http/httptest"
"testing"
"strings"
"bytes"
"github.com/gorilla/websocket"
)
func dummySuccessHandler(ctx context.Context, payload *Payload) (interface{}, *Error) {
return map[string]string{"message": "success"}, nil
}
func dummyErrorHandler(ctx context.Context, payload *Payload) (interface{}, *Error) {
err := &InvalidRequest
err.Data = "data"
return nil, err
}
func TestRPCHandler(t *testing.T) {
h := NewRPCHandler()
h.Register("test_ok", dummySuccessHandler)
h.Register("test_error", dummyErrorHandler)
ts := httptest.NewServer(h)
defer ts.Close()
port := strings.Split(ts.URL, ":")[2]
conn, _, err := websocket.DefaultDialer.Dial("ws://127.0.0.1:"+port, nil)
defer conn.Close()
if err != nil {
t.Fatal(err)
}
cases := []struct {
input, output []byte
name string
}{
{
[]byte(`{"method": "test_ok"}`),
[]byte(`{"id":"","result":{"message":"success"},"jsonrpc":"2.0"}`),
`valid single request`,
},
{
[]byte(`{"method": "test_error"}`),
[]byte(`{"id":"","error":{"code":-32600,"data":"data","message":"invalid request"},"jsonrpc":"2.0"}`),
`valid single request with err response`,
},
{
[]byte(`{"method": "unknown_method"}`),
[]byte(`{"id":"","error":{"code":-32601,"message":"method not found"},"jsonrpc":"2.0"}`),
`call unknown method`,
},
{
[]byte(`[{"method": "test_ok", "id": "1"}, {"method": "test_ok", "id": "2"}, {"method": "test_ok", "id": "3"}]`),
[]byte(`[{"id":"1","result":{"message":"success"},"jsonrpc":"2.0"},{"id":"2","result":{"message":"success"},"jsonrpc":"2.0"},{"id":"3","result":{"message":"success"},"jsonrpc":"2.0"}]`),
`valid multiple requests`,
},
{
[]byte(`[{"method": "test_ok", "id": "1"}, {"method": "test_error", "id": "2"}, {"method": "test_ok", "id": "3"}]`),
[]byte(`[{"id":"1","result":{"message":"success"},"jsonrpc":"2.0"},{"id":"2","error":{"code":-32600,"data":"data","message":"invalid request"},"jsonrpc":"2.0"},{"id":"3","result":{"message":"success"},"jsonrpc":"2.0"}]`),
`valid multiple requests with err response`,
},
{
[]byte(`{asd`),
[]byte(`{"id":"","error":{"code":-32700,"data":"invalid character 'a' looking for beginning of object key string","message":"parse error"},"jsonrpc":"2.0"}`),
`invalid json`,
},
{
[]byte(`[{"method": "test_ok", "id": "1"}, {"method": "test_ok", "id": "2"}`),
[]byte(`{"id":"","error":{"code":-32700,"data":"Value is array, but can't find closing ']' symbol","message":"parse error"},"jsonrpc":"2.0"}`),
`invalid array json`,
},
{
[]byte(`{"method": 12331212}`),
[]byte(`{"id":"","error":{"code":-32602,"data":"json: cannot unmarshal number into Go struct field Payload.method of type string","message":"invalid params"},"jsonrpc":"2.0"}`),
`invalid json attrs`,
},
}
for _, c := range cases {
err = conn.WriteMessage(websocket.TextMessage, []byte(c.input))
if err != nil {
t.Fatal(err)
}
_, resp, err := conn.ReadMessage()
if err != nil {
t.Fatal(err)
}
resp = bytes.TrimSpace(resp)
if !bytes.Equal(resp, c.output) {
t.Fatalf("got unexpected response:\n%s\n\nexpected:\n%s\non testcase %s", resp, c.output, c.name)
}
}
drainResponseChannel := struct {
input [][]byte
name string
}{
[][]byte{
[]byte(`{"method": "test_ok"}`),
[]byte(`{"method": "unknown_method"}`),
[]byte(`{"method": "test_error"}`),
},
`valid single request`,
}
for _, input := range drainResponseChannel.input {
err = conn.WriteMessage(websocket.TextMessage, []byte(input))
if err != nil {
t.Fatal(err)
}
}
responsesCount := 0
for range drainResponseChannel.input {
_, _, err := conn.ReadMessage()
if err != nil {
t.Fatal(err)
}
responsesCount++
}
if responsesCount != len(drainResponseChannel.input) {
t.Fatalf("got unexpected responses count: %d, expected: %d", responsesCount, len(drainResponseChannel.input))
}
}