1// Copyright 2004 Google Inc. All Rights Reserved 2 3 4#include <string> 5#include <sstream> 6#include <iostream> 7#include "talk/base/common.h" 8#include "talk/base/gunit.h" 9#include "talk/xmllite/xmlelement.h" 10#include "talk/xmpp/xmppstanzaparser.h" 11 12using buzz::QName; 13using buzz::XmlElement; 14using buzz::XmppStanzaParser; 15using buzz::XmppStanzaParseHandler; 16 17class XmppStanzaParserTestHandler : public XmppStanzaParseHandler { 18 public: 19 virtual void StartStream(const XmlElement * element) { 20 ss_ << "START" << element->Str(); 21 } 22 virtual void Stanza(const XmlElement * element) { 23 ss_ << "STANZA" << element->Str(); 24 } 25 virtual void EndStream() { 26 ss_ << "END"; 27 } 28 virtual void XmlError() { 29 ss_ << "ERROR"; 30 } 31 32 std::string Str() { 33 return ss_.str(); 34 } 35 36 std::string StrClear() { 37 std::string result = ss_.str(); 38 ss_.str(""); 39 return result; 40 } 41 42 private: 43 std::stringstream ss_; 44}; 45 46 47TEST(XmppStanzaParserTest, TestTrivial) { 48 XmppStanzaParserTestHandler handler; 49 XmppStanzaParser parser(&handler); 50 std::string fragment; 51 52 fragment = "<trivial/>"; 53 parser.Parse(fragment.c_str(), fragment.length(), false); 54 EXPECT_EQ("START<trivial/>END", handler.StrClear()); 55} 56 57TEST(XmppStanzaParserTest, TestStanzaAtATime) { 58 XmppStanzaParserTestHandler handler; 59 XmppStanzaParser parser(&handler); 60 std::string fragment; 61 62 fragment = "<stream:stream id='abc' xmlns='j:c' xmlns:stream='str'>"; 63 parser.Parse(fragment.c_str(), fragment.length(), false); 64 EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" " 65 "xmlns:stream=\"str\"/>", handler.StrClear()); 66 67 fragment = "<message type='foo'><body>hello</body></message>"; 68 parser.Parse(fragment.c_str(), fragment.length(), false); 69 EXPECT_EQ("STANZA<c:message type=\"foo\" xmlns:c=\"j:c\">" 70 "<c:body>hello</c:body></c:message>", handler.StrClear()); 71 72 fragment = " SOME TEXT TO IGNORE "; 73 parser.Parse(fragment.c_str(), fragment.length(), false); 74 EXPECT_EQ("", handler.StrClear()); 75 76 fragment = "<iq type='set' id='123'><abc xmlns='def'/></iq>"; 77 parser.Parse(fragment.c_str(), fragment.length(), false); 78 EXPECT_EQ("STANZA<c:iq type=\"set\" id=\"123\" xmlns:c=\"j:c\">" 79 "<abc xmlns=\"def\"/></c:iq>", handler.StrClear()); 80 81 fragment = "</stream:stream>"; 82 parser.Parse(fragment.c_str(), fragment.length(), false); 83 EXPECT_EQ("END", handler.StrClear()); 84} 85 86TEST(XmppStanzaParserTest, TestFragmentedStanzas) { 87 XmppStanzaParserTestHandler handler; 88 XmppStanzaParser parser(&handler); 89 std::string fragment; 90 91 fragment = "<stream:stream id='abc' xmlns='j:c' xml"; 92 parser.Parse(fragment.c_str(), fragment.length(), false); 93 EXPECT_EQ("", handler.StrClear()); 94 95 fragment = "ns:stream='str'><message type='foo'><body>hel"; 96 parser.Parse(fragment.c_str(), fragment.length(), false); 97 EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" " 98 "xmlns:stream=\"str\"/>", handler.StrClear()); 99 100 fragment = "lo</body></message> IGNORE ME <iq type='set' id='123'>" 101 "<abc xmlns='def'/></iq></st"; 102 parser.Parse(fragment.c_str(), fragment.length(), false); 103 EXPECT_EQ("STANZA<c:message type=\"foo\" xmlns:c=\"j:c\">" 104 "<c:body>hello</c:body></c:message>STANZA<c:iq type=\"set\" id=\"123\" " 105 "xmlns:c=\"j:c\"><abc xmlns=\"def\"/></c:iq>", handler.StrClear()); 106 107 fragment = "ream:stream>"; 108 parser.Parse(fragment.c_str(), fragment.length(), false); 109 EXPECT_EQ("END", handler.StrClear()); 110} 111 112TEST(XmppStanzaParserTest, TestReset) { 113 XmppStanzaParserTestHandler handler; 114 XmppStanzaParser parser(&handler); 115 std::string fragment; 116 117 fragment = "<stream:stream id='abc' xmlns='j:c' xml"; 118 parser.Parse(fragment.c_str(), fragment.length(), false); 119 EXPECT_EQ("", handler.StrClear()); 120 121 parser.Reset(); 122 fragment = "<stream:stream id='abc' xmlns='j:c' xml"; 123 parser.Parse(fragment.c_str(), fragment.length(), false); 124 EXPECT_EQ("", handler.StrClear()); 125 126 fragment = "ns:stream='str'><message type='foo'><body>hel"; 127 parser.Parse(fragment.c_str(), fragment.length(), false); 128 EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" " 129 "xmlns:stream=\"str\"/>", handler.StrClear()); 130 parser.Reset(); 131 132 fragment = "<stream:stream id='abc' xmlns='j:c' xmlns:stream='str'>"; 133 parser.Parse(fragment.c_str(), fragment.length(), false); 134 EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" " 135 "xmlns:stream=\"str\"/>", handler.StrClear()); 136 137 fragment = "<message type='foo'><body>hello</body></message>"; 138 parser.Parse(fragment.c_str(), fragment.length(), false); 139 EXPECT_EQ("STANZA<c:message type=\"foo\" xmlns:c=\"j:c\">" 140 "<c:body>hello</c:body></c:message>", handler.StrClear()); 141} 142 143TEST(XmppStanzaParserTest, TestError) { 144 XmppStanzaParserTestHandler handler; 145 XmppStanzaParser parser(&handler); 146 std::string fragment; 147 148 fragment = "<-foobar/>"; 149 parser.Parse(fragment.c_str(), fragment.length(), false); 150 EXPECT_EQ("ERROR", handler.StrClear()); 151 152 parser.Reset(); 153 fragment = "<stream:stream/>"; 154 parser.Parse(fragment.c_str(), fragment.length(), false); 155 EXPECT_EQ("ERROR", handler.StrClear()); 156 parser.Reset(); 157 158 fragment = "ns:stream='str'><message type='foo'><body>hel"; 159 parser.Parse(fragment.c_str(), fragment.length(), false); 160 EXPECT_EQ("ERROR", handler.StrClear()); 161 parser.Reset(); 162 163 fragment = "<stream:stream xmlns:stream='st' xmlns='jc'>" 164 "<foo/><bar><st:foobar/></bar>"; 165 parser.Parse(fragment.c_str(), fragment.length(), false); 166 EXPECT_EQ("START<stream:stream xmlns:stream=\"st\" xmlns=\"jc\"/>STANZA" 167 "<jc:foo xmlns:jc=\"jc\"/>ERROR", handler.StrClear()); 168} 169