diff --git a/client.go b/client.go index bb62ce8..76de3de 100644 --- a/client.go +++ b/client.go @@ -210,13 +210,13 @@ func (c *Client) recv(keepaliveQuit chan<- struct{}) (err error) { // Handle stream errors switch packet := val.(type) { case StreamError: - c.router.Route(c, val) + c.router.route(c, val) close(keepaliveQuit) c.streamError(packet.Error.Local, packet.Text) return errors.New("stream error: " + packet.Error.Local) } - c.router.Route(c, val) + c.router.route(c, val) } } diff --git a/component.go b/component.go index 5fedc9a..eaea1d1 100644 --- a/component.go +++ b/component.go @@ -128,11 +128,11 @@ func (c *Component) recv() (err error) { // Handle stream errors switch p := val.(type) { case StreamError: - c.router.Route(c, val) + c.router.route(c, val) c.streamError(p.Error.Local, p.Text) return errors.New("stream error: " + p.Error.Local) } - c.router.Route(c, val) + c.router.route(c, val) } } diff --git a/router.go b/router.go index 79837a6..82b4a22 100644 --- a/router.go +++ b/router.go @@ -29,7 +29,9 @@ func NewRouter() *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 if r.Match(p, &match) { match.Handler.HandlePacket(s, p) diff --git a/router_test.go b/router_test.go index 7da1218..c1049bf 100644 --- a/router_test.go +++ b/router_test.go @@ -1,91 +1,89 @@ -package xmpp_test +package xmpp import ( "bytes" "encoding/xml" "testing" - - "gosrc.io/xmpp" ) // ============================================================================ // Test route & matchers func TestNameMatcher(t *testing.T) { - router := xmpp.NewRouter() - router.HandleFunc("message", func(s xmpp.Sender, p xmpp.Packet) { + router := NewRouter() + router.HandleFunc("message", func(s Sender, p Packet) { _ = s.SendRaw(successFlag) }) // Check that a message packet is properly matched 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" - router.Route(conn, msg) + router.route(conn, msg) if conn.String() != successFlag { t.Error("Message was not matched and routed properly") } // Check that an IQ packet is not matched conn = NewSenderMock() - iq := xmpp.NewIQ(xmpp.Attrs{Type: xmpp.IQTypeGet, To: "localhost", Id: "1"}) - iq.Payload = &xmpp.DiscoInfo{} - router.Route(conn, iq) + iq := NewIQ(Attrs{Type: IQTypeGet, To: "localhost", Id: "1"}) + iq.Payload = &DiscoInfo{} + router.route(conn, iq) if conn.String() == successFlag { t.Error("IQ should not have been matched and routed") } } func TestIQNSMatcher(t *testing.T) { - router := xmpp.NewRouter() + router := NewRouter() router.NewRoute(). - IQNamespaces(xmpp.NSDiscoInfo, xmpp.NSDiscoItems). - HandlerFunc(func(s xmpp.Sender, p xmpp.Packet) { + IQNamespaces(NSDiscoInfo, NSDiscoItems). + HandlerFunc(func(s Sender, p Packet) { _ = s.SendRaw(successFlag) }) // Check that an IQ with proper namespace does match 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 - iqDisco.Payload = &xmpp.DiscoInfo{ + iqDisco.Payload = &DiscoInfo{ XMLName: xml.Name{ - Space: xmpp.NSDiscoInfo, + Space: NSDiscoInfo, Local: "query", }} - router.Route(conn, iqDisco) + router.route(conn, iqDisco) if conn.String() != successFlag { t.Errorf("IQ should have been matched and routed: %v", iqDisco) } // Check that another namespace is not matched 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 - iqVersion.Payload = &xmpp.DiscoInfo{ + iqVersion.Payload = &DiscoInfo{ XMLName: xml.Name{ Space: "jabber:iq:version", Local: "query", }} - router.Route(conn, iqVersion) + router.route(conn, iqVersion) if conn.String() == successFlag { t.Errorf("IQ should not have been matched and routed: %v", iqVersion) } } func TestTypeMatcher(t *testing.T) { - router := xmpp.NewRouter() + router := NewRouter() router.NewRoute(). StanzaType("normal"). - HandlerFunc(func(s xmpp.Sender, p xmpp.Packet) { + HandlerFunc(func(s Sender, p Packet) { _ = s.SendRaw(successFlag) }) // Check that a packet with the proper type matches 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" - router.Route(conn, message) + router.route(conn, message) if conn.String() != successFlag { 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 conn = NewSenderMock() - message = xmpp.NewMessage(xmpp.Attrs{To: "test@localhost", Id: "1"}) + message = NewMessage(Attrs{To: "test@localhost", Id: "1"}) message.Body = "hello" - router.Route(conn, message) + router.route(conn, message) if conn.String() != successFlag { 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 conn = NewSenderMock() - iqVersion := xmpp.NewIQ(xmpp.Attrs{Type: "get", From: "service.localhost", To: "test@localhost", Id: "1"}) - iqVersion.Payload = &xmpp.DiscoInfo{ + iqVersion := NewIQ(Attrs{Type: "get", From: "service.localhost", To: "test@localhost", Id: "1"}) + iqVersion.Payload = &DiscoInfo{ XMLName: xml.Name{ Space: "jabber:iq:version", Local: "query", }} - router.Route(conn, iqVersion) + router.route(conn, iqVersion) if conn.String() == successFlag { 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) { - router := xmpp.NewRouter() + router := NewRouter() router.NewRoute(). IQNamespaces("jabber:iq:version"). StanzaType("get"). - HandlerFunc(func(s xmpp.Sender, p xmpp.Packet) { + HandlerFunc(func(s Sender, p Packet) { _ = s.SendRaw(successFlag) }) // Data set - getVersionIq := xmpp.NewIQ(xmpp.Attrs{Type: "get", From: "service.localhost", To: "test@localhost", Id: "1"}) - getVersionIq.Payload = &xmpp.Version{ + getVersionIq := NewIQ(Attrs{Type: "get", From: "service.localhost", To: "test@localhost", Id: "1"}) + getVersionIq.Payload = &Version{ XMLName: xml.Name{ Space: "jabber:iq:version", Local: "query", }} - setVersionIq := xmpp.NewIQ(xmpp.Attrs{Type: "set", From: "service.localhost", To: "test@localhost", Id: "1"}) - setVersionIq.Payload = &xmpp.Version{ + setVersionIq := NewIQ(Attrs{Type: "set", From: "service.localhost", To: "test@localhost", Id: "1"}) + setVersionIq.Payload = &Version{ XMLName: xml.Name{ Space: "jabber:iq:version", Local: "query", }} - GetDiscoIq := xmpp.NewIQ(xmpp.Attrs{Type: "get", From: "service.localhost", To: "test@localhost", Id: "1"}) - GetDiscoIq.Payload = &xmpp.DiscoInfo{ + GetDiscoIq := NewIQ(Attrs{Type: "get", From: "service.localhost", To: "test@localhost", Id: "1"}) + GetDiscoIq.Payload = &DiscoInfo{ XMLName: xml.Name{ Space: "http://jabber.org/protocol/disco#info", 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" tests := []struct { name string - input xmpp.Packet + input Packet want bool }{ {name: "match get version iq", input: getVersionIq, want: true}, @@ -165,7 +163,7 @@ func TestCompositeMatcher(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(st *testing.T) { conn := NewSenderMock() - router.Route(conn, tc.input) + router.route(conn, tc.input) res := conn.String() == successFlag if tc.want != res { @@ -178,30 +176,30 @@ func TestCompositeMatcher(t *testing.T) { // 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. func TestCatchallMatcher(t *testing.T) { - router := xmpp.NewRouter() + router := NewRouter() router.NewRoute(). - HandlerFunc(func(s xmpp.Sender, p xmpp.Packet) { + HandlerFunc(func(s Sender, p Packet) { _ = s.SendRaw(successFlag) }) // Check that we match on several packets 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" - router.Route(conn, message) + router.route(conn, message) if conn.String() != successFlag { t.Errorf("chat message should have been matched and routed: %v", message) } conn = NewSenderMock() - iqVersion := xmpp.NewIQ(xmpp.Attrs{Type: "get", From: "service.localhost", To: "test@localhost", Id: "1"}) - iqVersion.Payload = &xmpp.DiscoInfo{ + iqVersion := NewIQ(Attrs{Type: "get", From: "service.localhost", To: "test@localhost", Id: "1"}) + iqVersion.Payload = &DiscoInfo{ XMLName: xml.Name{ Space: "jabber:iq:version", Local: "query", }} - router.Route(conn, iqVersion) + router.route(conn, iqVersion) if conn.String() != successFlag { 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)} } -func (s SenderMock) Send(packet xmpp.Packet) error { +func (s SenderMock) Send(packet Packet) error { out, err := xml.Marshal(packet) if err != nil { return err @@ -241,7 +239,7 @@ func (s SenderMock) String() string { func TestSenderMock(t *testing.T) { conn := NewSenderMock() - msg := xmpp.NewMessage(xmpp.Attrs{To: "test@localhost", Id: "1"}) + msg := NewMessage(Attrs{To: "test@localhost", Id: "1"}) msg.Body = "Hello" if err := conn.Send(msg); err != nil { t.Error("Could not send message")