~samwhited/xmpp

e171a2b53a42def71901874e991373d884500c9d — Sam Whited 5 years ago b95f457
Make IQ types unmarshalable (and add tests)
2 files changed, 54 insertions(+), 2 deletions(-)

M iq.go
M iq_test.go
M iq.go => iq.go +20 -2
@@ 7,6 7,7 @@ package xmpp
import (
	"context"
	"encoding/xml"
	"errors"
	"strings"

	"mellium.im/xmpp/jid"


@@ 17,10 18,10 @@ import (
// response in the form of a result or an error.
type IQ struct {
	From     *jid.JID `xml:"from,attr"`
	To       *jid.JID `xml:"to,attr"`
	ID       string   `xml:"id,attr"`
	InnerXML []byte   `xml:",innerxml"`
	Lang     string   `xml:"http://www.w3.org/XML/1998/namespace lang,attr,omitempty"`
	To       *jid.JID `xml:"to,attr"`
	InnerXML []byte   `xml:",innerxml"`
	Type     iqType   `xml:"type,attr"`
	XMLName  xml.Name `xml:"iq"`
}


@@ 47,6 48,23 @@ func (t iqType) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
	return xml.Attr{Name: name, Value: strings.ToLower(t.String())}, nil
}

func (t *iqType) UnmarshalXMLAttr(attr xml.Attr) error {
	switch attr.Value {
	case "get":
		*t = Get
	case "set":
		*t = Set
	case "result":
		*t = Result
	case "error":
		*t = Error
	default:
		// TODO: This should be a stanza error with the bad-request condition.
		return errors.New("bad-request")
	}
	return nil
}

// TODO: Should this be variadic and accept many payloads or many to's?
func (c *Conn) sendIQ(ctx context.Context, to *jid.JID, t iqType, v interface{}) (*IQ, error) {
	panic("xmpp: sendIQ not yet implemented")

M iq_test.go => iq_test.go +34 -0
@@ 9,6 9,12 @@ import (
	"testing"
)

var (
	_ xml.MarshalerAttr   = (*iqType)(nil)
	_ xml.MarshalerAttr   = Get
	_ xml.UnmarshalerAttr = (*iqType)(nil)
)

func TestMarshalIQTypeAttr(t *testing.T) {
	n := xml.Name{Space: "space", Local: "type"}
	for _, test := range []struct {


@@ 28,3 34,31 @@ func TestMarshalIQTypeAttr(t *testing.T) {
		}
	}
}

func TestUnmarshalIQTypeAttr(t *testing.T) {
	for _, test := range []struct {
		attr   xml.Attr
		iqtype iqType
		err    bool
	}{
		{xml.Attr{Name: xml.Name{}, Value: "get"}, Get, false},
		{xml.Attr{Name: xml.Name{Space: "", Local: "type"}, Value: "set"}, Set, false},
		{xml.Attr{Name: xml.Name{Space: "urn", Local: "loc"}, Value: "result"}, Result, false},
		{xml.Attr{Name: xml.Name{}, Value: "error"}, Error, false},
		{xml.Attr{Name: xml.Name{}, Value: "stuff"}, Error, true},
	} {
		iqtype := iqType(0)
		switch err := (&iqtype).UnmarshalXMLAttr(test.attr); {
		case test.err && err == nil:
			t.Error("Expected unmarshaling IQ type to error")
			continue
		case !test.err && err != nil:
			t.Error(err)
			continue
		case test.err && err != nil:
			continue
		case iqtype != test.iqtype:
			t.Errorf("Expected attr %+v to unmarshal into %s type IQ but got %s", test.attr, test.iqtype, iqtype)
		}
	}
}