blob: 8062e58e18f4cb9933b9af380f400c51f47ac011 [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/iqtask.h"
18#include "webrtc/libjingle/xmpp/jid.h"
19#include "webrtc/libjingle/xmpp/pubsubtasks.h"
20#include "webrtc/base/faketaskrunner.h"
21#include "webrtc/base/gunit.h"
22#include "webrtc/base/sigslot.h"
23
24struct HandledPubSubItem {
25 std::string itemid;
26 std::string payload;
27};
28
29class TestPubSubTasksListener : public sigslot::has_slots<> {
30 public:
31 TestPubSubTasksListener() : result_count(0), error_count(0) {}
32
33 void OnReceiveUpdate(buzz::PubSubReceiveTask* task,
34 const std::vector<buzz::PubSubItem>& items) {
35 OnItems(items);
36 }
37
38 void OnRequestResult(buzz::PubSubRequestTask* task,
39 const std::vector<buzz::PubSubItem>& items) {
40 OnItems(items);
41 }
42
43 void OnItems(const std::vector<buzz::PubSubItem>& items) {
44 for (std::vector<buzz::PubSubItem>::const_iterator item = items.begin();
45 item != items.end(); ++item) {
46 HandledPubSubItem handled_item;
47 handled_item.itemid = item->itemid;
48 if (item->elem->FirstElement() != NULL) {
49 handled_item.payload = item->elem->FirstElement()->Str();
50 }
51 this->items.push_back(handled_item);
52 }
53 }
54
55 void OnPublishResult(buzz::PubSubPublishTask* task) {
56 ++result_count;
57 }
58
59 void OnRetractResult(buzz::PubSubRetractTask* task) {
60 ++result_count;
61 }
62
63 void OnError(buzz::IqTask* task, const buzz::XmlElement* stanza) {
64 ++error_count;
65 }
66
67 std::vector<HandledPubSubItem> items;
68 int result_count;
69 int error_count;
70};
71
72class PubSubTasksTest : public testing::Test {
73 public:
74 PubSubTasksTest() :
75 pubsubjid("room@domain.com"),
76 node("topic"),
77 itemid("key") {
78 runner.reset(new rtc::FakeTaskRunner());
79 client = new buzz::FakeXmppClient(runner.get());
80 listener.reset(new TestPubSubTasksListener());
81 }
82
83 rtc::scoped_ptr<rtc::FakeTaskRunner> runner;
84 // Client deleted by deleting runner.
85 buzz::FakeXmppClient* client;
86 rtc::scoped_ptr<TestPubSubTasksListener> listener;
87 buzz::Jid pubsubjid;
88 std::string node;
89 std::string itemid;
90};
91
92TEST_F(PubSubTasksTest, TestRequest) {
93 buzz::PubSubRequestTask* task =
94 new buzz::PubSubRequestTask(client, pubsubjid, node);
95 task->SignalResult.connect(
96 listener.get(), &TestPubSubTasksListener::OnRequestResult);
97 task->Start();
98
99 std::string expected_iq =
100 "<cli:iq type=\"get\" to=\"room@domain.com\" id=\"0\" "
101 "xmlns:cli=\"jabber:client\">"
102 "<pub:pubsub xmlns:pub=\"http://jabber.org/protocol/pubsub\">"
103 "<pub:items node=\"topic\"/>"
104 "</pub:pubsub>"
105 "</cli:iq>";
106
107 ASSERT_EQ(1U, client->sent_stanzas().size());
108 EXPECT_EQ(expected_iq, client->sent_stanzas()[0]->Str());
109
110 std::string result_iq =
111 "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'>"
112 " <pubsub xmlns='http://jabber.org/protocol/pubsub'>"
113 " <items node='topic'>"
114 " <item id='key0'>"
115 " <value0/>"
116 " </item>"
117 " <item id='key1'>"
118 " <value1/>"
119 " </item>"
120 " </items>"
121 " </pubsub>"
122 "</iq>";
123
124 client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
125
126 ASSERT_EQ(2U, listener->items.size());
127 EXPECT_EQ("key0", listener->items[0].itemid);
128 EXPECT_EQ("<pub:value0 xmlns:pub=\"http://jabber.org/protocol/pubsub\"/>",
129 listener->items[0].payload);
130 EXPECT_EQ("key1", listener->items[1].itemid);
131 EXPECT_EQ("<pub:value1 xmlns:pub=\"http://jabber.org/protocol/pubsub\"/>",
132 listener->items[1].payload);
133}
134
135TEST_F(PubSubTasksTest, TestRequestError) {
136 std::string result_iq =
137 "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
138 " <error type='auth'>"
139 " <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
140 " </error>"
141 "</iq>";
142
143 buzz::PubSubRequestTask* task =
144 new buzz::PubSubRequestTask(client, pubsubjid, node);
145 task->SignalResult.connect(
146 listener.get(), &TestPubSubTasksListener::OnRequestResult);
147 task->SignalError.connect(
148 listener.get(), &TestPubSubTasksListener::OnError);
149 task->Start();
150 client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
151
152 EXPECT_EQ(0, listener->result_count);
153 EXPECT_EQ(1, listener->error_count);
154}
155
156TEST_F(PubSubTasksTest, TestReceive) {
157 std::string items_message =
158 "<message xmlns='jabber:client' from='room@domain.com'>"
159 " <event xmlns='http://jabber.org/protocol/pubsub#event'>"
160 " <items node='topic'>"
161 " <item id='key0'>"
162 " <value0/>"
163 " </item>"
164 " <item id='key1'>"
165 " <value1/>"
166 " </item>"
167 " </items>"
168 " </event>"
169 "</message>";
170
171 buzz::PubSubReceiveTask* task =
172 new buzz::PubSubReceiveTask(client, pubsubjid, node);
173 task->SignalUpdate.connect(
174 listener.get(), &TestPubSubTasksListener::OnReceiveUpdate);
175 task->Start();
176 client->HandleStanza(buzz::XmlElement::ForStr(items_message));
177
178 ASSERT_EQ(2U, listener->items.size());
179 EXPECT_EQ("key0", listener->items[0].itemid);
180 EXPECT_EQ(
181 "<eve:value0 xmlns:eve=\"http://jabber.org/protocol/pubsub#event\"/>",
182 listener->items[0].payload);
183 EXPECT_EQ("key1", listener->items[1].itemid);
184 EXPECT_EQ(
185 "<eve:value1 xmlns:eve=\"http://jabber.org/protocol/pubsub#event\"/>",
186 listener->items[1].payload);
187}
188
189TEST_F(PubSubTasksTest, TestPublish) {
190 buzz::XmlElement* payload =
191 new buzz::XmlElement(buzz::QName(buzz::NS_PUBSUB, "value"));
192 std::string expected_iq =
193 "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
194 "xmlns:cli=\"jabber:client\">"
195 "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
196 "<publish node=\"topic\">"
197 "<item id=\"key\">"
198 "<value/>"
199 "</item>"
200 "</publish>"
201 "</pubsub>"
202 "</cli:iq>";
203
204 std::vector<buzz::XmlElement*> children;
205 children.push_back(payload);
206 buzz::PubSubPublishTask* task =
207 new buzz::PubSubPublishTask(client, pubsubjid, node, itemid, children);
208 task->SignalResult.connect(
209 listener.get(), &TestPubSubTasksListener::OnPublishResult);
210 task->Start();
211
212 ASSERT_EQ(1U, client->sent_stanzas().size());
213 EXPECT_EQ(expected_iq, client->sent_stanzas()[0]->Str());
214
215 std::string result_iq =
216 "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'/>";
217
218 client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
219
220 EXPECT_EQ(1, listener->result_count);
221 EXPECT_EQ(0, listener->error_count);
222}
223
224TEST_F(PubSubTasksTest, TestPublishError) {
225 buzz::XmlElement* payload =
226 new buzz::XmlElement(buzz::QName(buzz::NS_PUBSUB, "value"));
227
228 std::vector<buzz::XmlElement*> children;
229 children.push_back(payload);
230 buzz::PubSubPublishTask* task =
231 new buzz::PubSubPublishTask(client, pubsubjid, node, itemid, children);
232 task->SignalResult.connect(
233 listener.get(), &TestPubSubTasksListener::OnPublishResult);
234 task->SignalError.connect(
235 listener.get(), &TestPubSubTasksListener::OnError);
236 task->Start();
237
238 std::string result_iq =
239 "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
240 " <error type='auth'>"
241 " <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
242 " </error>"
243 "</iq>";
244
245 client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
246
247 EXPECT_EQ(0, listener->result_count);
248 EXPECT_EQ(1, listener->error_count);
249}
250
251TEST_F(PubSubTasksTest, TestRetract) {
252 buzz::PubSubRetractTask* task =
253 new buzz::PubSubRetractTask(client, pubsubjid, node, itemid);
254 task->SignalResult.connect(
255 listener.get(), &TestPubSubTasksListener::OnRetractResult);
256 task->SignalError.connect(
257 listener.get(), &TestPubSubTasksListener::OnError);
258 task->Start();
259
260 std::string expected_iq =
261 "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
262 "xmlns:cli=\"jabber:client\">"
263 "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
264 "<retract node=\"topic\" notify=\"true\">"
265 "<item id=\"key\"/>"
266 "</retract>"
267 "</pubsub>"
268 "</cli:iq>";
269
270 ASSERT_EQ(1U, client->sent_stanzas().size());
271 EXPECT_EQ(expected_iq, client->sent_stanzas()[0]->Str());
272
273 std::string result_iq =
274 "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'/>";
275
276 client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
277
278 EXPECT_EQ(1, listener->result_count);
279 EXPECT_EQ(0, listener->error_count);
280}