blob: 3815ef8a509935dccc425124315c476dda6ccbd1 [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001/*
2 * Copyright 2011 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <string>
12
13#include "webrtc/libjingle/xmllite/qname.h"
14#include "webrtc/libjingle/xmllite/xmlelement.h"
15#include "webrtc/libjingle/xmpp/constants.h"
16#include "webrtc/libjingle/xmpp/fakexmppclient.h"
17#include "webrtc/libjingle/xmpp/jid.h"
18#include "webrtc/libjingle/xmpp/pubsubclient.h"
19#include "webrtc/base/faketaskrunner.h"
20#include "webrtc/base/gunit.h"
21#include "webrtc/base/sigslot.h"
22
23struct HandledPubSubItem {
24 std::string itemid;
25 std::string payload;
26};
27
28class TestPubSubItemsListener : public sigslot::has_slots<> {
29 public:
30 TestPubSubItemsListener() : error_count(0) {}
31
32 void OnItems(buzz::PubSubClient*,
33 const std::vector<buzz::PubSubItem>& items) {
34 for (std::vector<buzz::PubSubItem>::const_iterator item = items.begin();
35 item != items.end(); ++item) {
36 HandledPubSubItem handled_item;
37 handled_item.itemid = item->itemid;
38 if (item->elem->FirstElement() != NULL) {
39 handled_item.payload = item->elem->FirstElement()->Str();
40 }
41 this->items.push_back(handled_item);
42 }
43 }
44
45 void OnRequestError(buzz::PubSubClient* client,
46 const buzz::XmlElement* stanza) {
47 error_count++;
48 }
49
50 void OnPublishResult(buzz::PubSubClient* client,
51 const std::string& task_id,
52 const buzz::XmlElement* item) {
53 result_task_id = task_id;
54 }
55
56 void OnPublishError(buzz::PubSubClient* client,
57 const std::string& task_id,
58 const buzz::XmlElement* item,
59 const buzz::XmlElement* stanza) {
60 error_count++;
61 error_task_id = task_id;
62 }
63
64 void OnRetractResult(buzz::PubSubClient* client,
65 const std::string& task_id) {
66 result_task_id = task_id;
67 }
68
69 void OnRetractError(buzz::PubSubClient* client,
70 const std::string& task_id,
71 const buzz::XmlElement* stanza) {
72 error_count++;
73 error_task_id = task_id;
74 }
75
76 std::vector<HandledPubSubItem> items;
77 int error_count;
78 std::string error_task_id;
79 std::string result_task_id;
80};
81
82class PubSubClientTest : public testing::Test {
83 public:
84 PubSubClientTest() :
85 pubsubjid("room@domain.com"),
86 node("topic"),
87 itemid("key") {
88 runner.reset(new rtc::FakeTaskRunner());
89 xmpp_client = new buzz::FakeXmppClient(runner.get());
90 client.reset(new buzz::PubSubClient(xmpp_client, pubsubjid, node));
91 listener.reset(new TestPubSubItemsListener());
92 client->SignalItems.connect(
93 listener.get(), &TestPubSubItemsListener::OnItems);
94 client->SignalRequestError.connect(
95 listener.get(), &TestPubSubItemsListener::OnRequestError);
96 client->SignalPublishResult.connect(
97 listener.get(), &TestPubSubItemsListener::OnPublishResult);
98 client->SignalPublishError.connect(
99 listener.get(), &TestPubSubItemsListener::OnPublishError);
100 client->SignalRetractResult.connect(
101 listener.get(), &TestPubSubItemsListener::OnRetractResult);
102 client->SignalRetractError.connect(
103 listener.get(), &TestPubSubItemsListener::OnRetractError);
104 }
105
106 rtc::scoped_ptr<rtc::FakeTaskRunner> runner;
107 // xmpp_client deleted by deleting runner.
108 buzz::FakeXmppClient* xmpp_client;
109 rtc::scoped_ptr<buzz::PubSubClient> client;
110 rtc::scoped_ptr<TestPubSubItemsListener> listener;
111 buzz::Jid pubsubjid;
112 std::string node;
113 std::string itemid;
114};
115
116TEST_F(PubSubClientTest, TestRequest) {
117 client->RequestItems();
118
119 std::string expected_iq =
120 "<cli:iq type=\"get\" to=\"room@domain.com\" id=\"0\" "
121 "xmlns:cli=\"jabber:client\">"
122 "<pub:pubsub xmlns:pub=\"http://jabber.org/protocol/pubsub\">"
123 "<pub:items node=\"topic\"/>"
124 "</pub:pubsub>"
125 "</cli:iq>";
126
127 ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
128 EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
129
130 std::string result_iq =
131 "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'>"
132 " <pubsub xmlns='http://jabber.org/protocol/pubsub'>"
133 " <items node='topic'>"
134 " <item id='key0'>"
135 " <value0a/>"
136 " </item>"
137 " <item id='key1'>"
138 " <value1a/>"
139 " </item>"
140 " </items>"
141 " </pubsub>"
142 "</iq>";
143
144 xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
145 ASSERT_EQ(2U, listener->items.size());
146 EXPECT_EQ("key0", listener->items[0].itemid);
147 EXPECT_EQ("<pub:value0a xmlns:pub=\"http://jabber.org/protocol/pubsub\"/>",
148 listener->items[0].payload);
149 EXPECT_EQ("key1", listener->items[1].itemid);
150 EXPECT_EQ("<pub:value1a xmlns:pub=\"http://jabber.org/protocol/pubsub\"/>",
151 listener->items[1].payload);
152
153 std::string items_message =
154 "<message xmlns='jabber:client' from='room@domain.com'>"
155 " <event xmlns='http://jabber.org/protocol/pubsub#event'>"
156 " <items node='topic'>"
157 " <item id='key0'>"
158 " <value0b/>"
159 " </item>"
160 " <item id='key1'>"
161 " <value1b/>"
162 " </item>"
163 " </items>"
164 " </event>"
165 "</message>";
166
167 xmpp_client->HandleStanza(buzz::XmlElement::ForStr(items_message));
168 ASSERT_EQ(4U, listener->items.size());
169 EXPECT_EQ("key0", listener->items[2].itemid);
170 EXPECT_EQ("<eve:value0b"
171 " xmlns:eve=\"http://jabber.org/protocol/pubsub#event\"/>",
172 listener->items[2].payload);
173 EXPECT_EQ("key1", listener->items[3].itemid);
174 EXPECT_EQ("<eve:value1b"
175 " xmlns:eve=\"http://jabber.org/protocol/pubsub#event\"/>",
176 listener->items[3].payload);
177}
178
179TEST_F(PubSubClientTest, TestRequestError) {
180 std::string result_iq =
181 "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
182 " <error type='auth'>"
183 " <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
184 " </error>"
185 "</iq>";
186
187 client->RequestItems();
188 xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
189 EXPECT_EQ(1, listener->error_count);
190}
191
192TEST_F(PubSubClientTest, TestPublish) {
193 buzz::XmlElement* payload =
194 new buzz::XmlElement(buzz::QName(buzz::NS_PUBSUB, "value"));
195
196 std::string task_id;
197 client->PublishItem(itemid, payload, &task_id);
198
199 std::string expected_iq =
200 "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
201 "xmlns:cli=\"jabber:client\">"
202 "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
203 "<publish node=\"topic\">"
204 "<item id=\"key\">"
205 "<value/>"
206 "</item>"
207 "</publish>"
208 "</pubsub>"
209 "</cli:iq>";
210
211 ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
212 EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
213
214 std::string result_iq =
215 "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'/>";
216
217 xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
218 EXPECT_EQ(task_id, listener->result_task_id);
219}
220
221TEST_F(PubSubClientTest, TestPublishError) {
222 buzz::XmlElement* payload =
223 new buzz::XmlElement(buzz::QName(buzz::NS_PUBSUB, "value"));
224
225 std::string task_id;
226 client->PublishItem(itemid, payload, &task_id);
227
228 std::string result_iq =
229 "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
230 " <error type='auth'>"
231 " <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
232 " </error>"
233 "</iq>";
234
235 xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
236 EXPECT_EQ(1, listener->error_count);
237 EXPECT_EQ(task_id, listener->error_task_id);
238}
239
240TEST_F(PubSubClientTest, TestRetract) {
241 std::string task_id;
242 client->RetractItem(itemid, &task_id);
243
244 std::string expected_iq =
245 "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
246 "xmlns:cli=\"jabber:client\">"
247 "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
248 "<retract node=\"topic\" notify=\"true\">"
249 "<item id=\"key\"/>"
250 "</retract>"
251 "</pubsub>"
252 "</cli:iq>";
253
254 ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
255 EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
256
257 std::string result_iq =
258 "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'/>";
259
260 xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
261 EXPECT_EQ(task_id, listener->result_task_id);
262}
263
264TEST_F(PubSubClientTest, TestRetractError) {
265 std::string task_id;
266 client->RetractItem(itemid, &task_id);
267
268 std::string result_iq =
269 "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
270 " <error type='auth'>"
271 " <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
272 " </error>"
273 "</iq>";
274
275 xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
276 EXPECT_EQ(1, listener->error_count);
277 EXPECT_EQ(task_id, listener->error_task_id);
278}