/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ package org.apache.vysper.xmpp.modules.extension.xep0045_muc.handler; import java.util.List; import org.apache.vysper.xml.fragment.XMLElement; import org.apache.vysper.xml.fragment.XMLSemanticError; import org.apache.vysper.xmpp.addressing.Entity; import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.Occupant; import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.Room; import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.RoomType; import org.apache.vysper.xmpp.protocol.NamespaceURIs; import org.apache.vysper.xmpp.protocol.ProtocolException; import org.apache.vysper.xmpp.protocol.ResponseStanzaContainer; import org.apache.vysper.xmpp.protocol.StanzaHandler; import org.apache.vysper.xmpp.stanza.PresenceStanzaType; import org.apache.vysper.xmpp.stanza.Stanza; import org.apache.vysper.xmpp.stanza.StanzaBuilder; /** */ public class ExitRoomTestCase extends AbstractMUCHandlerTestCase { private Stanza exitRoom(Entity occupantJid, Entity roomJid) throws ProtocolException { return exitRoom(occupantJid, roomJid, null); } private Stanza exitRoom(Entity occupantJid, Entity roomJid, String status) throws ProtocolException { StanzaBuilder stanzaBuilder = StanzaBuilder.createPresenceStanza(occupantJid, roomJid, null, PresenceStanzaType.UNAVAILABLE, null, status); Stanza presenceStanza = stanzaBuilder.build(); ResponseStanzaContainer container = handler.execute(presenceStanza, sessionContext.getServerRuntimeContext(), true, sessionContext, null); if (container != null) { return container.getResponseStanza(); } else { return null; } } @Override protected StanzaHandler createHandler() { return new MUCPresenceHandler(conference); } public void testExitRoom() throws Exception { Room room = conference.findRoom(ROOM1_JID); room.addOccupant(OCCUPANT1_JID, "Nick1"); room.addOccupant(OCCUPANT2_JID, "Nick2"); assertNull(exitRoom(OCCUPANT1_JID, ROOM1_JID_WITH_NICK)); assertEquals(1, room.getOccupantCount()); Occupant occupant = room.getOccupants().iterator().next(); assertEquals(OCCUPANT2_JID, occupant.getJid()); } public void testExitNonexistingRoom() throws Exception { // Quietly ignore assertNull(exitRoom(OCCUPANT1_JID, ROOM2_JID_WITH_NICK)); } public void testExitRoomWithoutEntering() throws Exception { // Exit a room where the user is not a participant, quietly ignore assertNull(exitRoom(OCCUPANT1_JID, ROOM1_JID_WITH_NICK)); } public void testTemporaryRoomDeleted() throws Exception { // Room1 is temporary Room room = conference.findRoom(ROOM1_JID); assertTrue(room.isRoomType(RoomType.Temporary)); room.addOccupant(OCCUPANT1_JID, "Nick1"); // exit room, room should be deleted assertNull(exitRoom(OCCUPANT1_JID, ROOM1_JID_WITH_NICK)); assertNull(conference.findRoom(ROOM1_JID)); } public void testPersistentRoomNotDeleted() throws Exception { // Room2 is persistent Room room = conference.createRoom(ROOM2_JID, "Room 2", RoomType.Persistent); room.addOccupant(OCCUPANT1_JID, "Nick1"); // exit room, room should be deleted assertNull(exitRoom(OCCUPANT1_JID, ROOM1_JID_WITH_NICK)); assertNotNull(conference.findRoom(ROOM1_JID)); } public void testExitRoomWithRelays() throws Exception { // add occupants to the room Room room = conference.findOrCreateRoom(ROOM1_JID, "Room 1"); room.addOccupant(OCCUPANT1_JID, "Nick 1"); room.addOccupant(OCCUPANT2_JID, "Nick 2"); // now, let user 1 exit room exitRoom(OCCUPANT1_JID, ROOM1_JID_WITH_NICK); // verify stanzas to existing occupants on the exiting user assertExitPresenceStanza(ROOM1_JID, "Nick 1", OCCUPANT1_JID, occupant1Queue.getNext(), null, true); assertExitPresenceStanza(ROOM1_JID, "Nick 1", OCCUPANT2_JID, occupant2Queue.getNext(), null, false); } public void testExitRoomWithRelaysWithStatus() throws Exception { String statusMessage = "Custom status"; // add occupants to the room Room room = conference.findOrCreateRoom(ROOM1_JID, "Room 1"); room.addOccupant(OCCUPANT1_JID, "Nick 1"); room.addOccupant(OCCUPANT2_JID, "Nick 2"); // now, let user 1 exit room exitRoom(OCCUPANT1_JID, ROOM1_JID_WITH_NICK, statusMessage); // verify stanzas to existing occupants on the exiting user assertExitPresenceStanza(ROOM1_JID, "Nick 1", OCCUPANT1_JID, occupant1Queue.getNext(), statusMessage, true); assertExitPresenceStanza(ROOM1_JID, "Nick 1", OCCUPANT2_JID, occupant2Queue.getNext(), statusMessage, false); } private void assertExitPresenceStanza(Entity roomJid, String nick, Entity to, Stanza stanza, String expectedStatus, boolean own) throws XMLSemanticError { // should be from room + nick name assertEquals(roomJid.getFullQualifiedName() + "/" + nick, stanza.getFrom().getFullQualifiedName()); // should be to the existing user assertEquals(to, stanza.getTo()); assertEquals("unavailable", stanza.getAttributeValue("type")); XMLElement xElement = stanza.getSingleInnerElementsNamed("x"); assertEquals(NamespaceURIs.XEP0045_MUC_USER, xElement.getNamespaceURI()); // since this room is non-anonymous, x must contain an item element with the users full JID XMLElement itemElement = xElement.getSingleInnerElementsNamed("item"); assertEquals("none", itemElement.getAttributeValue("affiliation")); assertEquals("none", itemElement.getAttributeValue("role")); if (own) { List<XMLElement> statuses = xElement.getInnerElementsNamed("status"); assertEquals(1, statuses.size()); assertEquals("110", statuses.get(0).getAttributeValue("code")); } if (expectedStatus != null) { List<XMLElement> statuses = xElement.getInnerElementsNamed("status"); assertEquals(1, statuses.size()); assertEquals(expectedStatus, statuses.get(0).getInnerText().getText()); } } }