mirror of
https://github.com/vanitasvitae/Smack.git
synced 2025-09-10 09:39:39 +02:00
Rework incoming packet listeners and Roster
Differentiate between asynchronous and synchronous ones. Asynchronous are the ones where the invocation order may not be the same as the order in which the stanzas arrived. Since it's no longer guaranteed that when a unit test calls processPacket(stanza) the stanza will be completely processed when the call returns, it was necessary to extend the unit tests (mostly Roster and ChatManager) with a packet listener that waits for his invocation. Since we now also use LinkedHashMaps as Map for the packet listeners (SMACK-531, SMACK-424), adding a packet listeners as last also means that it will be called as last. We exploit this behavior change now in the unit tests. Rename 'recvListeners' to 'syncRecvListeners' in AbstractXMPPConnection. Rename 'rosterInitialized' to 'loaded' in Roster. Add Roster.isLoaded(). Reset 'loaded' to false in Roster.setOfflinePresencesAndResetLoaded() (was setOfflinePresences()). Fixes SMACK-583, SMACK-532, SMACK-424
This commit is contained in:
parent
e5c6c9bdf8
commit
717090d272
39 changed files with 443 additions and 306 deletions
|
@ -27,102 +27,108 @@ import org.jivesoftware.smack.ChatManager.MatchMode;
|
|||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Message.Type;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.jivesoftware.smack.test.util.WaitForPacketListener;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ChatConnectionTest {
|
||||
|
||||
private DummyConnection connection;
|
||||
private DummyConnection dc;
|
||||
private ChatManager cm;
|
||||
private TestChatManagerListener listener;
|
||||
private WaitForPacketListener waitListener;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
connection = getConnection();
|
||||
// Defaults
|
||||
ChatManager.setDefaultIsNormalIncluded(true);
|
||||
ChatManager.setDefaultMatchMode(MatchMode.BARE_JID);
|
||||
|
||||
dc = DummyConnection.newConnectedDummyConnection();
|
||||
cm = ChatManager.getInstanceFor(dc);
|
||||
listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
waitListener = new WaitForPacketListener();
|
||||
dc.addSyncPacketListener(waitListener, null);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (connection != null)
|
||||
connection.disconnect();
|
||||
if (dc != null) {
|
||||
dc.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDefaultSetNormalIncluded() {
|
||||
public void validateDefaultSetNormalIncludedFalse() {
|
||||
ChatManager.setDefaultIsNormalIncluded(false);
|
||||
assertFalse(ChatManager.getInstanceFor(getConnection()).isNormalIncluded());
|
||||
|
||||
assertFalse(ChatManager.getInstanceFor(new DummyConnection()).isNormalIncluded());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDefaultSetNormalIncludedTrue() {
|
||||
ChatManager.setDefaultIsNormalIncluded(true);
|
||||
assertTrue(ChatManager.getInstanceFor(getConnection()).isNormalIncluded());
|
||||
assertTrue(ChatManager.getInstanceFor(new DummyConnection()).isNormalIncluded());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void validateDefaultSetMatchMode() {
|
||||
public void validateDefaultSetMatchModeNone() {
|
||||
ChatManager.setDefaultMatchMode(MatchMode.NONE);
|
||||
assertEquals(MatchMode.NONE, ChatManager.getInstanceFor(getConnection()).getMatchMode());
|
||||
|
||||
assertEquals(MatchMode.NONE, ChatManager.getInstanceFor(new DummyConnection()).getMatchMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDefaultSetMatchModeBareJid() {
|
||||
ChatManager.setDefaultMatchMode(MatchMode.BARE_JID);
|
||||
assertEquals(MatchMode.BARE_JID, ChatManager.getInstanceFor(getConnection()).getMatchMode());
|
||||
assertEquals(MatchMode.BARE_JID, ChatManager.getInstanceFor(new DummyConnection()).getMatchMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateMessageTypeWithDefaults() {
|
||||
DummyConnection dc = getConnection();
|
||||
ChatManager cm = ChatManager.getInstanceFor(dc);
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
public void validateMessageTypeWithDefaults1() {
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.chat);
|
||||
processServerMessage(incomingChat, dc);
|
||||
processServerMessage(incomingChat);
|
||||
assertNotNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
dc = getConnection();
|
||||
cm = ChatManager.getInstanceFor(dc);
|
||||
listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
incomingChat = createChatPacket("134", true);
|
||||
@Test
|
||||
public void validateMessageTypeWithDefaults2() {
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.normal);
|
||||
processServerMessage(incomingChat, dc);
|
||||
processServerMessage(incomingChat);
|
||||
assertNotNull(listener.getNewChat());
|
||||
|
||||
dc = getConnection();
|
||||
cm = ChatManager.getInstanceFor(dc);
|
||||
listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
incomingChat = createChatPacket("134", true);
|
||||
}
|
||||
@Test
|
||||
public void validateMessageTypeWithDefaults3() {
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.groupchat);
|
||||
processServerMessage(incomingChat, dc);
|
||||
assertNull(listener.getNewChat());
|
||||
|
||||
dc = getConnection();
|
||||
cm = ChatManager.getInstanceFor(dc);
|
||||
listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.headline);
|
||||
processServerMessage(incomingChat, dc);
|
||||
processServerMessage(incomingChat);
|
||||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void validateMessageTypeWithNoNormal() {
|
||||
DummyConnection dc = getConnection();
|
||||
ChatManager cm = ChatManager.getInstanceFor(dc);
|
||||
public void validateMessageTypeWithDefaults4() {
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.headline);
|
||||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateMessageTypeWithNoNormal1() {
|
||||
cm.setNormalIncluded(false);
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.chat);
|
||||
processServerMessage(incomingChat, dc);
|
||||
processServerMessage(incomingChat);
|
||||
assertNotNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
dc = getConnection();
|
||||
cm = ChatManager.getInstanceFor(dc);
|
||||
@Test
|
||||
public void validateMessageTypeWithNoNormal2() {
|
||||
cm.setNormalIncluded(false);
|
||||
listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
incomingChat = createChatPacket("134", true);
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.normal);
|
||||
processServerMessage(incomingChat, dc);
|
||||
processServerMessage(incomingChat);
|
||||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
|
@ -130,65 +136,59 @@ public class ChatConnectionTest {
|
|||
@Test
|
||||
public void chatMatchedOnJIDWhenNoThreadBareMode() {
|
||||
// MatchMode.BARE_JID is the default, so setting required.
|
||||
DummyConnection con = getConnection();
|
||||
TestMessageListener msgListener = new TestMessageListener();
|
||||
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
|
||||
ChatManager cm = ChatManager.getInstanceFor(con);
|
||||
cm.addChatListener(listener);
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat, con);
|
||||
processServerMessage(incomingChat);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
|
||||
// Should match on chat with full jid
|
||||
incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat, con);
|
||||
processServerMessage(incomingChat);
|
||||
assertEquals(2, msgListener.getNumMessages());
|
||||
|
||||
// Should match on chat with bare jid
|
||||
incomingChat = createChatPacket(null, false);
|
||||
processServerMessage(incomingChat, con);
|
||||
processServerMessage(incomingChat);
|
||||
assertEquals(3, msgListener.getNumMessages());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chatMatchedOnJIDWhenNoThreadJidMode() {
|
||||
DummyConnection con = getConnection();
|
||||
TestMessageListener msgListener = new TestMessageListener();
|
||||
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
|
||||
ChatManager cm = ChatManager.getInstanceFor(con);
|
||||
cm.setMatchMode(MatchMode.SUPPLIED_JID);
|
||||
cm.addChatListener(listener);
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat, con);
|
||||
processServerMessage(incomingChat);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
cm.removeChatListener(listener);
|
||||
|
||||
// Should match on chat with full jid
|
||||
incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat, con);
|
||||
processServerMessage(incomingChat);
|
||||
assertEquals(2, msgListener.getNumMessages());
|
||||
|
||||
// Should not match on chat with bare jid
|
||||
TestChatManagerListener listener2 = new TestChatManagerListener();
|
||||
cm.addChatListener(listener2);
|
||||
incomingChat = createChatPacket(null, false);
|
||||
processServerMessage(incomingChat, con);
|
||||
processServerMessage(incomingChat);
|
||||
assertEquals(2, msgListener.getNumMessages());
|
||||
assertNotNull(listener2.getNewChat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chatMatchedOnJIDWhenNoThreadNoneMode() {
|
||||
DummyConnection con = getConnection();
|
||||
TestMessageListener msgListener = new TestMessageListener();
|
||||
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
|
||||
ChatManager cm = ChatManager.getInstanceFor(con);
|
||||
cm.setMatchMode(MatchMode.NONE);
|
||||
cm.addChatListener(listener);
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat, con);
|
||||
processServerMessage(incomingChat);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertEquals(1, msgListener.getNumMessages());
|
||||
|
@ -198,7 +198,7 @@ public class ChatConnectionTest {
|
|||
TestChatManagerListener listener2 = new TestChatManagerListener();
|
||||
cm.addChatListener(listener2);
|
||||
incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat, con);
|
||||
processServerMessage(incomingChat);
|
||||
assertEquals(1, msgListener.getNumMessages());
|
||||
assertNotNull(newChat);
|
||||
cm.removeChatListener(listener2);
|
||||
|
@ -207,7 +207,7 @@ public class ChatConnectionTest {
|
|||
TestChatManagerListener listener3 = new TestChatManagerListener();
|
||||
cm.addChatListener(listener3);
|
||||
incomingChat = createChatPacket(null, false);
|
||||
processServerMessage(incomingChat, con);
|
||||
processServerMessage(incomingChat);
|
||||
assertEquals(1, msgListener.getNumMessages());
|
||||
assertNotNull(listener3.getNewChat());
|
||||
}
|
||||
|
@ -218,9 +218,6 @@ public class ChatConnectionTest {
|
|||
*/
|
||||
@Test
|
||||
public void chatFoundWhenNoThreadFullJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
ChatManager cm = ChatManager.getInstanceFor(connection);
|
||||
cm.addChatListener(listener);
|
||||
Chat outgoing = cm.createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
|
@ -237,9 +234,6 @@ public class ChatConnectionTest {
|
|||
*/
|
||||
@Test
|
||||
public void chatFoundWhenNoThreadBaseJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
ChatManager cm = ChatManager.getInstanceFor(connection);
|
||||
cm.addChatListener(listener);
|
||||
Chat outgoing = cm.createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(null, false);
|
||||
|
@ -256,9 +250,6 @@ public class ChatConnectionTest {
|
|||
*/
|
||||
@Test
|
||||
public void chatFoundWithSameThreadFullJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
ChatManager cm = ChatManager.getInstanceFor(connection);
|
||||
cm.addChatListener(listener);
|
||||
Chat outgoing = cm.createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID(), true);
|
||||
|
@ -275,9 +266,6 @@ public class ChatConnectionTest {
|
|||
*/
|
||||
@Test
|
||||
public void chatFoundWithSameThreadBaseJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
ChatManager cm = ChatManager.getInstanceFor(connection);
|
||||
cm.addChatListener(listener);
|
||||
Chat outgoing = cm.createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID(), false);
|
||||
|
@ -294,9 +282,6 @@ public class ChatConnectionTest {
|
|||
*/
|
||||
@Test
|
||||
public void chatNotFoundWithDiffThreadBaseJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
ChatManager cm = ChatManager.getInstanceFor(connection);
|
||||
cm.addChatListener(listener);
|
||||
Chat outgoing = cm.createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID() + "ff", false);
|
||||
|
@ -313,9 +298,6 @@ public class ChatConnectionTest {
|
|||
*/
|
||||
@Test
|
||||
public void chatNotFoundWithDiffThreadFullJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
ChatManager cm = ChatManager.getInstanceFor(connection);
|
||||
cm.addChatListener(listener);
|
||||
Chat outgoing = cm.createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID() + "ff", true);
|
||||
|
@ -328,11 +310,7 @@ public class ChatConnectionTest {
|
|||
|
||||
@Test
|
||||
public void chatNotMatchedWithTypeNormal() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
DummyConnection con = getConnection();
|
||||
ChatManager cm = ChatManager.getInstanceFor(con);
|
||||
cm.setNormalIncluded(false);
|
||||
cm.addChatListener(listener);
|
||||
|
||||
Message incomingChat = createChatPacket(null, false);
|
||||
incomingChat.setType(Type.normal);
|
||||
|
@ -341,50 +319,26 @@ public class ChatConnectionTest {
|
|||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private ChatManager getChatManager(boolean includeNormal, MatchMode mode) {
|
||||
ChatManager cm = ChatManager.getInstanceFor(getConnection());
|
||||
cm.setMatchMode(mode);
|
||||
cm.setNormalIncluded(includeNormal);
|
||||
return cm;
|
||||
}
|
||||
|
||||
private DummyConnection getConnection() {
|
||||
DummyConnection con = new DummyConnection();
|
||||
|
||||
try {
|
||||
con.connect();
|
||||
con.login();
|
||||
} catch (Exception e) {
|
||||
// No need for handling in a dummy connection.
|
||||
}
|
||||
return con;
|
||||
}
|
||||
private Message createChatPacket(final String threadId, final boolean isFullJid) {
|
||||
Message chatMsg = new Message("me@testserver", Message.Type.chat);
|
||||
chatMsg.setBody("the body message - " + System.currentTimeMillis());
|
||||
chatMsg.setFrom("you@testserver" + (isFullJid ? "/resource" : ""));
|
||||
|
||||
if (threadId != null)
|
||||
chatMsg.setThread(threadId);
|
||||
chatMsg.setThread(threadId);
|
||||
return chatMsg;
|
||||
}
|
||||
|
||||
private void processServerMessage(Packet incomingChat) {
|
||||
processServerMessage(incomingChat, connection);
|
||||
}
|
||||
|
||||
private void processServerMessage(Packet incomingChat, DummyConnection con) {
|
||||
TestChatServer chatServer = new TestChatServer(incomingChat, con);
|
||||
TestChatServer chatServer = new TestChatServer(incomingChat, dc);
|
||||
chatServer.start();
|
||||
try {
|
||||
chatServer.join();
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
}
|
||||
waitListener.waitAndReset();
|
||||
}
|
||||
|
||||
class TestChatManagerListener implements ChatManagerListener {
|
||||
class TestChatManagerListener extends WaitForPacketListener implements ChatManagerListener {
|
||||
private Chat newChat;
|
||||
private ChatMessageListener listener;
|
||||
|
||||
|
@ -401,6 +355,7 @@ public class ChatConnectionTest {
|
|||
|
||||
if (listener != null)
|
||||
newChat.addMessageListener(listener);
|
||||
reportInvoked();
|
||||
}
|
||||
|
||||
public Chat getNewChat() {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
@ -189,7 +190,7 @@ public class DummyConnection extends AbstractXMPPConnection {
|
|||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <P extends TopLevelStreamElement> P getSentPacket() throws InterruptedException {
|
||||
return (P) queue.poll();
|
||||
return (P) queue.poll(5, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -221,6 +222,18 @@ public class DummyConnection extends AbstractXMPPConnection {
|
|||
invokePacketCollectorsAndNotifyRecvListeners(packet);
|
||||
}
|
||||
|
||||
public static DummyConnection newConnectedDummyConnection() {
|
||||
DummyConnection dummyConnection = new DummyConnection();
|
||||
try {
|
||||
dummyConnection.connect();
|
||||
dummyConnection.login();
|
||||
}
|
||||
catch (SmackException | IOException | XMPPException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return dummyConnection;
|
||||
}
|
||||
|
||||
public static class DummyConnectionConfiguration extends ConnectionConfiguration {
|
||||
protected DummyConnectionConfiguration(Builder builder) {
|
||||
super(builder);
|
||||
|
|
|
@ -26,6 +26,7 @@ import static org.junit.Assert.fail;
|
|||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
|
@ -36,6 +37,7 @@ import org.jivesoftware.smack.packet.IQ.Type;
|
|||
import org.jivesoftware.smack.packet.RosterPacket.Item;
|
||||
import org.jivesoftware.smack.packet.RosterPacket.ItemType;
|
||||
import org.jivesoftware.smack.test.util.TestUtils;
|
||||
import org.jivesoftware.smack.test.util.WaitForPacketListener;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
@ -52,6 +54,7 @@ import org.xmlpull.v1.XmlPullParser;
|
|||
public class RosterTest {
|
||||
|
||||
private DummyConnection connection;
|
||||
private Roster roster;
|
||||
private TestRosterListener rosterListener;
|
||||
|
||||
@Before
|
||||
|
@ -63,7 +66,9 @@ public class RosterTest {
|
|||
connection.connect();
|
||||
connection.login();
|
||||
rosterListener = new TestRosterListener();
|
||||
connection.getRoster().addRosterListener(rosterListener);
|
||||
roster = connection.getRoster();
|
||||
roster.addRosterListener(rosterListener);
|
||||
connection.setPacketReplyTimeout(1000 * 60 * 5);
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -83,19 +88,17 @@ public class RosterTest {
|
|||
* <a href="http://xmpp.org/rfcs/rfc3921.html#roster-login"
|
||||
* >RFC3921: Retrieving One's Roster on Login</a>.
|
||||
*/
|
||||
@Test(timeout=5000)
|
||||
@Test
|
||||
public void testSimpleRosterInitialization() throws Exception {
|
||||
// Setup
|
||||
final Roster roster = connection.getRoster();
|
||||
assertNotNull("Can't get the roster from the provided connection!", roster);
|
||||
assertFalse("Roster shouldn't be already initialized!",
|
||||
roster.rosterInitialized);
|
||||
assertFalse("Roster shouldn't be already loaded!",
|
||||
roster.isLoaded());
|
||||
|
||||
// Perform roster initialization
|
||||
initRoster(connection, roster);
|
||||
initRoster();
|
||||
|
||||
// Verify roster
|
||||
assertTrue("Roster can't be initialized!", roster.rosterInitialized);
|
||||
assertTrue("Roster can't be loaded!", roster.waitUntilLoaded());
|
||||
verifyRomeosEntry(roster.getEntry("romeo@example.net"));
|
||||
verifyMercutiosEntry(roster.getEntry("mercutio@example.com"));
|
||||
verifyBenvoliosEntry(roster.getEntry("benvolio@example.net"));
|
||||
|
@ -121,7 +124,7 @@ public class RosterTest {
|
|||
* <a href="http://xmpp.org/rfcs/rfc3921.html#roster-add"
|
||||
* >RFC3921: Adding a Roster Item</a>.
|
||||
*/
|
||||
@Test(timeout=5000)
|
||||
@Test
|
||||
public void testAddRosterItem() throws Throwable {
|
||||
// Constants for the new contact
|
||||
final String contactJID = "nurse@example.com";
|
||||
|
@ -129,9 +132,8 @@ public class RosterTest {
|
|||
final String[] contactGroup = {"Servants"};
|
||||
|
||||
// Setup
|
||||
final Roster roster = connection.getRoster();
|
||||
assertNotNull("Can't get the roster from the provided connection!", roster);
|
||||
initRoster(connection, roster);
|
||||
initRoster();
|
||||
rosterListener.reset();
|
||||
|
||||
// Adding the new roster item
|
||||
|
@ -161,6 +163,7 @@ public class RosterTest {
|
|||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
rosterListener.waitUntilInvocationOrTimeout();
|
||||
|
||||
// Verify the roster entry of the new contact
|
||||
final RosterEntry addedEntry = roster.getEntry(contactJID);
|
||||
|
@ -192,7 +195,7 @@ public class RosterTest {
|
|||
* <a href="http://xmpp.org/rfcs/rfc3921.html#roster-update"
|
||||
* >RFC3921: Updating a Roster Item</a>.
|
||||
*/
|
||||
@Test(timeout=5000)
|
||||
@Test
|
||||
public void testUpdateRosterItem() throws Throwable {
|
||||
// Constants for the updated contact
|
||||
final String contactJID = "romeo@example.net";
|
||||
|
@ -200,9 +203,8 @@ public class RosterTest {
|
|||
final String[] contactGroups = {"Friends", "Lovers"};
|
||||
|
||||
// Setup
|
||||
final Roster roster = connection.getRoster();
|
||||
assertNotNull("Can't get the roster from the provided connection!", roster);
|
||||
initRoster(connection, roster);
|
||||
initRoster();
|
||||
rosterListener.reset();
|
||||
|
||||
// Updating the roster item
|
||||
|
@ -235,6 +237,7 @@ public class RosterTest {
|
|||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
rosterListener.waitUntilInvocationOrTimeout();
|
||||
|
||||
// Verify the roster entry of the updated contact
|
||||
final RosterEntry addedEntry = roster.getEntry(contactJID);
|
||||
|
@ -267,15 +270,14 @@ public class RosterTest {
|
|||
* <a href="http://xmpp.org/rfcs/rfc3921.html#roster-delete"
|
||||
* >RFC3921: Deleting a Roster Item</a>.
|
||||
*/
|
||||
@Test(timeout=5000)
|
||||
@Test
|
||||
public void testDeleteRosterItem() throws Throwable {
|
||||
// The contact which should be deleted
|
||||
final String contactJID = "romeo@example.net";
|
||||
|
||||
// Setup
|
||||
final Roster roster = connection.getRoster();
|
||||
assertNotNull("Can't get the roster from the provided connection!", roster);
|
||||
initRoster(connection, roster);
|
||||
initRoster();
|
||||
rosterListener.reset();
|
||||
|
||||
// Delete a roster item
|
||||
|
@ -296,6 +298,7 @@ public class RosterTest {
|
|||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
rosterListener.waitUntilInvocationOrTimeout();
|
||||
|
||||
// Verify
|
||||
final RosterEntry deletedEntry = roster.getEntry(contactJID);
|
||||
|
@ -314,10 +317,9 @@ public class RosterTest {
|
|||
* <a href="http://xmpp.org/internet-drafts/draft-ietf-xmpp-3921bis-03.html#roster-syntax-actions-push"
|
||||
* >RFC3921bis-03: Roster Push</a>.
|
||||
*/
|
||||
@Test(timeout=5000)
|
||||
@Test
|
||||
public void testSimpleRosterPush() throws Throwable {
|
||||
final String contactJID = "nurse@example.com";
|
||||
final Roster roster = connection.getRoster();
|
||||
assertNotNull("Can't get the roster from the provided connection!", roster);
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("<iq id=\"rostertest1\" type=\"set\" ")
|
||||
|
@ -328,11 +330,12 @@ public class RosterTest {
|
|||
.append("</iq>");
|
||||
final XmlPullParser parser = TestUtils.getIQParser(sb.toString());
|
||||
final IQ rosterPush = PacketParserUtils.parse(parser, connection);
|
||||
initRoster(connection, roster);
|
||||
initRoster();
|
||||
rosterListener.reset();
|
||||
|
||||
// Simulate receiving the roster push
|
||||
connection.processPacket(rosterPush);
|
||||
rosterListener.waitUntilInvocationOrTimeout();
|
||||
|
||||
// Verify the roster entry of the new contact
|
||||
final RosterEntry addedEntry = roster.getEntry(contactJID);
|
||||
|
@ -358,7 +361,7 @@ public class RosterTest {
|
|||
*
|
||||
* @see <a href="http://xmpp.org/rfcs/rfc6121.html#roster-syntax-actions-push">RFC 6121, Section 2.1.6</a>
|
||||
*/
|
||||
@Test(timeout=5000)
|
||||
@Test
|
||||
public void testIgnoreInvalidFrom() {
|
||||
RosterPacket packet = new RosterPacket();
|
||||
packet.setType(Type.set);
|
||||
|
@ -366,8 +369,11 @@ public class RosterTest {
|
|||
packet.setFrom("mallory@example.com");
|
||||
packet.addRosterItem(new Item("spam@example.com", "Cool products!"));
|
||||
|
||||
WaitForPacketListener waitForPacketListener = new WaitForPacketListener();
|
||||
connection.addAsyncPacketListener(waitForPacketListener, null);
|
||||
// Simulate receiving the roster push
|
||||
connection.processPacket(packet);
|
||||
waitForPacketListener.waitUntilInvocationOrTimeout();
|
||||
|
||||
assertNull("Contact was added to roster", connection.getRoster().getEntry("spam@example.com"));
|
||||
}
|
||||
|
@ -386,9 +392,8 @@ public class RosterTest {
|
|||
final String[] contactGroup = {""};
|
||||
|
||||
// Setup
|
||||
final Roster roster = connection.getRoster();
|
||||
assertNotNull("Can't get the roster from the provided connection!", roster);
|
||||
initRoster(connection, roster);
|
||||
initRoster();
|
||||
rosterListener.reset();
|
||||
|
||||
// Adding the new roster item
|
||||
|
@ -416,6 +421,7 @@ public class RosterTest {
|
|||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
rosterListener.waitUntilInvocationOrTimeout();
|
||||
|
||||
// Verify the roster entry of the new contact
|
||||
final RosterEntry addedEntry = roster.getEntry(contactJID);
|
||||
|
@ -445,10 +451,9 @@ public class RosterTest {
|
|||
*
|
||||
* @see <a href="http://www.igniterealtime.org/issues/browse/SMACK-294">SMACK-294</a>
|
||||
*/
|
||||
@Test(timeout=5000)
|
||||
@Test
|
||||
public void testEmptyGroupRosterPush() throws Throwable {
|
||||
final String contactJID = "nurse@example.com";
|
||||
final Roster roster = connection.getRoster();
|
||||
assertNotNull("Can't get the roster from the provided connection!", roster);
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("<iq id=\"rostertest2\" type=\"set\" ")
|
||||
|
@ -461,11 +466,12 @@ public class RosterTest {
|
|||
.append("</iq>");
|
||||
final XmlPullParser parser = TestUtils.getIQParser(sb.toString());
|
||||
final IQ rosterPush = PacketParserUtils.parse(parser, connection);
|
||||
initRoster(connection, roster);
|
||||
initRoster();
|
||||
rosterListener.reset();
|
||||
|
||||
// Simulate receiving the roster push
|
||||
connection.processPacket(rosterPush);
|
||||
rosterListener.waitUntilInvocationOrTimeout();
|
||||
|
||||
// Verify the roster entry of the new contact
|
||||
final RosterEntry addedEntry = roster.getEntry(contactJID);
|
||||
|
@ -520,7 +526,7 @@ public class RosterTest {
|
|||
* @param roster the roster (or buddy list) which should be initialized.
|
||||
* @throws SmackException
|
||||
*/
|
||||
public static void initRoster(DummyConnection connection, Roster roster) throws InterruptedException, XMPPException, SmackException {
|
||||
private void initRoster() throws InterruptedException, XMPPException, SmackException {
|
||||
roster.reload();
|
||||
while (true) {
|
||||
final Packet sentPacket = connection.getSentPacket();
|
||||
|
@ -558,6 +564,8 @@ public class RosterTest {
|
|||
break;
|
||||
}
|
||||
}
|
||||
roster.waitUntilLoaded();
|
||||
rosterListener.waitUntilInvocationOrTimeout();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -687,10 +695,10 @@ public class RosterTest {
|
|||
/**
|
||||
* This class can be used to check if the RosterListener was invoked.
|
||||
*/
|
||||
public static class TestRosterListener implements RosterListener {
|
||||
private CopyOnWriteArrayList<String> addressesAdded = new CopyOnWriteArrayList<String>();
|
||||
private CopyOnWriteArrayList<String> addressesDeleted = new CopyOnWriteArrayList<String>();
|
||||
private CopyOnWriteArrayList<String> addressesUpdated = new CopyOnWriteArrayList<String>();
|
||||
public static class TestRosterListener extends WaitForPacketListener implements RosterListener {
|
||||
private final List<String> addressesAdded = new CopyOnWriteArrayList<>();
|
||||
private final List<String> addressesDeleted = new CopyOnWriteArrayList<>();
|
||||
private final List<String> addressesUpdated = new CopyOnWriteArrayList<>();
|
||||
|
||||
public synchronized void entriesAdded(Collection<String> addresses) {
|
||||
addressesAdded.addAll(addresses);
|
||||
|
@ -699,6 +707,7 @@ public class RosterTest {
|
|||
System.out.println("Roster entry for " + address + " added.");
|
||||
}
|
||||
}
|
||||
reportInvoked();
|
||||
}
|
||||
|
||||
public synchronized void entriesDeleted(Collection<String> addresses) {
|
||||
|
@ -708,6 +717,7 @@ public class RosterTest {
|
|||
System.out.println("Roster entry for " + address + " deleted.");
|
||||
}
|
||||
}
|
||||
reportInvoked();
|
||||
}
|
||||
|
||||
public synchronized void entriesUpdated(Collection<String> addresses) {
|
||||
|
@ -717,12 +727,14 @@ public class RosterTest {
|
|||
System.out.println("Roster entry for " + address + " updated.");
|
||||
}
|
||||
}
|
||||
reportInvoked();
|
||||
}
|
||||
|
||||
public void presenceChanged(Presence presence) {
|
||||
if (SmackConfiguration.DEBUG_ENABLED) {
|
||||
System.out.println("Roster presence changed: " + presence.toXML());
|
||||
}
|
||||
reportInvoked();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -756,6 +768,7 @@ public class RosterTest {
|
|||
* Reset the lists of added, deleted or updated items.
|
||||
*/
|
||||
public synchronized void reset() {
|
||||
super.reset();
|
||||
addressesAdded.clear();
|
||||
addressesDeleted.clear();
|
||||
addressesUpdated.clear();
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.util.Collection;
|
|||
import java.util.HashSet;
|
||||
|
||||
import org.jivesoftware.smack.ConnectionConfiguration.Builder;
|
||||
import org.jivesoftware.smack.RosterTest.TestRosterListener;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.IQ.Type;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
|
@ -53,15 +54,14 @@ import org.junit.rules.TemporaryFolder;
|
|||
public class RosterVersioningTest {
|
||||
|
||||
private DummyConnection connection;
|
||||
private Roster roster;
|
||||
private TestRosterListener rosterListener;
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder tmpFolder = new TemporaryFolder();
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
// Uncomment this to enable debug output
|
||||
//XMPPConnection.DEBUG_ENABLED = true;
|
||||
|
||||
DirectoryRosterStore store = DirectoryRosterStore.init(tmpFolder.newFolder("store"));
|
||||
populateStore(store);
|
||||
|
||||
|
@ -69,13 +69,20 @@ public class RosterVersioningTest {
|
|||
builder.setRosterStore(store);
|
||||
connection = new DummyConnection(builder.build());
|
||||
connection.connect();
|
||||
|
||||
connection.login();
|
||||
rosterListener = new TestRosterListener();
|
||||
roster = connection.getRoster();
|
||||
roster.addRosterListener(rosterListener);
|
||||
roster.reload();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (connection != null) {
|
||||
if (rosterListener != null && roster != null) {
|
||||
roster.removeRosterListener(rosterListener);
|
||||
rosterListener = null;
|
||||
}
|
||||
connection.disconnect();
|
||||
connection = null;
|
||||
}
|
||||
|
@ -89,10 +96,9 @@ public class RosterVersioningTest {
|
|||
*/
|
||||
@Test(timeout = 5000)
|
||||
public void testEqualVersionStored() throws InterruptedException, IOException, XMPPException, SmackException {
|
||||
connection.getRoster().reload();
|
||||
answerWithEmptyRosterResult();
|
||||
roster.waitUntilLoaded();
|
||||
|
||||
Roster roster = connection.getRoster();
|
||||
Collection<RosterEntry> entries = roster.getEntries();
|
||||
assertSame("Size of the roster", 3, entries.size());
|
||||
|
||||
|
@ -124,8 +130,6 @@ public class RosterVersioningTest {
|
|||
*/
|
||||
@Test(timeout = 5000)
|
||||
public void testOtherVersionStored() throws InterruptedException, XMPPException, SmackException {
|
||||
connection.getRoster().reload();
|
||||
|
||||
Item vaglafItem = vaglafItem();
|
||||
|
||||
// We expect that the roster request is the only packet sent. This is not part of the specification,
|
||||
|
@ -141,7 +145,9 @@ public class RosterVersioningTest {
|
|||
answer.setVersion("newVersion");
|
||||
answer.addRosterItem(vaglafItem);
|
||||
|
||||
rosterListener.reset();
|
||||
connection.processPacket(answer);
|
||||
rosterListener.waitUntilInvocationOrTimeout();
|
||||
} else {
|
||||
assertTrue("Expected to get a RosterPacket ", false);
|
||||
}
|
||||
|
@ -164,11 +170,10 @@ public class RosterVersioningTest {
|
|||
*/
|
||||
@Test(timeout = 5000)
|
||||
public void testRosterVersioningWithCachedRosterAndPushes() throws Throwable {
|
||||
connection.getRoster().reload();
|
||||
answerWithEmptyRosterResult();
|
||||
rosterListener.waitAndReset();
|
||||
|
||||
RosterStore store = connection.getConfiguration().getRosterStore();
|
||||
Roster roster = connection.getRoster();
|
||||
|
||||
// Simulate a roster push adding vaglaf
|
||||
{
|
||||
|
@ -179,7 +184,9 @@ public class RosterVersioningTest {
|
|||
|
||||
Item pushedItem = vaglafItem();
|
||||
rosterPush.addRosterItem(pushedItem);
|
||||
rosterListener.reset();
|
||||
connection.processPacket(rosterPush);
|
||||
rosterListener.waitAndReset();
|
||||
|
||||
assertEquals("Expect store version after push", "v97", store.getRosterVersion());
|
||||
|
||||
|
@ -204,7 +211,9 @@ public class RosterVersioningTest {
|
|||
Item item = new Item("vaglaf@example.com", "vaglaf the only");
|
||||
item.setItemType(ItemType.remove);
|
||||
rosterPush.addRosterItem(item);
|
||||
rosterListener.reset();
|
||||
connection.processPacket(rosterPush);
|
||||
rosterListener.waitAndReset();
|
||||
|
||||
assertNull("Store doses not contain vaglaf", store.getEntry("vaglaf@example.com"));
|
||||
assertEquals("Expect store version after push", "v98", store.getRosterVersion());
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2015 Florian Schmaus
|
||||
*
|
||||
* Licensed 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.jivesoftware.smack.test.util;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jivesoftware.smack.PacketListener;
|
||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
|
||||
public class WaitForPacketListener implements PacketListener {
|
||||
|
||||
private CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
@Override
|
||||
public void processPacket(Packet packet) throws NotConnectedException {
|
||||
reportInvoked();
|
||||
}
|
||||
|
||||
protected void reportInvoked() {
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
public void waitAndReset() {
|
||||
waitUntilInvocationOrTimeout();
|
||||
reset();
|
||||
}
|
||||
|
||||
public void waitUntilInvocationOrTimeout() {
|
||||
try {
|
||||
boolean res = latch.await(30, TimeUnit.SECONDS);
|
||||
if (!res) {
|
||||
throw new IllegalStateException("Latch timed out before it reached zero");
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
// TODO better handling of spurious interrupts
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
latch = new CountDownLatch(1);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue