Do not export Router.route as it is not supposed to be called directly

disco_info_form
Mickael Remond 5 years ago committed by Mickaël Rémond
parent 3521c488ea
commit d6d371df4d

@ -210,13 +210,13 @@ func (c *Client) recv(keepaliveQuit chan<- struct{}) (err error) {
// Handle stream errors // Handle stream errors
switch packet := val.(type) { switch packet := val.(type) {
case StreamError: case StreamError:
c.router.Route(c, val) c.router.route(c, val)
close(keepaliveQuit) close(keepaliveQuit)
c.streamError(packet.Error.Local, packet.Text) c.streamError(packet.Error.Local, packet.Text)
return errors.New("stream error: " + packet.Error.Local) return errors.New("stream error: " + packet.Error.Local)
} }
c.router.Route(c, val) c.router.route(c, val)
} }
} }

@ -128,11 +128,11 @@ func (c *Component) recv() (err error) {
// Handle stream errors // Handle stream errors
switch p := val.(type) { switch p := val.(type) {
case StreamError: case StreamError:
c.router.Route(c, val) c.router.route(c, val)
c.streamError(p.Error.Local, p.Text) c.streamError(p.Error.Local, p.Text)
return errors.New("stream error: " + p.Error.Local) return errors.New("stream error: " + p.Error.Local)
} }
c.router.Route(c, val) c.router.route(c, val)
} }
} }

@ -29,7 +29,9 @@ func NewRouter() *Router {
return &Router{} return &Router{}
} }
func (r *Router) Route(s Sender, p Packet) { // route is called by the XMPP client to dispatch stanza received using the set up routes.
// It is also used by test, but is not supposed to be used directly by users of the library.
func (r *Router) route(s Sender, p Packet) {
var match RouteMatch var match RouteMatch
if r.Match(p, &match) { if r.Match(p, &match) {
match.Handler.HandlePacket(s, p) match.Handler.HandlePacket(s, p)

@ -1,91 +1,89 @@
package xmpp_test package xmpp
import ( import (
"bytes" "bytes"
"encoding/xml" "encoding/xml"
"testing" "testing"
"gosrc.io/xmpp"
) )
// ============================================================================ // ============================================================================
// Test route & matchers // Test route & matchers
func TestNameMatcher(t *testing.T) { func TestNameMatcher(t *testing.T) {
router := xmpp.NewRouter() router := NewRouter()
router.HandleFunc("message", func(s xmpp.Sender, p xmpp.Packet) { router.HandleFunc("message", func(s Sender, p Packet) {
_ = s.SendRaw(successFlag) _ = s.SendRaw(successFlag)
}) })
// Check that a message packet is properly matched // Check that a message packet is properly matched
conn := NewSenderMock() conn := NewSenderMock()
msg := xmpp.NewMessage(xmpp.Attrs{Type: xmpp.MessageTypeChat, To: "test@localhost", Id: "1"}) msg := NewMessage(Attrs{Type: MessageTypeChat, To: "test@localhost", Id: "1"})
msg.Body = "Hello" msg.Body = "Hello"
router.Route(conn, msg) router.route(conn, msg)
if conn.String() != successFlag { if conn.String() != successFlag {
t.Error("Message was not matched and routed properly") t.Error("Message was not matched and routed properly")
} }
// Check that an IQ packet is not matched // Check that an IQ packet is not matched
conn = NewSenderMock() conn = NewSenderMock()
iq := xmpp.NewIQ(xmpp.Attrs{Type: xmpp.IQTypeGet, To: "localhost", Id: "1"}) iq := NewIQ(Attrs{Type: IQTypeGet, To: "localhost", Id: "1"})
iq.Payload = &xmpp.DiscoInfo{} iq.Payload = &DiscoInfo{}
router.Route(conn, iq) router.route(conn, iq)
if conn.String() == successFlag { if conn.String() == successFlag {
t.Error("IQ should not have been matched and routed") t.Error("IQ should not have been matched and routed")
} }
} }
func TestIQNSMatcher(t *testing.T) { func TestIQNSMatcher(t *testing.T) {
router := xmpp.NewRouter() router := NewRouter()
router.NewRoute(). router.NewRoute().
IQNamespaces(xmpp.NSDiscoInfo, xmpp.NSDiscoItems). IQNamespaces(NSDiscoInfo, NSDiscoItems).
HandlerFunc(func(s xmpp.Sender, p xmpp.Packet) { HandlerFunc(func(s Sender, p Packet) {
_ = s.SendRaw(successFlag) _ = s.SendRaw(successFlag)
}) })
// Check that an IQ with proper namespace does match // Check that an IQ with proper namespace does match
conn := NewSenderMock() conn := NewSenderMock()
iqDisco := xmpp.NewIQ(xmpp.Attrs{Type: xmpp.IQTypeGet, To: "localhost", Id: "1"}) iqDisco := NewIQ(Attrs{Type: IQTypeGet, To: "localhost", Id: "1"})
// TODO: Add a function to generate payload with proper namespace initialisation // TODO: Add a function to generate payload with proper namespace initialisation
iqDisco.Payload = &xmpp.DiscoInfo{ iqDisco.Payload = &DiscoInfo{
XMLName: xml.Name{ XMLName: xml.Name{
Space: xmpp.NSDiscoInfo, Space: NSDiscoInfo,
Local: "query", Local: "query",
}} }}
router.Route(conn, iqDisco) router.route(conn, iqDisco)
if conn.String() != successFlag { if conn.String() != successFlag {
t.Errorf("IQ should have been matched and routed: %v", iqDisco) t.Errorf("IQ should have been matched and routed: %v", iqDisco)
} }
// Check that another namespace is not matched // Check that another namespace is not matched
conn = NewSenderMock() conn = NewSenderMock()
iqVersion := xmpp.NewIQ(xmpp.Attrs{Type: xmpp.IQTypeGet, To: "localhost", Id: "1"}) iqVersion := NewIQ(Attrs{Type: IQTypeGet, To: "localhost", Id: "1"})
// TODO: Add a function to generate payload with proper namespace initialisation // TODO: Add a function to generate payload with proper namespace initialisation
iqVersion.Payload = &xmpp.DiscoInfo{ iqVersion.Payload = &DiscoInfo{
XMLName: xml.Name{ XMLName: xml.Name{
Space: "jabber:iq:version", Space: "jabber:iq:version",
Local: "query", Local: "query",
}} }}
router.Route(conn, iqVersion) router.route(conn, iqVersion)
if conn.String() == successFlag { if conn.String() == successFlag {
t.Errorf("IQ should not have been matched and routed: %v", iqVersion) t.Errorf("IQ should not have been matched and routed: %v", iqVersion)
} }
} }
func TestTypeMatcher(t *testing.T) { func TestTypeMatcher(t *testing.T) {
router := xmpp.NewRouter() router := NewRouter()
router.NewRoute(). router.NewRoute().
StanzaType("normal"). StanzaType("normal").
HandlerFunc(func(s xmpp.Sender, p xmpp.Packet) { HandlerFunc(func(s Sender, p Packet) {
_ = s.SendRaw(successFlag) _ = s.SendRaw(successFlag)
}) })
// Check that a packet with the proper type matches // Check that a packet with the proper type matches
conn := NewSenderMock() conn := NewSenderMock()
message := xmpp.NewMessage(xmpp.Attrs{Type: "normal", To: "test@localhost", Id: "1"}) message := NewMessage(Attrs{Type: "normal", To: "test@localhost", Id: "1"})
message.Body = "hello" message.Body = "hello"
router.Route(conn, message) router.route(conn, message)
if conn.String() != successFlag { if conn.String() != successFlag {
t.Errorf("'normal' message should have been matched and routed: %v", message) t.Errorf("'normal' message should have been matched and routed: %v", message)
@ -93,9 +91,9 @@ func TestTypeMatcher(t *testing.T) {
// We should match on default type 'normal' for message without a type // We should match on default type 'normal' for message without a type
conn = NewSenderMock() conn = NewSenderMock()
message = xmpp.NewMessage(xmpp.Attrs{To: "test@localhost", Id: "1"}) message = NewMessage(Attrs{To: "test@localhost", Id: "1"})
message.Body = "hello" message.Body = "hello"
router.Route(conn, message) router.route(conn, message)
if conn.String() != successFlag { if conn.String() != successFlag {
t.Errorf("message should have been matched and routed: %v", message) t.Errorf("message should have been matched and routed: %v", message)
@ -103,13 +101,13 @@ func TestTypeMatcher(t *testing.T) {
// We do not match on other types // We do not match on other types
conn = NewSenderMock() conn = NewSenderMock()
iqVersion := xmpp.NewIQ(xmpp.Attrs{Type: "get", From: "service.localhost", To: "test@localhost", Id: "1"}) iqVersion := NewIQ(Attrs{Type: "get", From: "service.localhost", To: "test@localhost", Id: "1"})
iqVersion.Payload = &xmpp.DiscoInfo{ iqVersion.Payload = &DiscoInfo{
XMLName: xml.Name{ XMLName: xml.Name{
Space: "jabber:iq:version", Space: "jabber:iq:version",
Local: "query", Local: "query",
}} }}
router.Route(conn, iqVersion) router.route(conn, iqVersion)
if conn.String() == successFlag { if conn.String() == successFlag {
t.Errorf("iq get should not have been matched and routed: %v", iqVersion) t.Errorf("iq get should not have been matched and routed: %v", iqVersion)
@ -117,42 +115,42 @@ func TestTypeMatcher(t *testing.T) {
} }
func TestCompositeMatcher(t *testing.T) { func TestCompositeMatcher(t *testing.T) {
router := xmpp.NewRouter() router := NewRouter()
router.NewRoute(). router.NewRoute().
IQNamespaces("jabber:iq:version"). IQNamespaces("jabber:iq:version").
StanzaType("get"). StanzaType("get").
HandlerFunc(func(s xmpp.Sender, p xmpp.Packet) { HandlerFunc(func(s Sender, p Packet) {
_ = s.SendRaw(successFlag) _ = s.SendRaw(successFlag)
}) })
// Data set // Data set
getVersionIq := xmpp.NewIQ(xmpp.Attrs{Type: "get", From: "service.localhost", To: "test@localhost", Id: "1"}) getVersionIq := NewIQ(Attrs{Type: "get", From: "service.localhost", To: "test@localhost", Id: "1"})
getVersionIq.Payload = &xmpp.Version{ getVersionIq.Payload = &Version{
XMLName: xml.Name{ XMLName: xml.Name{
Space: "jabber:iq:version", Space: "jabber:iq:version",
Local: "query", Local: "query",
}} }}
setVersionIq := xmpp.NewIQ(xmpp.Attrs{Type: "set", From: "service.localhost", To: "test@localhost", Id: "1"}) setVersionIq := NewIQ(Attrs{Type: "set", From: "service.localhost", To: "test@localhost", Id: "1"})
setVersionIq.Payload = &xmpp.Version{ setVersionIq.Payload = &Version{
XMLName: xml.Name{ XMLName: xml.Name{
Space: "jabber:iq:version", Space: "jabber:iq:version",
Local: "query", Local: "query",
}} }}
GetDiscoIq := xmpp.NewIQ(xmpp.Attrs{Type: "get", From: "service.localhost", To: "test@localhost", Id: "1"}) GetDiscoIq := NewIQ(Attrs{Type: "get", From: "service.localhost", To: "test@localhost", Id: "1"})
GetDiscoIq.Payload = &xmpp.DiscoInfo{ GetDiscoIq.Payload = &DiscoInfo{
XMLName: xml.Name{ XMLName: xml.Name{
Space: "http://jabber.org/protocol/disco#info", Space: "http://jabber.org/protocol/disco#info",
Local: "query", Local: "query",
}} }}
message := xmpp.NewMessage(xmpp.Attrs{Type: "normal", To: "test@localhost", Id: "1"}) message := NewMessage(Attrs{Type: "normal", To: "test@localhost", Id: "1"})
message.Body = "hello" message.Body = "hello"
tests := []struct { tests := []struct {
name string name string
input xmpp.Packet input Packet
want bool want bool
}{ }{
{name: "match get version iq", input: getVersionIq, want: true}, {name: "match get version iq", input: getVersionIq, want: true},
@ -165,7 +163,7 @@ func TestCompositeMatcher(t *testing.T) {
for _, tc := range tests { for _, tc := range tests {
t.Run(tc.name, func(st *testing.T) { t.Run(tc.name, func(st *testing.T) {
conn := NewSenderMock() conn := NewSenderMock()
router.Route(conn, tc.input) router.route(conn, tc.input)
res := conn.String() == successFlag res := conn.String() == successFlag
if tc.want != res { if tc.want != res {
@ -178,30 +176,30 @@ func TestCompositeMatcher(t *testing.T) {
// A blank route with empty matcher will always match // A blank route with empty matcher will always match
// It can be use to receive all packets that do not match any of the previous route. // It can be use to receive all packets that do not match any of the previous route.
func TestCatchallMatcher(t *testing.T) { func TestCatchallMatcher(t *testing.T) {
router := xmpp.NewRouter() router := NewRouter()
router.NewRoute(). router.NewRoute().
HandlerFunc(func(s xmpp.Sender, p xmpp.Packet) { HandlerFunc(func(s Sender, p Packet) {
_ = s.SendRaw(successFlag) _ = s.SendRaw(successFlag)
}) })
// Check that we match on several packets // Check that we match on several packets
conn := NewSenderMock() conn := NewSenderMock()
message := xmpp.NewMessage(xmpp.Attrs{Type: "chat", To: "test@localhost", Id: "1"}) message := NewMessage(Attrs{Type: "chat", To: "test@localhost", Id: "1"})
message.Body = "hello" message.Body = "hello"
router.Route(conn, message) router.route(conn, message)
if conn.String() != successFlag { if conn.String() != successFlag {
t.Errorf("chat message should have been matched and routed: %v", message) t.Errorf("chat message should have been matched and routed: %v", message)
} }
conn = NewSenderMock() conn = NewSenderMock()
iqVersion := xmpp.NewIQ(xmpp.Attrs{Type: "get", From: "service.localhost", To: "test@localhost", Id: "1"}) iqVersion := NewIQ(Attrs{Type: "get", From: "service.localhost", To: "test@localhost", Id: "1"})
iqVersion.Payload = &xmpp.DiscoInfo{ iqVersion.Payload = &DiscoInfo{
XMLName: xml.Name{ XMLName: xml.Name{
Space: "jabber:iq:version", Space: "jabber:iq:version",
Local: "query", Local: "query",
}} }}
router.Route(conn, iqVersion) router.route(conn, iqVersion)
if conn.String() != successFlag { if conn.String() != successFlag {
t.Errorf("iq get should have been matched and routed: %v", iqVersion) t.Errorf("iq get should have been matched and routed: %v", iqVersion)
@ -221,7 +219,7 @@ func NewSenderMock() SenderMock {
return SenderMock{buffer: new(bytes.Buffer)} return SenderMock{buffer: new(bytes.Buffer)}
} }
func (s SenderMock) Send(packet xmpp.Packet) error { func (s SenderMock) Send(packet Packet) error {
out, err := xml.Marshal(packet) out, err := xml.Marshal(packet)
if err != nil { if err != nil {
return err return err
@ -241,7 +239,7 @@ func (s SenderMock) String() string {
func TestSenderMock(t *testing.T) { func TestSenderMock(t *testing.T) {
conn := NewSenderMock() conn := NewSenderMock()
msg := xmpp.NewMessage(xmpp.Attrs{To: "test@localhost", Id: "1"}) msg := NewMessage(Attrs{To: "test@localhost", Id: "1"})
msg.Body = "Hello" msg.Body = "Hello"
if err := conn.Send(msg); err != nil { if err := conn.Send(msg); err != nil {
t.Error("Could not send message") t.Error("Could not send message")

Loading…
Cancel
Save