1// Copyright 2004 Google Inc. All Rights Reserved
2
3
4#include <iostream>
5#include <sstream>
6#include <string>
7#include "webrtc/libjingle/xmllite/xmlelement.h"
8#include "talk/xmpp/xmppstanzaparser.h"
9#include "webrtc/base/common.h"
10#include "webrtc/base/gunit.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