1 // Copyright 2011 Google Inc. All Rights Reserved
6 #include "webrtc/libjingle/xmllite/qname.h"
7 #include "webrtc/libjingle/xmllite/xmlelement.h"
8 #include "talk/xmpp/constants.h"
9 #include "talk/xmpp/fakexmppclient.h"
10 #include "talk/xmpp/jid.h"
11 #include "talk/xmpp/pubsubclient.h"
12 #include "webrtc/base/faketaskrunner.h"
13 #include "webrtc/base/gunit.h"
14 #include "webrtc/base/sigslot.h"
16 struct HandledPubSubItem {
21 class TestPubSubItemsListener : public sigslot::has_slots<> {
23 TestPubSubItemsListener() : error_count(0) {}
25 void OnItems(buzz::PubSubClient*,
26 const std::vector<buzz::PubSubItem>& items) {
27 for (std::vector<buzz::PubSubItem>::const_iterator item = items.begin();
28 item != items.end(); ++item) {
29 HandledPubSubItem handled_item;
30 handled_item.itemid = item->itemid;
31 if (item->elem->FirstElement() != NULL) {
32 handled_item.payload = item->elem->FirstElement()->Str();
34 this->items.push_back(handled_item);
38 void OnRequestError(buzz::PubSubClient* client,
39 const buzz::XmlElement* stanza) {
43 void OnPublishResult(buzz::PubSubClient* client,
44 const std::string& task_id,
45 const buzz::XmlElement* item) {
46 result_task_id = task_id;
49 void OnPublishError(buzz::PubSubClient* client,
50 const std::string& task_id,
51 const buzz::XmlElement* item,
52 const buzz::XmlElement* stanza) {
54 error_task_id = task_id;
57 void OnRetractResult(buzz::PubSubClient* client,
58 const std::string& task_id) {
59 result_task_id = task_id;
62 void OnRetractError(buzz::PubSubClient* client,
63 const std::string& task_id,
64 const buzz::XmlElement* stanza) {
66 error_task_id = task_id;
69 std::vector<HandledPubSubItem> items;
71 std::string error_task_id;
72 std::string result_task_id;
75 class PubSubClientTest : public testing::Test {
78 pubsubjid("room@domain.com"),
81 runner.reset(new rtc::FakeTaskRunner());
82 xmpp_client = new buzz::FakeXmppClient(runner.get());
83 client.reset(new buzz::PubSubClient(xmpp_client, pubsubjid, node));
84 listener.reset(new TestPubSubItemsListener());
85 client->SignalItems.connect(
86 listener.get(), &TestPubSubItemsListener::OnItems);
87 client->SignalRequestError.connect(
88 listener.get(), &TestPubSubItemsListener::OnRequestError);
89 client->SignalPublishResult.connect(
90 listener.get(), &TestPubSubItemsListener::OnPublishResult);
91 client->SignalPublishError.connect(
92 listener.get(), &TestPubSubItemsListener::OnPublishError);
93 client->SignalRetractResult.connect(
94 listener.get(), &TestPubSubItemsListener::OnRetractResult);
95 client->SignalRetractError.connect(
96 listener.get(), &TestPubSubItemsListener::OnRetractError);
99 rtc::scoped_ptr<rtc::FakeTaskRunner> runner;
100 // xmpp_client deleted by deleting runner.
101 buzz::FakeXmppClient* xmpp_client;
102 rtc::scoped_ptr<buzz::PubSubClient> client;
103 rtc::scoped_ptr<TestPubSubItemsListener> listener;
109 TEST_F(PubSubClientTest, TestRequest) {
110 client->RequestItems();
112 std::string expected_iq =
113 "<cli:iq type=\"get\" to=\"room@domain.com\" id=\"0\" "
114 "xmlns:cli=\"jabber:client\">"
115 "<pub:pubsub xmlns:pub=\"http://jabber.org/protocol/pubsub\">"
116 "<pub:items node=\"topic\"/>"
120 ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
121 EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
123 std::string result_iq =
124 "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'>"
125 " <pubsub xmlns='http://jabber.org/protocol/pubsub'>"
126 " <items node='topic'>"
137 xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
138 ASSERT_EQ(2U, listener->items.size());
139 EXPECT_EQ("key0", listener->items[0].itemid);
140 EXPECT_EQ("<pub:value0a xmlns:pub=\"http://jabber.org/protocol/pubsub\"/>",
141 listener->items[0].payload);
142 EXPECT_EQ("key1", listener->items[1].itemid);
143 EXPECT_EQ("<pub:value1a xmlns:pub=\"http://jabber.org/protocol/pubsub\"/>",
144 listener->items[1].payload);
146 std::string items_message =
147 "<message xmlns='jabber:client' from='room@domain.com'>"
148 " <event xmlns='http://jabber.org/protocol/pubsub#event'>"
149 " <items node='topic'>"
160 xmpp_client->HandleStanza(buzz::XmlElement::ForStr(items_message));
161 ASSERT_EQ(4U, listener->items.size());
162 EXPECT_EQ("key0", listener->items[2].itemid);
163 EXPECT_EQ("<eve:value0b"
164 " xmlns:eve=\"http://jabber.org/protocol/pubsub#event\"/>",
165 listener->items[2].payload);
166 EXPECT_EQ("key1", listener->items[3].itemid);
167 EXPECT_EQ("<eve:value1b"
168 " xmlns:eve=\"http://jabber.org/protocol/pubsub#event\"/>",
169 listener->items[3].payload);
172 TEST_F(PubSubClientTest, TestRequestError) {
173 std::string result_iq =
174 "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
175 " <error type='auth'>"
176 " <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
180 client->RequestItems();
181 xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
182 EXPECT_EQ(1, listener->error_count);
185 TEST_F(PubSubClientTest, TestPublish) {
186 buzz::XmlElement* payload =
187 new buzz::XmlElement(buzz::QName(buzz::NS_PUBSUB, "value"));
190 client->PublishItem(itemid, payload, &task_id);
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\">"
204 ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
205 EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
207 std::string result_iq =
208 "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'/>";
210 xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
211 EXPECT_EQ(task_id, listener->result_task_id);
214 TEST_F(PubSubClientTest, TestPublishError) {
215 buzz::XmlElement* payload =
216 new buzz::XmlElement(buzz::QName(buzz::NS_PUBSUB, "value"));
219 client->PublishItem(itemid, payload, &task_id);
221 std::string result_iq =
222 "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
223 " <error type='auth'>"
224 " <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
228 xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
229 EXPECT_EQ(1, listener->error_count);
230 EXPECT_EQ(task_id, listener->error_task_id);
233 TEST_F(PubSubClientTest, TestRetract) {
235 client->RetractItem(itemid, &task_id);
237 std::string expected_iq =
238 "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
239 "xmlns:cli=\"jabber:client\">"
240 "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
241 "<retract node=\"topic\" notify=\"true\">"
247 ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
248 EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
250 std::string result_iq =
251 "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'/>";
253 xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
254 EXPECT_EQ(task_id, listener->result_task_id);
257 TEST_F(PubSubClientTest, TestRetractError) {
259 client->RetractItem(itemid, &task_id);
261 std::string result_iq =
262 "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
263 " <error type='auth'>"
264 " <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
268 xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
269 EXPECT_EQ(1, listener->error_count);
270 EXPECT_EQ(task_id, listener->error_task_id);