/* * Copyright 2004 The WebRTC Project Authors. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include <iostream> #include <sstream> #include <string> #include "webrtc/libjingle/xmllite/xmlelement.h" #include "webrtc/libjingle/xmpp/xmppstanzaparser.h" #include "webrtc/base/common.h" #include "webrtc/base/gunit.h" using buzz::QName; using buzz::XmlElement; using buzz::XmppStanzaParser; using buzz::XmppStanzaParseHandler; class XmppStanzaParserTestHandler : public XmppStanzaParseHandler { public: virtual void StartStream(const XmlElement * element) { ss_ << "START" << element->Str(); } virtual void Stanza(const XmlElement * element) { ss_ << "STANZA" << element->Str(); } virtual void EndStream() { ss_ << "END"; } virtual void XmlError() { ss_ << "ERROR"; } std::string Str() { return ss_.str(); } std::string StrClear() { std::string result = ss_.str(); ss_.str(""); return result; } private: std::stringstream ss_; }; TEST(XmppStanzaParserTest, TestTrivial) { XmppStanzaParserTestHandler handler; XmppStanzaParser parser(&handler); std::string fragment; fragment = "<trivial/>"; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("START<trivial/>END", handler.StrClear()); } TEST(XmppStanzaParserTest, TestStanzaAtATime) { XmppStanzaParserTestHandler handler; XmppStanzaParser parser(&handler); std::string fragment; fragment = "<stream:stream id='abc' xmlns='j:c' xmlns:stream='str'>"; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" " "xmlns:stream=\"str\"/>", handler.StrClear()); fragment = "<message type='foo'><body>hello</body></message>"; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("STANZA<c:message type=\"foo\" xmlns:c=\"j:c\">" "<c:body>hello</c:body></c:message>", handler.StrClear()); fragment = " SOME TEXT TO IGNORE "; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("", handler.StrClear()); fragment = "<iq type='set' id='123'><abc xmlns='def'/></iq>"; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("STANZA<c:iq type=\"set\" id=\"123\" xmlns:c=\"j:c\">" "<abc xmlns=\"def\"/></c:iq>", handler.StrClear()); fragment = "</stream:stream>"; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("END", handler.StrClear()); } TEST(XmppStanzaParserTest, TestFragmentedStanzas) { XmppStanzaParserTestHandler handler; XmppStanzaParser parser(&handler); std::string fragment; fragment = "<stream:stream id='abc' xmlns='j:c' xml"; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("", handler.StrClear()); fragment = "ns:stream='str'><message type='foo'><body>hel"; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" " "xmlns:stream=\"str\"/>", handler.StrClear()); fragment = "lo</body></message> IGNORE ME <iq type='set' id='123'>" "<abc xmlns='def'/></iq></st"; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("STANZA<c:message type=\"foo\" xmlns:c=\"j:c\">" "<c:body>hello</c:body></c:message>STANZA<c:iq type=\"set\" id=\"123\" " "xmlns:c=\"j:c\"><abc xmlns=\"def\"/></c:iq>", handler.StrClear()); fragment = "ream:stream>"; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("END", handler.StrClear()); } TEST(XmppStanzaParserTest, TestReset) { XmppStanzaParserTestHandler handler; XmppStanzaParser parser(&handler); std::string fragment; fragment = "<stream:stream id='abc' xmlns='j:c' xml"; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("", handler.StrClear()); parser.Reset(); fragment = "<stream:stream id='abc' xmlns='j:c' xml"; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("", handler.StrClear()); fragment = "ns:stream='str'><message type='foo'><body>hel"; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" " "xmlns:stream=\"str\"/>", handler.StrClear()); parser.Reset(); fragment = "<stream:stream id='abc' xmlns='j:c' xmlns:stream='str'>"; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" " "xmlns:stream=\"str\"/>", handler.StrClear()); fragment = "<message type='foo'><body>hello</body></message>"; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("STANZA<c:message type=\"foo\" xmlns:c=\"j:c\">" "<c:body>hello</c:body></c:message>", handler.StrClear()); } TEST(XmppStanzaParserTest, TestError) { XmppStanzaParserTestHandler handler; XmppStanzaParser parser(&handler); std::string fragment; fragment = "<-foobar/>"; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("ERROR", handler.StrClear()); parser.Reset(); fragment = "<stream:stream/>"; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("ERROR", handler.StrClear()); parser.Reset(); fragment = "ns:stream='str'><message type='foo'><body>hel"; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("ERROR", handler.StrClear()); parser.Reset(); fragment = "<stream:stream xmlns:stream='st' xmlns='jc'>" "<foo/><bar><st:foobar/></bar>"; parser.Parse(fragment.c_str(), fragment.length(), false); EXPECT_EQ("START<stream:stream xmlns:stream=\"st\" xmlns=\"jc\"/>STANZA" "<jc:foo xmlns:jc=\"jc\"/>ERROR", handler.StrClear()); }