blob: a152f6060937e9199e87d74d7017643cbdf409ef [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
3 * Copyright 2004, Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <string>
29#include <sstream>
30#include <iostream>
31#include "common/common.h"
32#include "buzz/xmppengine.h"
33#include "buzz/xmlelement.h"
34#include "buzz/chatroommodule.h"
35#include "buzz/constants.h"
36#include "engine/util_unittest.h"
37#include "test/unittest.h"
38#include "test/unittest-inl.h"
39
40#define TEST_OK(x) TEST_EQ((x),XMPP_RETURN_OK)
41#define TEST_BADARGUMENT(x) TEST_EQ((x),XMPP_RETURN_BADARGUMENT)
42
43namespace buzz {
44
45class MultiUserChatModuleTest;
46
47static void
48WriteEnteredStatus(std::ostream& os, XmppChatroomEnteredStatus status) {
49 switch(status) {
50 case XMPP_CHATROOM_ENTERED_SUCCESS:
51 os<<"success";
52 break;
53 case XMPP_CHATROOM_ENTERED_FAILURE_NICKNAME_CONFLICT:
54 os<<"failure(nickname conflict)";
55 break;
56 case XMPP_CHATROOM_ENTERED_FAILURE_PASSWORD_REQUIRED:
57 os<<"failure(password required)";
58 break;
59 case XMPP_CHATROOM_ENTERED_FAILURE_PASSWORD_INCORRECT:
60 os<<"failure(password incorrect)";
61 break;
62 case XMPP_CHATROOM_ENTERED_FAILURE_NOT_A_MEMBER:
63 os<<"failure(not a member)";
64 break;
65 case XMPP_CHATROOM_ENTERED_FAILURE_MEMBER_BANNED:
66 os<<"failure(member banned)";
67 break;
68 case XMPP_CHATROOM_ENTERED_FAILURE_MAX_USERS:
69 os<<"failure(max users)";
70 break;
71 case XMPP_CHATROOM_ENTERED_FAILURE_ROOM_LOCKED:
72 os<<"failure(room locked)";
73 break;
74 case XMPP_CHATROOM_ENTERED_FAILURE_UNSPECIFIED:
75 os<<"failure(unspecified)";
76 break;
77 default:
78 os<<"unknown";
79 break;
80 }
81}
82
83static void
84WriteExitedStatus(std::ostream& os, XmppChatroomExitedStatus status) {
85 switch (status) {
86 case XMPP_CHATROOM_EXITED_REQUESTED:
87 os<<"requested";
88 break;
89 case XMPP_CHATROOM_EXITED_BANNED:
90 os<<"banned";
91 break;
92 case XMPP_CHATROOM_EXITED_KICKED:
93 os<<"kicked";
94 break;
95 case XMPP_CHATROOM_EXITED_NOT_A_MEMBER:
96 os<<"not member";
97 break;
98 case XMPP_CHATROOM_EXITED_SYSTEM_SHUTDOWN:
99 os<<"system shutdown";
100 break;
101 case XMPP_CHATROOM_EXITED_UNSPECIFIED:
102 os<<"unspecified";
103 break;
104 default:
105 os<<"unknown";
106 break;
107 }
108}
109
110//! This session handler saves all calls to a string. These are events and
111//! data delivered form the engine to application code.
112class XmppTestChatroomHandler : public XmppChatroomHandler {
113public:
114 XmppTestChatroomHandler() {}
115 virtual ~XmppTestChatroomHandler() {}
116
117 void ChatroomEnteredStatus(XmppChatroomModule* room,
118 XmppChatroomEnteredStatus status) {
119 UNUSED(room);
120 ss_ <<"[ChatroomEnteredStatus status: ";
121 WriteEnteredStatus(ss_, status);
122 ss_ <<"]";
123 }
124
125
126 void ChatroomExitedStatus(XmppChatroomModule* room,
127 XmppChatroomExitedStatus status) {
128 UNUSED(room);
129 ss_ <<"[ChatroomExitedStatus status: ";
130 WriteExitedStatus(ss_, status);
131 ss_ <<"]";
132 }
133
134 void MemberEntered(XmppChatroomModule* room,
135 const XmppChatroomMember* entered_member) {
136 UNUSED(room);
137 ss_ << "[MemberEntered " << entered_member->member_jid().Str() << "]";
138 }
139
140 void MemberExited(XmppChatroomModule* room,
141 const XmppChatroomMember* exited_member) {
142 UNUSED(room);
143 ss_ << "[MemberExited " << exited_member->member_jid().Str() << "]";
144 }
145
146 void MemberChanged(XmppChatroomModule* room,
147 const XmppChatroomMember* changed_member) {
148 UNUSED(room);
149 ss_ << "[MemberChanged " << changed_member->member_jid().Str() << "]";
150 }
151
152 virtual void MessageReceived(XmppChatroomModule* room, const XmlElement& message) {
153 UNUSED2(room, message);
154 }
155
156
157 std::string Str() {
158 return ss_.str();
159 }
160
161 std::string StrClear() {
162 std::string result = ss_.str();
163 ss_.str("");
164 return result;
165 }
166
167private:
168 std::stringstream ss_;
169};
170
171//! This is the class that holds all of the unit test code for the
172//! roster module
173class XmppChatroomModuleTest : public UnitTest {
174public:
175 XmppChatroomModuleTest() {}
176
177 void TestEnterExitChatroom() {
178 std::stringstream dump;
179
180 // Configure the engine
181 scoped_ptr<XmppEngine> engine(XmppEngine::Create());
182 XmppTestHandler handler(engine.get());
183
184 // Configure the module and handler
185 scoped_ptr<XmppChatroomModule> chatroom(XmppChatroomModule::Create());
186
187 // Configure the module handler
188 chatroom->RegisterEngine(engine.get());
189
190 // Set up callbacks
191 engine->SetOutputHandler(&handler);
192 engine->AddStanzaHandler(&handler);
193 engine->SetSessionHandler(&handler);
194
195 // Set up minimal login info
196 engine->SetUser(Jid("david@my-server"));
197 engine->SetPassword("david");
198
199 // Do the whole login handshake
200 RunLogin(this, engine.get(), &handler);
201 TEST_EQ("", handler.OutputActivity());
202
203 // Get the chatroom and set the handler
204 XmppTestChatroomHandler chatroom_handler;
205 chatroom->set_chatroom_handler(static_cast<XmppChatroomHandler*>(&chatroom_handler));
206
207 // try to enter the chatroom
208 TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_NOT_IN_ROOM);
209 chatroom->set_nickname("thirdwitch");
210 chatroom->set_chatroom_jid(Jid("darkcave@my-server"));
211 chatroom->RequestEnterChatroom("", XMPP_CONNECTION_STATUS_UNKNOWN, "en");
212 TEST_EQ(chatroom_handler.StrClear(), "");
213 TEST_EQ(handler.OutputActivity(),
214 "<presence to=\"darkcave@my-server/thirdwitch\">"
215 "<muc:x xmlns:muc=\"http://jabber.org/protocol/muc\"/>"
216 "</presence>");
217 TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_REQUESTED_ENTER);
218
219 // simulate the server and test the client
220 std::string input;
221 input = "<presence from=\"darkcave@my-server/firstwitch\" to=\"david@my-server\">"
222 "<x xmlns=\"http://jabber.org/protocol/muc#user\">"
223 "<item affiliation=\"owner\" role=\"participant\"/>"
224 "</x>"
225 "</presence>";
226 TEST_OK(engine->HandleInput(input.c_str(), input.length()));
227 TEST_EQ(chatroom_handler.StrClear(), "");
228 TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_REQUESTED_ENTER);
229
230 input = "<presence from=\"darkcave@my-server/secondwitch\" to=\"david@my-server\">"
231 "<x xmlns=\"http://jabber.org/protocol/muc#user\">"
232 "<item affiliation=\"member\" role=\"participant\"/>"
233 "</x>"
234 "</presence>";
235 TEST_OK(engine->HandleInput(input.c_str(), input.length()));
236 TEST_EQ(chatroom_handler.StrClear(), "");
237 TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_REQUESTED_ENTER);
238
239 input = "<presence from=\"darkcave@my-server/thirdwitch\" to=\"david@my-server\">"
240 "<x xmlns=\"http://jabber.org/protocol/muc#user\">"
241 "<item affiliation=\"member\" role=\"participant\"/>"
242 "</x>"
243 "</presence>";
244 TEST_OK(engine->HandleInput(input.c_str(), input.length()));
245 TEST_EQ(chatroom_handler.StrClear(),
246 "[ChatroomEnteredStatus status: success]");
247 TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_IN_ROOM);
248
249 // simulate somebody else entering the room after we entered
250 input = "<presence from=\"darkcave@my-server/fourthwitch\" to=\"david@my-server\">"
251 "<x xmlns=\"http://jabber.org/protocol/muc#user\">"
252 "<item affiliation=\"member\" role=\"participant\"/>"
253 "</x>"
254 "</presence>";
255 TEST_OK(engine->HandleInput(input.c_str(), input.length()));
256 TEST_EQ(chatroom_handler.StrClear(), "[MemberEntered darkcave@my-server/fourthwitch]");
257 TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_IN_ROOM);
258
259 // simulate somebody else leaving the room after we entered
260 input = "<presence from=\"darkcave@my-server/secondwitch\" to=\"david@my-server\" type=\"unavailable\">"
261 "<x xmlns=\"http://jabber.org/protocol/muc#user\">"
262 "<item affiliation=\"member\" role=\"participant\"/>"
263 "</x>"
264 "</presence>";
265 TEST_OK(engine->HandleInput(input.c_str(), input.length()));
266 TEST_EQ(chatroom_handler.StrClear(), "[MemberExited darkcave@my-server/secondwitch]");
267 TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_IN_ROOM);
268
269 // try to leave the room
270 chatroom->RequestExitChatroom();
271 TEST_EQ(chatroom_handler.StrClear(), "");
272 TEST_EQ(handler.OutputActivity(),
273 "<presence to=\"darkcave@my-server/thirdwitch\" type=\"unavailable\"/>");
274 TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_REQUESTED_EXIT);
275
276 // simulate the server and test the client
277 input = "<presence from=\"darkcave@my-server/thirdwitch\" to=\"david@my-server\" type=\"unavailable\">"
278 "<x xmlns=\"http://jabber.org/protocol/muc#user\">"
279 "<item affiliation=\"member\" role=\"participant\"/>"
280 "</x>"
281 "</presence>";
282 TEST_OK(engine->HandleInput(input.c_str(), input.length()));
283 TEST_EQ(chatroom_handler.StrClear(),
284 "[ChatroomExitedStatus status: requested]");
285 TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_NOT_IN_ROOM);
286 }
287
288};
289
290// A global function that creates the test suite for this set of tests.
291TestBase* ChatroomModuleTest_Create() {
292 TestSuite* suite = new TestSuite("ChatroomModuleTest");
293 ADD_TEST(suite, XmppChatroomModuleTest, TestEnterExitChatroom);
294 return suite;
295}
296
297}