/** * $RCSfile$ * $Revision$ * $Date$ * * Copyright (C) 2004 Jive Software. All rights reserved. * * This software is published under the terms of the GNU Public License (GPL), * a copy of which is included in this distribution. */ package org.jivesoftware.smack; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.test.SmackTestCase; import java.util.Iterator; /** * Ensure that the server is delivering messages to the correct client based on the client's * presence priority. * * @author Gaston Dombiak */ public class PresenceTest extends SmackTestCase { public PresenceTest(String arg0) { super(arg0); } /** * Connection(0) will send messages to the bareJID of Connection(1) where the user of * Connection(1) has logged from two different places with different presence priorities. */ public void testMessageToHighestPriority() { XMPPConnection conn = null; try { // User_1 will log in again using another resource conn = new XMPPConnection(getHost(), getPort()); conn.connect(); conn.login(getUsername(1), getUsername(1), "OtherPlace"); // Change the presence priorities of User_1 getConnection(1).sendPacket(new Presence(Presence.Type.available, null, 1, Presence.Mode.available)); conn.sendPacket(new Presence(Presence.Type.available, null, 2, Presence.Mode.available)); Thread.sleep(150); // Create the chats between the participants Chat chat0 = new Chat(getConnection(0), getBareJID(1)); Chat chat1 = new Chat(getConnection(1), getBareJID(0), chat0.getThreadID()); Chat chat2 = new Chat(conn, getBareJID(0), chat0.getThreadID()); // Test delivery of message to the presence with highest priority chat0.sendMessage("Hello"); assertNotNull("Resource with highest priority didn't receive the message", chat2.nextMessage(2000)); assertNull("Resource with lowest priority received the message", chat1.nextMessage(1000)); // Invert the presence priorities of User_1 getConnection(1).sendPacket(new Presence(Presence.Type.available, null, 2, Presence.Mode.available)); conn.sendPacket(new Presence(Presence.Type.available, null, 1, Presence.Mode.available)); Thread.sleep(150); // Test delivery of message to the presence with highest priority chat0.sendMessage("Hello"); assertNotNull("Resource with highest priority didn't receive the message", chat1.nextMessage(2000)); assertNull("Resource with lowest priority received the message", chat2.nextMessage(1000)); // User_1 closes his connection conn.disconnect(); Thread.sleep(150); // Test delivery of message to the unique presence of the user_1 chat0.sendMessage("Hello"); assertNotNull("Resource with highest priority didn't receive the message", chat1.nextMessage(2000)); getConnection(1).sendPacket(new Presence(Presence.Type.available, null, 2, Presence.Mode.available)); // User_1 will log in again using another resource conn = new XMPPConnection(getHost(), getPort()); conn.connect(); conn.login(getUsername(1), getUsername(1), "OtherPlace"); conn.sendPacket(new Presence(Presence.Type.available, null, 1, Presence.Mode.available)); chat2 = new Chat(conn, getBareJID(0), chat0.getThreadID()); Thread.sleep(150); // Test delivery of message to the presence with highest priority chat0.sendMessage("Hello"); assertNotNull("Resource with highest priority didn't receive the message", chat1.nextMessage(2000)); assertNull("Resource with lowest priority received the message", chat2.nextMessage(1000)); // Invert the presence priorities of User_1 getConnection(1).sendPacket(new Presence(Presence.Type.available, null, 1, Presence.Mode.available)); conn.sendPacket(new Presence(Presence.Type.available, null, 2, Presence.Mode.available)); Thread.sleep(150); // Test delivery of message to the presence with highest priority chat0.sendMessage("Hello"); assertNotNull("Resource with highest priority didn't receive the message", chat2.nextMessage(2000)); assertNull("Resource with lowest priority received the message", chat1.nextMessage(1000)); } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } finally { if (conn != null) { conn.disconnect(); } } } /** * User1 logs from 2 resources but only one is available. User0 sends a message * to the full JID of the unavailable resource. User1 in the not available resource * should receive the message. * TODO Fix this in Wildfire but before check if XMPP spec requests this feature */ public void testNotAvailablePresence() throws XMPPException { // Change the presence to unavailable of User_1 getConnection(1).sendPacket(new Presence(Presence.Type.unavailable)); // User_1 will log in again using another resource (that is going to be available) XMPPConnection conn = new XMPPConnection(getHost(), getPort()); conn.connect(); conn.login(getUsername(1), getUsername(1), "OtherPlace"); // Create chats between participants Chat chat0 = new Chat(getConnection(0), getFullJID(1)); Chat chat1 = new Chat(getConnection(1), getBareJID(0), chat0.getThreadID()); // Test delivery of message to the presence with highest priority chat0.sendMessage("Hello"); assertNotNull("Not available connection didn't receive message sent to full JID", chat1.nextMessage(2000)); assertNull("Not available connection received an unknown message", chat1.nextMessage(1000)); } /** * User1 is connected from 2 resources. User1 adds User0 to his roster. Ensure * that presences are correctly retrieved for User1. User1 logs off from one resource * and ensure that presences are still correct for User1. */ public void testMultipleResources() throws Exception { // Create another connection for the same user of connection 1 XMPPConnection conn4 = new XMPPConnection(getServiceName()); conn4.connect(); conn4.login(getUsername(1), getUsername(1), "Home"); // Add a new roster entry Roster roster = getConnection(0).getRoster(); roster.createEntry(getBareJID(1), "gato1", null); // Wait up to 2 seconds long initial = System.currentTimeMillis(); while (System.currentTimeMillis() - initial < 2000 && ( roster.getPresence(getBareJID(1)) == null)) { Thread.sleep(100); } // Check that a presence is returned for the new contact Presence presence = roster.getPresence(getBareJID(1)); assertNotNull("Returned a null Presence for an existing user", presence); presence = roster.getPresenceResource(getBareJID(1) + "/Home"); assertNotNull("Returned a null Presence for Home resource", presence); presence = roster.getPresenceResource(getFullJID(1)); assertNotNull("Returned a null Presence for Smack resource", presence); Iterator presences = roster.getPresences(getBareJID(1)); assertNotNull("No presence was found for user1", presences); assertTrue("No presence was found for user1", presences.hasNext()); presences.next(); assertTrue("Only one presence was found for user1", presences.hasNext()); // User1 logs out from one resource conn4.disconnect(); // Wait up to 1 second Thread.sleep(700); // Check that a presence is returned for the new contact presence = roster.getPresence(getBareJID(1)); assertNotNull("Returned a null Presence for an existing user", presence); presence = roster.getPresenceResource(getFullJID(1)); assertNotNull("Returned a null Presence for Smack resource", presence); presence = roster.getPresenceResource(getBareJID(1) + "/Home"); assertNull("Returned a Presence for no longer connected resource", presence); presences = roster.getPresences(getBareJID(1)); assertNotNull("No presence was found for user1", presences); assertTrue("No presence was found for user1", presences.hasNext()); presences.next(); assertFalse("More than one presence was found for user1", presences.hasNext()); } protected int getMaxConnections() { return 2; } }