1package xmpp 2 3import ( 4 "encoding/xml" 5 "errors" 6 7 "github.com/coyim/coyim/xmpp/data" 8 9 . "gopkg.in/check.v1" 10) 11 12type StreamsXMPPSuite struct{} 13 14var _ = Suite(&StreamsXMPPSuite{}) 15 16func (s *StreamsXMPPSuite) Test_sendInitialStreamHeader_returnsErrorIfSomethingGoesWrongWithFmtPrintf(c *C) { 17 conn := conn{ 18 out: &mockConnIOReaderWriter{err: errors.New("Hello")}, 19 originDomain: "foo.com", 20 } 21 22 err := conn.SendInitialStreamHeader() 23 c.Assert(err, Not(IsNil)) 24} 25 26func (s *StreamsXMPPSuite) Test_sendInitialStreamHeader_returnsErrorIfSomethingGoesWrongWithReadingAStream(c *C) { 27 mockIn := &mockConnIOReaderWriter{err: errors.New("Hello")} 28 conn := conn{ 29 out: &mockConnIOReaderWriter{}, 30 in: xml.NewDecoder(mockIn), 31 originDomain: "foo.com", 32 } 33 34 err := conn.SendInitialStreamHeader() 35 c.Assert(err, Not(IsNil)) 36} 37 38func (s *StreamsXMPPSuite) Test_sendInitialStreamHeader_sendsInitialStreamHeaderToOutput(c *C) { 39 mockOut := &mockConnIOReaderWriter{} 40 mockIn := &mockConnIOReaderWriter{err: errors.New("Hello")} 41 conn := conn{ 42 out: mockOut, 43 in: xml.NewDecoder(mockIn), 44 originDomain: "somewhere.org", 45 } 46 conn.SendInitialStreamHeader() 47 c.Assert(string(mockOut.write), Equals, "<?xml version='1.0'?><stream:stream to='somewhere.org' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>\n") 48} 49 50func (s *StreamsXMPPSuite) Test_sendInitialStreamHeader_expectsResponseStreamHeaderInReturn(c *C) { 51 mockOut := &mockConnIOReaderWriter{} 52 mockIn := &mockConnIOReaderWriter{read: []byte("<?xml version='1.0'?><stream:stream xmlns:stream='http://etherx.jabber.org/streams' version='1.0'></stream:stream>")} 53 conn := conn{ 54 out: mockOut, 55 in: xml.NewDecoder(mockIn), 56 originDomain: "somewhereElse.org", 57 } 58 59 err := conn.SendInitialStreamHeader() 60 c.Assert(err.Error(), Equals, "xmpp: error to unmarshal <features>: EOF") 61} 62 63func (s *StreamsXMPPSuite) Test_sendInitialStreamHeader_failsIfReturnedStreamIsNotCorrectNamespace(c *C) { 64 mockOut := &mockConnIOReaderWriter{} 65 mockIn := &mockConnIOReaderWriter{read: []byte("<?xml version='1.0'?><str:stream xmlns:str='http://etherx.jabber.org/streams2' version='1.0'>")} 66 conn := conn{ 67 out: mockOut, 68 in: xml.NewDecoder(mockIn), 69 originDomain: "somewhereElse.org", 70 } 71 72 err := conn.SendInitialStreamHeader() 73 c.Assert(err.Error(), Equals, "xmpp: expected <stream> but got <stream> in http://etherx.jabber.org/streams2") 74} 75 76func (s *StreamsXMPPSuite) Test_sendInitialStreamHeader_failsIfReturnedElementIsNotStream(c *C) { 77 mockOut := &mockConnIOReaderWriter{} 78 mockIn := &mockConnIOReaderWriter{read: []byte("<?xml version='1.0'?><str:feature xmlns:str='http://etherx.jabber.org/streams' version='1.0'>")} 79 conn := conn{ 80 out: mockOut, 81 in: xml.NewDecoder(mockIn), 82 originDomain: "somewhereElse.org", 83 } 84 85 err := conn.SendInitialStreamHeader() 86 c.Assert(err.Error(), Equals, "xmpp: expected <stream> but got <feature> in http://etherx.jabber.org/streams") 87} 88 89func (s *StreamsXMPPSuite) Test_sendInitialStreamHeader_expectsFeaturesInReturn(c *C) { 90 mockOut := &mockConnIOReaderWriter{} 91 mockIn := &mockConnIOReaderWriter{read: []byte("<?xml version='1.0'?><str:stream xmlns:str='http://etherx.jabber.org/streams' version='1.0'><str:features></str:features>")} 92 conn := conn{ 93 out: mockOut, 94 in: xml.NewDecoder(mockIn), 95 originDomain: "somewhereElse.org", 96 } 97 98 err := conn.SendInitialStreamHeader() 99 c.Assert(err, IsNil) 100 expected := data.StreamFeatures{} 101 expected.XMLName = xml.Name{Space: "http://etherx.jabber.org/streams", Local: "features"} 102 c.Assert(conn.features, DeepEquals, expected) 103} 104 105func (s *StreamsXMPPSuite) Test_sendInitialStreamHeader_receiveResponseStreamHeaderInReturn(c *C) { 106 mockOut := &mockConnIOReaderWriter{} 107 mockIn := &mockConnIOReaderWriter{read: []byte(` 108 <?xml version='1.0'?> 109 <str:stream xmlns:str='http://etherx.jabber.org/streams' version='1.0'> 110 <str:features> 111 <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind' /> 112 <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'> 113 <required/> 114 </starttls> 115 <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> 116 <mechanism>PLAIN</mechanism> 117 <mechanism>X-OAUTH2</mechanism> 118 <mechanism>X-GOOGLE-TOKEN</mechanism> 119 </mechanisms> 120 <register xmlns='http://jabber.org/features/iq-register'/> 121 </str:features> 122 `)} 123 conn := conn{ 124 out: mockOut, 125 in: xml.NewDecoder(mockIn), 126 originDomain: "somewhereElse.org", 127 } 128 129 err := conn.SendInitialStreamHeader() 130 c.Assert(err, IsNil) 131 expected := data.StreamFeatures{ 132 XMLName: xml.Name{Space: "http://etherx.jabber.org/streams", Local: "features"}, 133 Bind: data.BindBind{ 134 XMLName: xml.Name{Space: "urn:ietf:params:xml:ns:xmpp-bind", Local: "bind"}, Resource: "", Jid: "", 135 }, 136 StartTLS: data.StartTLS{ 137 XMLName: xml.Name{Space: "urn:ietf:params:xml:ns:xmpp-tls", Local: "starttls"}, 138 Required: xml.Name{Space: "urn:ietf:params:xml:ns:xmpp-tls", Local: "required"}, 139 }, 140 Mechanisms: data.SaslMechanisms{ 141 XMLName: xml.Name{Space: "urn:ietf:params:xml:ns:xmpp-sasl", Local: "mechanisms"}, 142 Mechanism: []string{"PLAIN", "X-OAUTH2", "X-GOOGLE-TOKEN"}, 143 }, 144 InBandRegistration: &data.InBandRegistration{ 145 XMLName: xml.Name{Space: "http://jabber.org/features/iq-register", Local: "register"}, 146 }, 147 } 148 149 c.Assert(conn.features, DeepEquals, expected) 150} 151