• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2004 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 <iostream>
12 #include <sstream>
13 #include <string>
14 #include "buzz/chatroommodule.h"
15 #include "buzz/constants.h"
16 #include "buzz/xmlelement.h"
17 #include "buzz/xmppengine.h"
18 #include "common/common.h"
19 #include "engine/util_unittest.h"
20 #include "test/unittest-inl.h"
21 #include "test/unittest.h"
22 
23 #define TEST_OK(x) TEST_EQ((x),XMPP_RETURN_OK)
24 #define TEST_BADARGUMENT(x) TEST_EQ((x),XMPP_RETURN_BADARGUMENT)
25 
26 namespace buzz {
27 
28 class MultiUserChatModuleTest;
29 
30 static void
WriteEnteredStatus(std::ostream & os,XmppChatroomEnteredStatus status)31 WriteEnteredStatus(std::ostream& os, XmppChatroomEnteredStatus status) {
32   switch(status) {
33     case XMPP_CHATROOM_ENTERED_SUCCESS:
34       os<<"success";
35       break;
36     case XMPP_CHATROOM_ENTERED_FAILURE_NICKNAME_CONFLICT:
37       os<<"failure(nickname conflict)";
38       break;
39     case XMPP_CHATROOM_ENTERED_FAILURE_PASSWORD_REQUIRED:
40       os<<"failure(password required)";
41       break;
42     case XMPP_CHATROOM_ENTERED_FAILURE_PASSWORD_INCORRECT:
43       os<<"failure(password incorrect)";
44       break;
45     case XMPP_CHATROOM_ENTERED_FAILURE_NOT_A_MEMBER:
46       os<<"failure(not a member)";
47       break;
48     case XMPP_CHATROOM_ENTERED_FAILURE_MEMBER_BANNED:
49       os<<"failure(member banned)";
50       break;
51     case XMPP_CHATROOM_ENTERED_FAILURE_MAX_USERS:
52       os<<"failure(max users)";
53       break;
54     case XMPP_CHATROOM_ENTERED_FAILURE_ROOM_LOCKED:
55       os<<"failure(room locked)";
56       break;
57     case XMPP_CHATROOM_ENTERED_FAILURE_UNSPECIFIED:
58       os<<"failure(unspecified)";
59       break;
60     default:
61       os<<"unknown";
62       break;
63   }
64 }
65 
66 static void
WriteExitedStatus(std::ostream & os,XmppChatroomExitedStatus status)67 WriteExitedStatus(std::ostream& os, XmppChatroomExitedStatus status) {
68   switch (status) {
69     case XMPP_CHATROOM_EXITED_REQUESTED:
70       os<<"requested";
71       break;
72     case XMPP_CHATROOM_EXITED_BANNED:
73       os<<"banned";
74       break;
75     case XMPP_CHATROOM_EXITED_KICKED:
76       os<<"kicked";
77       break;
78     case XMPP_CHATROOM_EXITED_NOT_A_MEMBER:
79       os<<"not member";
80       break;
81     case XMPP_CHATROOM_EXITED_SYSTEM_SHUTDOWN:
82       os<<"system shutdown";
83       break;
84     case XMPP_CHATROOM_EXITED_UNSPECIFIED:
85       os<<"unspecified";
86       break;
87     default:
88       os<<"unknown";
89       break;
90   }
91 }
92 
93 //! This session handler saves all calls to a string.  These are events and
94 //! data delivered form the engine to application code.
95 class XmppTestChatroomHandler : public XmppChatroomHandler {
96 public:
XmppTestChatroomHandler()97   XmppTestChatroomHandler() {}
~XmppTestChatroomHandler()98   virtual ~XmppTestChatroomHandler() {}
99 
ChatroomEnteredStatus(XmppChatroomModule * room,XmppChatroomEnteredStatus status)100   void ChatroomEnteredStatus(XmppChatroomModule* room,
101                              XmppChatroomEnteredStatus status) {
102     RTC_UNUSED(room);
103     ss_ <<"[ChatroomEnteredStatus status: ";
104     WriteEnteredStatus(ss_, status);
105     ss_ <<"]";
106   }
107 
108 
ChatroomExitedStatus(XmppChatroomModule * room,XmppChatroomExitedStatus status)109   void ChatroomExitedStatus(XmppChatroomModule* room,
110                             XmppChatroomExitedStatus status) {
111     RTC_UNUSED(room);
112     ss_ <<"[ChatroomExitedStatus status: ";
113     WriteExitedStatus(ss_, status);
114     ss_ <<"]";
115   }
116 
MemberEntered(XmppChatroomModule * room,const XmppChatroomMember * entered_member)117   void MemberEntered(XmppChatroomModule* room,
118                           const XmppChatroomMember* entered_member) {
119     RTC_UNUSED(room);
120     ss_ << "[MemberEntered " << entered_member->member_jid().Str() << "]";
121   }
122 
MemberExited(XmppChatroomModule * room,const XmppChatroomMember * exited_member)123   void MemberExited(XmppChatroomModule* room,
124                          const XmppChatroomMember* exited_member) {
125     RTC_UNUSED(room);
126     ss_ << "[MemberExited " << exited_member->member_jid().Str() << "]";
127   }
128 
MemberChanged(XmppChatroomModule * room,const XmppChatroomMember * changed_member)129   void MemberChanged(XmppChatroomModule* room,
130       const XmppChatroomMember* changed_member) {
131     RTC_UNUSED(room);
132     ss_ << "[MemberChanged " << changed_member->member_jid().Str() << "]";
133   }
134 
MessageReceived(XmppChatroomModule * room,const XmlElement & message)135   virtual void MessageReceived(XmppChatroomModule* room, const XmlElement& message) {
136     RTC_UNUSED2(room, message);
137   }
138 
139 
Str()140   std::string Str() {
141     return ss_.str();
142   }
143 
StrClear()144   std::string StrClear() {
145     std::string result = ss_.str();
146     ss_.str("");
147     return result;
148   }
149 
150 private:
151   std::stringstream ss_;
152 };
153 
154 //! This is the class that holds all of the unit test code for the
155 //! roster module
156 class XmppChatroomModuleTest : public UnitTest {
157 public:
XmppChatroomModuleTest()158   XmppChatroomModuleTest() {}
159 
TestEnterExitChatroom()160   void TestEnterExitChatroom() {
161     std::stringstream dump;
162 
163     // Configure the engine
164     rtc::scoped_ptr<XmppEngine> engine(XmppEngine::Create());
165     XmppTestHandler handler(engine.get());
166 
167     // Configure the module and handler
168     rtc::scoped_ptr<XmppChatroomModule> chatroom(XmppChatroomModule::Create());
169 
170     // Configure the module handler
171     chatroom->RegisterEngine(engine.get());
172 
173     // Set up callbacks
174     engine->SetOutputHandler(&handler);
175     engine->AddStanzaHandler(&handler);
176     engine->SetSessionHandler(&handler);
177 
178     // Set up minimal login info
179     engine->SetUser(Jid("david@my-server"));
180     engine->SetPassword("david");
181 
182     // Do the whole login handshake
183     RunLogin(this, engine.get(), &handler);
184     TEST_EQ("", handler.OutputActivity());
185 
186     // Get the chatroom and set the handler
187     XmppTestChatroomHandler chatroom_handler;
188     chatroom->set_chatroom_handler(static_cast<XmppChatroomHandler*>(&chatroom_handler));
189 
190     // try to enter the chatroom
191     TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_NOT_IN_ROOM);
192     chatroom->set_nickname("thirdwitch");
193     chatroom->set_chatroom_jid(Jid("darkcave@my-server"));
194     chatroom->RequestEnterChatroom("", XMPP_CONNECTION_STATUS_UNKNOWN, "en");
195     TEST_EQ(chatroom_handler.StrClear(), "");
196     TEST_EQ(handler.OutputActivity(),
197       "<presence to=\"darkcave@my-server/thirdwitch\">"
198         "<muc:x xmlns:muc=\"http://jabber.org/protocol/muc\"/>"
199       "</presence>");
200     TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_REQUESTED_ENTER);
201 
202     // simulate the server and test the client
203     std::string input;
204     input = "<presence from=\"darkcave@my-server/firstwitch\" to=\"david@my-server\">"
205              "<x xmlns=\"http://jabber.org/protocol/muc#user\">"
206               "<item affiliation=\"owner\" role=\"participant\"/>"
207              "</x>"
208             "</presence>";
209     TEST_OK(engine->HandleInput(input.c_str(), input.length()));
210     TEST_EQ(chatroom_handler.StrClear(), "");
211     TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_REQUESTED_ENTER);
212 
213     input = "<presence from=\"darkcave@my-server/secondwitch\" to=\"david@my-server\">"
214              "<x xmlns=\"http://jabber.org/protocol/muc#user\">"
215               "<item affiliation=\"member\" role=\"participant\"/>"
216              "</x>"
217             "</presence>";
218     TEST_OK(engine->HandleInput(input.c_str(), input.length()));
219     TEST_EQ(chatroom_handler.StrClear(), "");
220     TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_REQUESTED_ENTER);
221 
222     input = "<presence from=\"darkcave@my-server/thirdwitch\" to=\"david@my-server\">"
223              "<x xmlns=\"http://jabber.org/protocol/muc#user\">"
224               "<item affiliation=\"member\" role=\"participant\"/>"
225              "</x>"
226             "</presence>";
227     TEST_OK(engine->HandleInput(input.c_str(), input.length()));
228     TEST_EQ(chatroom_handler.StrClear(),
229       "[ChatroomEnteredStatus status: success]");
230     TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_IN_ROOM);
231 
232     // simulate somebody else entering the room after we entered
233     input = "<presence from=\"darkcave@my-server/fourthwitch\" to=\"david@my-server\">"
234              "<x xmlns=\"http://jabber.org/protocol/muc#user\">"
235               "<item affiliation=\"member\" role=\"participant\"/>"
236              "</x>"
237             "</presence>";
238     TEST_OK(engine->HandleInput(input.c_str(), input.length()));
239     TEST_EQ(chatroom_handler.StrClear(), "[MemberEntered darkcave@my-server/fourthwitch]");
240     TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_IN_ROOM);
241 
242     // simulate somebody else leaving the room after we entered
243     input = "<presence from=\"darkcave@my-server/secondwitch\" to=\"david@my-server\" type=\"unavailable\">"
244              "<x xmlns=\"http://jabber.org/protocol/muc#user\">"
245               "<item affiliation=\"member\" role=\"participant\"/>"
246              "</x>"
247             "</presence>";
248     TEST_OK(engine->HandleInput(input.c_str(), input.length()));
249     TEST_EQ(chatroom_handler.StrClear(), "[MemberExited darkcave@my-server/secondwitch]");
250     TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_IN_ROOM);
251 
252     // try to leave the room
253     chatroom->RequestExitChatroom();
254     TEST_EQ(chatroom_handler.StrClear(), "");
255     TEST_EQ(handler.OutputActivity(),
256       "<presence to=\"darkcave@my-server/thirdwitch\" type=\"unavailable\"/>");
257     TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_REQUESTED_EXIT);
258 
259     // simulate the server and test the client
260     input = "<presence from=\"darkcave@my-server/thirdwitch\" 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(),
267       "[ChatroomExitedStatus status: requested]");
268     TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_NOT_IN_ROOM);
269   }
270 
271 };
272 
273 // A global function that creates the test suite for this set of tests.
ChatroomModuleTest_Create()274 TestBase* ChatroomModuleTest_Create() {
275   TestSuite* suite = new TestSuite("ChatroomModuleTest");
276   ADD_TEST(suite, XmppChatroomModuleTest, TestEnterExitChatroom);
277   return suite;
278 }
279 
280 }
281