package org.buddycloud.channelserver.utils.users; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.LinkedList; import java.util.Properties; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import org.buddycloud.channelserver.Configuration; import org.buddycloud.channelserver.channel.ChannelManager; import org.buddycloud.channelserver.db.exception.NodeStoreException; import org.buddycloud.channelserver.packetHandler.iq.IQTestHandler; import org.buddycloud.channelserver.pubsub.model.NodeSubscription; import org.buddycloud.channelserver.pubsub.model.impl.NodeSubscriptionImpl; import org.buddycloud.channelserver.pubsub.subscription.Subscriptions; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.xmpp.packet.JID; import org.xmpp.packet.Packet; import org.xmpp.packet.Presence; import org.xmpp.resultsetmanagement.ResultSetImpl; public class OnlineResourceManagerTest extends IQTestHandler { private OnlineResourceManager onlineUser; private Properties configuration; private JID localUserLaptop = new JID("user@server1.com/laptop"); private JID localUserDesktop = new JID("user@server1.com/desktop"); private JID localUserNoResource = new JID("user@server1.com"); private JID remoteBuddycloudServer = new JID("channels.buddycloud.org"); private ChannelManager channelManager; private JID remoteUser = new JID("user@server2.com/remote"); @Before public void setUp() throws Exception { configuration = Mockito.mock(Properties.class); Mockito.when(configuration.getProperty(Configuration.CONFIGURATION_SERVER_DOMAIN)).thenReturn("server1.com"); channelManager = Mockito.mock(ChannelManager.class); Mockito.when(channelManager.onlineJids(Mockito.any(JID.class))).thenThrow(Exception.class); Mockito.doThrow(Exception.class).when(channelManager).jidOffline(Mockito.any(JID.class)); Mockito.doThrow(Exception.class).when(channelManager).jidOnline(Mockito.any(JID.class)); onlineUser = new OnlineResourceManager(configuration, channelManager); } @Test(expected = NullPointerException.class) public void testNotSettingCorrectConfigurationKeysThrowsException() { Properties configuration = Mockito.mock(Properties.class); Mockito.when(configuration.getProperty(Configuration.CONFIGURATION_SERVER_DOMAIN)).thenReturn(null); onlineUser = new OnlineResourceManager(configuration, channelManager); } @Test public void testRequestingOnlineResourcesForOfflineUserReturnsNone() throws Exception { ArrayList<JID> users = onlineUser.getResources(localUserNoResource); assertEquals(0, users.size()); } @Test public void testCanSetAUserAsOnlineAndSeeInOnlineResourcesList() throws Exception { onlineUser.updateStatus(localUserDesktop, "chat"); ArrayList<JID> users = onlineUser.getResources(localUserNoResource); assertEquals(1, users.size()); } @Test public void testAttemptingToUpdateStatusOfUserNotFromDomainIsIgnored() throws Exception { onlineUser.updateStatus(remoteUser, "chat"); ArrayList<JID> users = onlineUser.getResources(new JID(remoteUser.toBareJID())); assertEquals(0, users.size()); } @Test public void testAttemptingToUpdateStatusOfUserFromExternallyValidatedDomain() throws Exception { when(configuration.getProperty(Configuration.CONFIGURATION_LOCAL_DOMAIN_CHECKER)).thenReturn(Boolean.TRUE.toString()); onlineUser.updateStatus(remoteUser, "online"); ArrayList<JID> users = onlineUser.getResources(new JID(remoteUser.toBareJID())); assertEquals(1, users.size()); } @Test public void testCanGoOnlineOnTwoResourcesAndRetrieveBoth() throws Exception { onlineUser.updateStatus(localUserDesktop, "chat"); onlineUser.updateStatus(localUserLaptop, "chat"); ArrayList<JID> users = onlineUser.getResources(localUserNoResource); assertEquals(2, users.size()); assertEquals(localUserDesktop, users.get(0)); assertEquals(localUserLaptop, users.get(1)); } @Test public void testCanGoOnlineOnTwoResourcesTakeOneOfflineAndRetrieveOneBack() throws Exception { onlineUser.updateStatus(localUserDesktop, "chat"); onlineUser.updateStatus(localUserLaptop, "chat"); onlineUser.updateStatus(localUserDesktop, OnlineResourceManager.UNAVAILABLE); ArrayList<JID> users = onlineUser.getResources(localUserNoResource); assertEquals(1, users.size()); assertEquals(localUserLaptop, users.get(0)); } @Test public void testCanConstructAJidIndependentlyAndItWillStillMatch() throws Exception { onlineUser.updateStatus(localUserDesktop, "chat"); onlineUser.updateStatus(localUserLaptop, "chat"); onlineUser.updateStatus(new JID(localUserDesktop.toFullJID()), OnlineResourceManager.UNAVAILABLE); ArrayList<JID> users = onlineUser.getResources(localUserNoResource); assertEquals(1, users.size()); assertEquals(new JID(localUserLaptop.toFullJID()), users.get(0)); } @Test public void testPassingAFullJidReturnsToGetResourcesOnlyReturnsThatJid() throws Exception { ArrayList<JID> users = onlineUser.getResources(localUserDesktop); assertEquals(1, users.size()); assertEquals(localUserDesktop, users.get(0)); } @Test public void testPassingRemoteBuddycloudServerReturnsOnlyThatJid() throws Exception { ArrayList<JID> users = onlineUser.getResources(remoteBuddycloudServer); assertEquals(1, users.size()); assertEquals(remoteBuddycloudServer, users.get(0)); } @Test public void testAddingTheSameResourceTwiceDoesntResultInTwoEntries() throws Exception { onlineUser.updateStatus(localUserDesktop, "chat"); onlineUser.updateStatus(localUserDesktop, "chat"); ArrayList<JID> users = onlineUser.getResources(localUserNoResource); assertEquals(1, users.size()); assertEquals(new JID(localUserDesktop.toFullJID()), users.get(0)); } @Test public void testAutoSubscribeToNoListeners() throws Exception { Mockito.when(channelManager.getNodeSubscriptionListeners()).thenReturn(new ResultSetImpl<NodeSubscription>(new LinkedList<NodeSubscription>())); BlockingQueue<Packet> outQueue = new LinkedBlockingQueue<Packet>(); onlineUser.subscribeToNodeListeners(outQueue); Assert.assertTrue(outQueue.isEmpty()); } @Test public void testAutoSubscribeToListeners() throws Exception { JID jid = new JID("user@server.com"); LinkedList<NodeSubscription> subscriptions = new LinkedList<NodeSubscription>(); subscriptions.add(new NodeSubscriptionImpl("nodeId", jid, Subscriptions.subscribed, null)); Mockito.when(channelManager.getNodeSubscriptionListeners()).thenReturn(new ResultSetImpl<NodeSubscription>(subscriptions)); BlockingQueue<Packet> outQueue = new LinkedBlockingQueue<Packet>(); onlineUser.subscribeToNodeListeners(outQueue); Assert.assertFalse(outQueue.isEmpty()); Presence presence = (Presence) outQueue.poll(); Assert.assertEquals(jid, presence.getTo()); Assert.assertEquals(Presence.Type.subscribe, presence.getType()); } @Test public void ifUsingDatabaseWeSeeRequestForOnlineUsersMethod() throws Exception { Mockito.when(configuration.getProperty(Mockito.eq(Configuration.PERSIST_PRESENCE_DATA), Mockito.anyString())).thenReturn("true"); channelManager = Mockito.mock(ChannelManager.class); onlineUser = new OnlineResourceManager(configuration, channelManager); onlineUser.getResources(localUserNoResource); Mockito.verify(channelManager, Mockito.times(1)).onlineJids(Mockito.eq(localUserNoResource)); } @Test public void ifUsingDatabaseWeSeeRequestForAddingUser() throws Exception { Mockito.when(configuration.getProperty(Mockito.eq(Configuration.PERSIST_PRESENCE_DATA), Mockito.anyString())).thenReturn("true"); channelManager = Mockito.mock(ChannelManager.class); onlineUser = new OnlineResourceManager(configuration, channelManager); onlineUser.updateStatus(localUserLaptop, "chat"); Mockito.verify(channelManager, Mockito.times(1)).jidOnline(Mockito.eq(localUserLaptop)); } @Test public void ifUsingDatabaseWeSeeRequestForRemovingUser() throws NodeStoreException { Mockito.when(configuration.getProperty(Mockito.eq(Configuration.PERSIST_PRESENCE_DATA), Mockito.anyString())).thenReturn("true"); channelManager = Mockito.mock(ChannelManager.class); onlineUser = new OnlineResourceManager(configuration, channelManager); onlineUser.updateStatus(localUserLaptop, OnlineResourceManager.UNAVAILABLE); Mockito.verify(channelManager, Mockito.times(1)).jidOffline(Mockito.eq(localUserLaptop)); } }