~samwhited/xmpp

xmpp/stream/error_test.go -rw-r--r-- 5.7 KiB
60a076f3Sam Whited .builds: disable testing against gotip 4 days ago
                                                                                
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
168
// Copyright 2015 The Mellium Contributors.
// Use of this source code is governed by the BSD 2-clause
// license that can be found in the LICENSE file.

package stream_test

import (
	"encoding/xml"
	"errors"
	"fmt"
	"net"
	"testing"

	"mellium.im/xmlstream"
	"mellium.im/xmpp/stream"
)

var (
	_ error               = (*stream.Error)(nil)
	_ error               = stream.Error{}
	_ xml.Marshaler       = (*stream.Error)(nil)
	_ xml.Marshaler       = stream.Error{}
	_ xml.Unmarshaler     = (*stream.Error)(nil)
	_ xmlstream.Marshaler = (*stream.Error)(nil)
	_ xmlstream.WriterTo  = (*stream.Error)(nil)
)

func TestCompare(t *testing.T) {
	hostGoneApp := stream.HostGone.ApplicationError(xmlstream.Wrap(nil, xml.StartElement{}))
	if !errors.Is(stream.HostGone, hostGoneApp) {
		t.Errorf("did not expect adding application error to affect comparison")
	}
	if errors.Is(stream.HostGone, stream.BadNamespacePrefix) {
		t.Errorf("did not expect two errors with different names to be equivalent")
	}
	if !errors.Is(stream.HostGone, stream.Error{}) {
		t.Errorf("expected empty stream error to compare to any other stream error")
	}
}

var marshalTests = [...]struct {
	se  stream.Error
	xml string
	err bool
}{
	0: {
		// see-other-host errors should wrap IPv6 addresses in brackets.
		se:  stream.SeeOtherHostError(&net.IPAddr{IP: net.ParseIP("::1")}),
		xml: `<error xmlns="http://etherx.jabber.org/streams"><see-other-host xmlns="urn:ietf:params:xml:ns:xmpp-streams">[::1]</see-other-host></error>`,
		err: false,
	},
	1: {
		// see-other-host should not wrap IPv6 addresses in brackets if they are already wrapped.
		se:  stream.SeeOtherHostError(&net.TCPAddr{IP: net.ParseIP("::1"), Port: 5222}),
		xml: `<error xmlns="http://etherx.jabber.org/streams"><see-other-host xmlns="urn:ietf:params:xml:ns:xmpp-streams">[::1]:5222</see-other-host></error>`,
		err: false,
	},
	2: {
		// see-other-host should not mess with IPv4 addresses.
		se:  stream.SeeOtherHostError(&net.IPAddr{IP: net.ParseIP("127.0.0.1")}),
		xml: `<error xmlns="http://etherx.jabber.org/streams"><see-other-host xmlns="urn:ietf:params:xml:ns:xmpp-streams">127.0.0.1</see-other-host></error>`,
		err: false,
	},
	3: {
		se:  stream.UnsupportedEncoding.InnerXML(xmlstream.Token(xml.CharData("test"))),
		xml: `<error xmlns="http://etherx.jabber.org/streams"><unsupported-encoding xmlns="urn:ietf:params:xml:ns:xmpp-streams">test</unsupported-encoding></error>`,
	},
	4: {
		se:  stream.UnsupportedEncoding.ApplicationError(xmlstream.Token(xml.CharData("test"))),
		xml: `<error xmlns="http://etherx.jabber.org/streams"><unsupported-encoding xmlns="urn:ietf:params:xml:ns:xmpp-streams"></unsupported-encoding>test</error>`,
	},
	5: {
		se:  stream.UnsupportedEncoding.ApplicationError(xmlstream.Token(xml.CharData("test"))).InnerXML(xmlstream.Token(xml.CharData("foo"))),
		xml: `<error xmlns="http://etherx.jabber.org/streams"><unsupported-encoding xmlns="urn:ietf:params:xml:ns:xmpp-streams">foo</unsupported-encoding>test</error>`,
	},
	6: {
		se:  stream.UnsupportedEncoding.ApplicationError(xmlstream.Token(xml.CharData("test"))).InnerXML(xmlstream.Token(xml.CharData("foo"))),
		xml: `<error xmlns="http://etherx.jabber.org/streams"><unsupported-encoding xmlns="urn:ietf:params:xml:ns:xmpp-streams">foo</unsupported-encoding>test</error>`,
	},
	7: {
		se: stream.Error{Err: "undefined-condition", Text: []struct {
			Lang  string
			Value string
		}{{
			Lang:  "en",
			Value: "some value",
		}, {
			Value: "some error",
		}}},
		xml: `<error xmlns="http://etherx.jabber.org/streams"><undefined-condition xmlns="urn:ietf:params:xml:ns:xmpp-streams"></undefined-condition><text xmlns="urn:ietf:params:xml:ns:xmpp-streams" xml:lang="en">some value</text><text xmlns="urn:ietf:params:xml:ns:xmpp-streams">some error</text></error>`,
	},
}

func TestMarshal(t *testing.T) {
	for i, tc := range marshalTests {
		t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
			xb, err := xml.Marshal(tc.se)
			switch xbs := string(xb); {
			case tc.err && err == nil:
				t.Errorf("expected marshaling to fail")
				return
			case !tc.err && err != nil:
				t.Errorf("did not expect error, got=%v", err)
				return
			case err != nil:
				return
			case xbs != tc.xml:
				t.Errorf("bad output:\nwant=`%s`,\n got=`%s`", tc.xml, xbs)
			}
		})
	}
}

var unmarshalTests = [...]struct {
	xml string
	se  stream.Error
	err bool
}{
	0: {
		xml: `<stream:error><restricted-xml xmlns="urn:ietf:params:xml:ns:xmpp-streams"></restricted-xml></stream:error>`,
		se:  stream.RestrictedXML,
		err: false,
	},
	1: {
		xml: `<stream:error></a>`,
		se:  stream.RestrictedXML,
		err: true,
	},
	2: {
		xml: `<error xmlns="http://etherx.jabber.org/streams"><undefined-condition xmlns="urn:ietf:params:xml:ns:xmpp-streams"></undefined-condition><text xmlns="urn:ietf:params:xml:ns:xmpp-streams" xml:lang="en">some value</text><text xmlns="urn:ietf:params:xml:ns:xmpp-streams">some error</text></error>`,
		se: stream.Error{Err: "undefined-condition", Text: []struct {
			Lang  string
			Value string
		}{{
			Lang:  "en",
			Value: "some value",
		}, {
			Value: "some error",
		}}},
	},
}

func TestUnmarshal(t *testing.T) {
	for i, test := range unmarshalTests {
		t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
			s := stream.Error{}
			err := xml.Unmarshal([]byte(test.xml), &s)
			switch {
			case test.err && err == nil:
				t.Errorf("expected unmarshaling error for `%v` to fail", test.xml)
				return
			case !test.err && err != nil:
				t.Errorf("unexpected error: %v", err)
				return
			case err != nil:
				return
			case s.Err != test.se.Err:
				t.Errorf("expected Err `%#v` but got `%#v`", test.se, s)
			}
		})
	}
}

func TestErrorReturnsCondition(t *testing.T) {
	if stream.RestrictedXML.Error() != "restricted-xml" {
		t.Error("error should return the error condition")
	}
}