-
Notifications
You must be signed in to change notification settings - Fork 0
/
handler_test.go
167 lines (136 loc) · 4.67 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package courier
import (
"context"
"errors"
"io/ioutil"
"net/http"
"testing"
"time"
"github.com/nyaruka/gocommon/urns"
"github.com/stretchr/testify/assert"
)
func init() {
RegisterHandler(NewHandler())
}
type dummyHandler struct {
server Server
backend Backend
}
// NewHandler returns a new Dummy handler
func NewHandler() ChannelHandler {
return &dummyHandler{}
}
func (h *dummyHandler) ChannelName() string { return "Dummy Handler" }
func (h *dummyHandler) ChannelType() ChannelType { return ChannelType("DM") }
func (h *dummyHandler) UseChannelRouteUUID() bool { return true }
func (h *dummyHandler) GetChannel(ctx context.Context, r *http.Request) (Channel, error) {
dmChannel := NewMockChannel("e4bb1578-29da-4fa5-a214-9da19dd24230", "DM", "2020", "US", map[string]interface{}{})
return dmChannel, nil
}
// Initialize is called by the engine once everything is loaded
func (h *dummyHandler) Initialize(s Server) error {
h.server = s
h.backend = s.Backend()
s.AddHandlerRoute(h, http.MethodGet, "receive", h.receiveMsg)
return nil
}
// SendMsg sends the passed in message, returning any error
func (h *dummyHandler) SendMsg(ctx context.Context, msg Msg) (MsgStatus, error) {
return h.backend.NewMsgStatusForID(msg.Channel(), msg.ID(), MsgSent), nil
}
// ReceiveMsg sends the passed in message, returning any error
func (h *dummyHandler) receiveMsg(ctx context.Context, channel Channel, w http.ResponseWriter, r *http.Request) ([]Event, error) {
r.ParseForm()
from := r.Form.Get("from")
text := r.Form.Get("text")
if from == "" || text == "" {
return nil, errors.New("missing from or text")
}
msg := h.backend.NewIncomingMsg(channel, urns.URN("tel:"+from), text)
w.WriteHeader(200)
w.Write([]byte("ok"))
h.backend.WriteMsg(ctx, msg)
return []Event{msg}, nil
}
func (h *dummyHandler) PurgeOutgoing(ctx context.Context, channel Channel) error {
return nil
}
func testConfig() *Config {
config := NewConfig()
config.DB = "postgres://courier:courier@localhost:5432/courier_test?sslmode=disable"
config.Redis = "redis://localhost:6379/0"
return config
}
func TestHandling(t *testing.T) {
assert := assert.New(t)
// create our backend and server
mb := NewMockBackend()
s := NewServer(testConfig(), mb)
// start everything
s.Start()
defer s.Stop()
time.Sleep(100 * time.Millisecond)
// create and add a new outgoing message
xxChannel := NewMockChannel("53e5aafa-8155-449d-9009-fcb30d54bd26", "XX", "2020", "US", map[string]interface{}{})
dmChannel := NewMockChannel("e4bb1578-29da-4fa5-a214-9da19dd24230", "DM", "2020", "US", map[string]interface{}{})
mb.AddChannel(dmChannel)
msg := &mockMsg{
channel: xxChannel,
id: NewMsgID(101),
uuid: NilMsgUUID,
text: "test message",
urn: "tel:+250788383383",
}
mb.PushOutgoingMsg(msg)
// sleep a second, sender should take care of it in that time
time.Sleep(time.Second)
// message should have errored because we have registered handlers
assert.Equal(1, len(mb.msgStatuses))
assert.Equal(msg.ID(), mb.msgStatuses[0].ID())
assert.Equal(MsgErrored, mb.msgStatuses[0].Status())
assert.Equal(1, len(mb.msgStatuses[0].Logs()))
// clear our statuses
mb.msgStatuses = nil
// change our channel to our dummy channel
msg = &mockMsg{
channel: dmChannel,
id: NewMsgID(102),
uuid: NilMsgUUID,
text: "test message 2",
urn: "tel:+250788383383",
}
// send it
mb.PushOutgoingMsg(msg)
time.Sleep(time.Second)
// message should be marked as wired
assert.Equal(1, len(mb.msgStatuses))
assert.Equal(msg.ID(), mb.msgStatuses[0].ID())
assert.Equal(MsgSent, mb.msgStatuses[0].Status())
// clear our statuses
mb.msgStatuses = nil
// send the message again, should be skipped but again marked as wired
mb.PushOutgoingMsg(msg)
time.Sleep(time.Second)
// message should be marked as wired
assert.Equal(1, len(mb.msgStatuses))
assert.Equal(msg.ID(), mb.msgStatuses[0].ID())
assert.Equal(MsgWired, mb.msgStatuses[0].Status())
// try to receive a message instead
resp, err := http.Get("http://localhost:8080/c/dm/e4bb1578-29da-4fa5-a214-9da19dd24230/receive")
assert.NoError(err)
assert.Equal(400, resp.StatusCode)
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
assert.Contains(string(body), "missing from or text")
req, _ := http.NewRequest("GET", "http://localhost:8080/c/dm/e4bb1578-29da-4fa5-a214-9da19dd24230/receive?from=2065551212&text=hello", nil)
req.Header.Set("Cookie", "secret")
resp, err = http.DefaultClient.Do(req)
assert.NoError(err)
assert.Equal(200, resp.StatusCode)
defer resp.Body.Close()
body, _ = ioutil.ReadAll(resp.Body)
assert.Contains(string(body), "ok")
// cookie stripped
log, _ := mb.GetLastChannelLog()
assert.NotContains(log.Request, "secret")
}