1package xmpp
2
3import (
4	"errors"
5	"io"
6	"reflect"
7
8	"github.com/coyim/coyim/xmpp/data"
9
10	. "gopkg.in/check.v1"
11)
12
13type IqXMPPSuite struct{}
14
15var _ = Suite(&IqXMPPSuite{})
16
17func (s *IqXMPPSuite) Test_SendIQReply_returnsErrorIfOneIsEncounteredWhenWriting(c *C) {
18	mockIn := &mockConnIOReaderWriter{err: errors.New("some error")}
19	conn := conn{
20		out: mockIn,
21		jid: "somewhat@foo.com/somewhere",
22	}
23
24	err := conn.SendIQReply("fo", "bar", "baz", nil)
25	c.Assert(err.Error(), Equals, "some error")
26}
27
28func (s *IqXMPPSuite) Test_SendIQReply_writesAnEmptyReplyIfEmptyIsGiven(c *C) {
29	mockIn := &mockConnIOReaderWriter{}
30	conn := conn{
31		out: mockIn,
32		jid: "som'ewhat@foo.com/somewhere",
33	}
34
35	err := conn.SendIQReply("f&o", "b\"ar", "b<az", data.EmptyReply{})
36	c.Assert(err, IsNil)
37	c.Assert(string(mockIn.write), Equals, "<iq to='f&amp;o' from='som&apos;ewhat@foo.com/somewhere' type='b&quot;ar' id='b&lt;az'></iq>")
38}
39
40func (s *IqXMPPSuite) Test_SendIQReply_returnsErrorIfAnUnXMLableEntryIsGiven(c *C) {
41	mockIn := &mockConnIOReaderWriter{}
42	conn := conn{
43		out: mockIn,
44		jid: "som'ewhat@foo.com/somewhere",
45	}
46	err := conn.SendIQReply("f&o", "b\"ar", "b<az", func() int { return 42 })
47	c.Assert(err.Error(), Equals, "xml: unsupported type: func() int")
48}
49
50func (s *IqXMPPSuite) Test_SendIQ_returnsErrorIfWritingDataFails(c *C) {
51	mockIn := &mockConnIOReaderWriter{err: errors.New("this also fails")}
52	conn := conn{
53		out: mockIn,
54		jid: "som'ewhat@foo.com/somewhere",
55	}
56	_, _, err := conn.SendIQ("", "", nil)
57	c.Assert(err.Error(), Equals, "this also fails")
58}
59
60func (s *IqXMPPSuite) Test_Send_returnsErrorIfAnUnXMLableEntryIsGiven(c *C) {
61	mockIn := &mockConnIOReaderWriter{}
62	conn := conn{
63		out: mockIn,
64		jid: "som'ewhat@foo.com/somewhere",
65	}
66	_, _, err := conn.SendIQ("", "", func() int { return 42 })
67	c.Assert(err.Error(), Equals, "xml: unsupported type: func() int")
68}
69
70func (s *IqXMPPSuite) Test_SendIQ_returnsErrorIfWritingDataFailsTheSecondTime(c *C) {
71	mockIn := &mockConnIOReaderWriter{err: errors.New("this also fails again"), errCount: 1}
72	conn := conn{
73		out: mockIn,
74		jid: "som'ewhat@foo.com/somewhere",
75	}
76	_, _, err := conn.SendIQ("", "", nil)
77	c.Assert(err.Error(), Equals, "this also fails again")
78	c.Assert(string(mockIn.write), Matches, "<iq xmlns='jabber:client'  from='som&apos;ewhat@foo.com/somewhere' type='' id='.+'></iq>")
79}
80
81func (s *IqXMPPSuite) TestConnSendIQReplyAndTyp(c *C) {
82	mockOut := mockConnIOReaderWriter{}
83	conn := conn{
84		out: &mockOut,
85		jid: "jid",
86	}
87	conn.inflights = make(map[data.Cookie]inflight)
88	reply, cookie, err := conn.SendIQ("example@xmpp.com", "typ", nil)
89	c.Assert(string(mockOut.write), Matches, "<iq xmlns='jabber:client' to='example@xmpp.com' from='jid' type='typ' id='.+'></iq>")
90	c.Assert(reply, NotNil)
91	c.Assert(cookie, NotNil)
92	c.Assert(err, IsNil)
93}
94
95func (s *IqXMPPSuite) TestConnSendIQRaw(c *C) {
96	mockOut := mockConnIOReaderWriter{}
97	conn := conn{
98		out: &mockOut,
99		jid: "jid",
100	}
101
102	conn.inflights = make(map[data.Cookie]inflight)
103	reply, cookie, err := conn.SendIQ("example@xmpp.com", "typ", rawXML("<foo param='bar' />"))
104	c.Assert(string(mockOut.write), Matches, "<iq xmlns='jabber:client' to='example@xmpp.com' from='jid' type='typ' id='.*'><foo param='bar' /></iq>")
105	c.Assert(reply, NotNil)
106	c.Assert(cookie, NotNil)
107	c.Assert(err, IsNil)
108}
109
110func (s *IqXMPPSuite) TestConnSendIQErr(c *C) {
111	mockOut := mockConnIOReaderWriter{err: io.EOF}
112	conn := conn{
113		out: &mockOut,
114		jid: "jid",
115	}
116	reply, cookie, err := conn.SendIQ("example@xmpp.com", "typ", nil)
117	c.Assert(string(mockOut.write), Matches, "<iq xmlns='jabber:client' to='example@xmpp.com' from='jid' type='typ' id='.*'>$")
118	c.Assert(reply, IsNil)
119	c.Assert(cookie, Equals, data.Cookie(0))
120	c.Assert(err, Equals, io.EOF)
121}
122
123func (s *IqXMPPSuite) TestConnSendIQEmptyReply(c *C) {
124	mockOut := mockConnIOReaderWriter{}
125	conn := conn{
126		out: &mockOut,
127		jid: "jid",
128	}
129	conn.inflights = make(map[data.Cookie]inflight)
130	reply, cookie, err := conn.SendIQ("example@xmpp.com", "typ", reflect.ValueOf(data.EmptyReply{}))
131	c.Assert(string(mockOut.write), Matches, "<iq xmlns='jabber:client' to='example@xmpp.com' from='jid' type='typ' id='.+'><Value><flag>153</flag></Value></iq>")
132	c.Assert(reply, NotNil)
133	c.Assert(cookie, NotNil)
134	c.Assert(err, IsNil)
135}
136
137func (s *IqXMPPSuite) TestConnSendIQReply(c *C) {
138	mockOut := mockConnIOReaderWriter{}
139	conn := conn{
140		out: &mockOut,
141		jid: "jid",
142	}
143	err := conn.SendIQReply("example@xmpp.com", "typ", "id", nil)
144	c.Assert(string(mockOut.write), Matches, "<iq to='example@xmpp.com' from='jid' type='typ' id='id'></iq>")
145	c.Assert(err, IsNil)
146}
147