mirror of
https://github.com/vanitasvitae/Smack.git
synced 2025-09-10 01:29:38 +02:00
Create smack-im subproject for XMPP-IM
Move Roster and Chat(Manager) code into their own packages within the new smack-im subproject. Apply Manager pattern to Roster. Fixes SMACK-637.
This commit is contained in:
parent
e722018808
commit
d5b8647d9d
47 changed files with 392 additions and 271 deletions
|
@ -1,400 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2010 Jive Software.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
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 dc;
|
||||
private ChatManager cm;
|
||||
private TestChatManagerListener listener;
|
||||
private WaitForPacketListener waitListener;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
// 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 (dc != null) {
|
||||
dc.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDefaultSetNormalIncludedFalse() {
|
||||
ChatManager.setDefaultIsNormalIncluded(false);
|
||||
assertFalse(ChatManager.getInstanceFor(new DummyConnection()).isNormalIncluded());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDefaultSetNormalIncludedTrue() {
|
||||
ChatManager.setDefaultIsNormalIncluded(true);
|
||||
assertTrue(ChatManager.getInstanceFor(new DummyConnection()).isNormalIncluded());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDefaultSetMatchModeNone() {
|
||||
ChatManager.setDefaultMatchMode(MatchMode.NONE);
|
||||
assertEquals(MatchMode.NONE, ChatManager.getInstanceFor(new DummyConnection()).getMatchMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDefaultSetMatchModeBareJid() {
|
||||
ChatManager.setDefaultMatchMode(MatchMode.BARE_JID);
|
||||
assertEquals(MatchMode.BARE_JID, ChatManager.getInstanceFor(new DummyConnection()).getMatchMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateMessageTypeWithDefaults1() {
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.chat);
|
||||
processServerMessage(incomingChat);
|
||||
assertNotNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateMessageTypeWithDefaults2() {
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.normal);
|
||||
processServerMessage(incomingChat);
|
||||
assertNotNull(listener.getNewChat());
|
||||
}
|
||||
@Test
|
||||
public void validateMessageTypeWithDefaults3() {
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.groupchat);
|
||||
processServerMessage(incomingChat);
|
||||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateMessageTypeWithDefaults4() {
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.headline);
|
||||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateMessageTypeWithNoNormal1() {
|
||||
cm.setNormalIncluded(false);
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.chat);
|
||||
processServerMessage(incomingChat);
|
||||
assertNotNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateMessageTypeWithNoNormal2() {
|
||||
cm.setNormalIncluded(false);
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.normal);
|
||||
processServerMessage(incomingChat);
|
||||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
// No thread behaviour
|
||||
@Test
|
||||
public void chatMatchedOnJIDWhenNoThreadBareMode() {
|
||||
// MatchMode.BARE_JID is the default, so setting required.
|
||||
TestMessageListener msgListener = new TestMessageListener();
|
||||
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
|
||||
cm.addChatListener(listener);
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
|
||||
// Should match on chat with full jid
|
||||
incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
assertEquals(2, msgListener.getNumMessages());
|
||||
|
||||
// Should match on chat with bare jid
|
||||
incomingChat = createChatPacket(null, false);
|
||||
processServerMessage(incomingChat);
|
||||
assertEquals(3, msgListener.getNumMessages());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chatMatchedOnJIDWhenNoThreadJidMode() {
|
||||
TestMessageListener msgListener = new TestMessageListener();
|
||||
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
|
||||
cm.setMatchMode(MatchMode.SUPPLIED_JID);
|
||||
cm.addChatListener(listener);
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
cm.removeChatListener(listener);
|
||||
|
||||
// Should match on chat with full jid
|
||||
incomingChat = createChatPacket(null, true);
|
||||
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);
|
||||
assertEquals(2, msgListener.getNumMessages());
|
||||
assertNotNull(listener2.getNewChat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chatMatchedOnJIDWhenNoThreadNoneMode() {
|
||||
TestMessageListener msgListener = new TestMessageListener();
|
||||
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
|
||||
cm.setMatchMode(MatchMode.NONE);
|
||||
cm.addChatListener(listener);
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertEquals(1, msgListener.getNumMessages());
|
||||
cm.removeChatListener(listener);
|
||||
|
||||
// Should not match on chat with full jid
|
||||
TestChatManagerListener listener2 = new TestChatManagerListener();
|
||||
cm.addChatListener(listener2);
|
||||
incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
assertEquals(1, msgListener.getNumMessages());
|
||||
assertNotNull(newChat);
|
||||
cm.removeChatListener(listener2);
|
||||
|
||||
// Should not match on chat with bare jid
|
||||
TestChatManagerListener listener3 = new TestChatManagerListener();
|
||||
cm.addChatListener(listener3);
|
||||
incomingChat = createChatPacket(null, false);
|
||||
processServerMessage(incomingChat);
|
||||
assertEquals(1, msgListener.getNumMessages());
|
||||
assertNotNull(listener3.getNewChat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has no thread
|
||||
* id and the user is a full jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatFoundWhenNoThreadFullJid() {
|
||||
Chat outgoing = cm.createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has no thread
|
||||
* id and the user is a base jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatFoundWhenNoThreadBaseJid() {
|
||||
Chat outgoing = cm.createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(null, false);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has the same id
|
||||
* and the user is a full jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatFoundWithSameThreadFullJid() {
|
||||
Chat outgoing = cm.createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID(), true);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has the same id
|
||||
* and the user is a base jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatFoundWithSameThreadBaseJid() {
|
||||
Chat outgoing = cm.createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID(), false);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is not matched to an incoming chat message that has a
|
||||
* different id and the same user as a base jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatNotFoundWithDiffThreadBaseJid() {
|
||||
Chat outgoing = cm.createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID() + "ff", false);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertFalse(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is not matched to an incoming chat message that has a
|
||||
* different id and the same base jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatNotFoundWithDiffThreadFullJid() {
|
||||
Chat outgoing = cm.createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID() + "ff", true);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertFalse(newChat == outgoing);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chatNotMatchedWithTypeNormal() {
|
||||
cm.setNormalIncluded(false);
|
||||
|
||||
Message incomingChat = createChatPacket(null, false);
|
||||
incomingChat.setType(Type.normal);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
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" : ""));
|
||||
chatMsg.setThread(threadId);
|
||||
return chatMsg;
|
||||
}
|
||||
|
||||
private void processServerMessage(Packet incomingChat) {
|
||||
TestChatServer chatServer = new TestChatServer(incomingChat, dc);
|
||||
chatServer.start();
|
||||
try {
|
||||
chatServer.join();
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
}
|
||||
waitListener.waitAndReset();
|
||||
}
|
||||
|
||||
class TestChatManagerListener extends WaitForPacketListener implements ChatManagerListener {
|
||||
private Chat newChat;
|
||||
private ChatMessageListener listener;
|
||||
|
||||
public TestChatManagerListener(TestMessageListener msgListener) {
|
||||
listener = msgListener;
|
||||
}
|
||||
|
||||
public TestChatManagerListener() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void chatCreated(Chat chat, boolean createdLocally) {
|
||||
newChat = chat;
|
||||
|
||||
if (listener != null)
|
||||
newChat.addMessageListener(listener);
|
||||
reportInvoked();
|
||||
}
|
||||
|
||||
public Chat getNewChat() {
|
||||
return newChat;
|
||||
}
|
||||
}
|
||||
|
||||
private class TestChatServer extends Thread {
|
||||
private Packet chatPacket;
|
||||
private DummyConnection con;
|
||||
|
||||
TestChatServer(Packet chatMsg, DummyConnection conect) {
|
||||
chatPacket = chatMsg;
|
||||
con = conect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
con.processPacket(chatPacket);
|
||||
}
|
||||
}
|
||||
|
||||
private class TestMessageListener implements ChatMessageListener {
|
||||
private Chat msgChat;
|
||||
private int counter = 0;
|
||||
|
||||
@Override
|
||||
public void processMessage(Chat chat, Message message) {
|
||||
msgChat = chat;
|
||||
counter++;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public Chat getChat() {
|
||||
return msgChat;
|
||||
}
|
||||
|
||||
public int getNumMessages() {
|
||||
return counter;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -49,7 +49,6 @@ public class DummyConnection extends AbstractXMPPConnection {
|
|||
private boolean reconnect = false;
|
||||
|
||||
private String connectionID;
|
||||
private Roster roster;
|
||||
|
||||
private final BlockingQueue<TopLevelStreamElement> queue = new LinkedBlockingQueue<TopLevelStreamElement>();
|
||||
|
||||
|
@ -89,7 +88,6 @@ public class DummyConnection extends AbstractXMPPConnection {
|
|||
protected void shutdown() {
|
||||
user = null;
|
||||
connectionID = null;
|
||||
roster = null;
|
||||
authenticated = false;
|
||||
|
||||
callConnectionClosedListener();
|
||||
|
@ -107,17 +105,6 @@ public class DummyConnection extends AbstractXMPPConnection {
|
|||
return connectionID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Roster getRoster() {
|
||||
if (isAnonymous()) {
|
||||
return null;
|
||||
}
|
||||
if (roster == null) {
|
||||
roster = new Roster(this);
|
||||
}
|
||||
return roster;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecureConnection() {
|
||||
return false;
|
||||
|
@ -136,7 +123,6 @@ public class DummyConnection extends AbstractXMPPConnection {
|
|||
+ config.getServiceName()
|
||||
+ "/"
|
||||
+ (resource != null ? resource : "Test");
|
||||
roster = new Roster(this);
|
||||
authenticated = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,783 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2010 Jive Software.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
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.ErrorIQ;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.packet.RosterPacket;
|
||||
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.packet.XMPPError.Condition;
|
||||
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;
|
||||
import org.junit.Test;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
* Tests that verifies the correct behavior of the {@link Roster} implementation.
|
||||
*
|
||||
* @see Roster
|
||||
* @see <a href="http://xmpp.org/rfcs/rfc3921.html#roster">Roster Management</a>
|
||||
* @author Guenther Niess
|
||||
*/
|
||||
public class RosterTest {
|
||||
|
||||
private DummyConnection connection;
|
||||
private Roster roster;
|
||||
private TestRosterListener rosterListener;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
// Uncomment this to enable debug output
|
||||
//SmackConfiguration.DEBUG = true;
|
||||
|
||||
connection = new DummyConnection();
|
||||
connection.connect();
|
||||
connection.login();
|
||||
rosterListener = new TestRosterListener();
|
||||
roster = connection.getRoster();
|
||||
roster.addRosterListener(rosterListener);
|
||||
connection.setPacketReplyTimeout(1000 * 60 * 5);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (connection != null) {
|
||||
if (rosterListener != null && connection.getRoster() != null) {
|
||||
connection.getRoster().removeRosterListener(rosterListener);
|
||||
rosterListener = null;
|
||||
}
|
||||
connection.disconnect();
|
||||
connection = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a simple roster initialization according to the example in
|
||||
* <a href="http://xmpp.org/rfcs/rfc3921.html#roster-login"
|
||||
* >RFC3921: Retrieving One's Roster on Login</a>.
|
||||
*/
|
||||
@Test
|
||||
public void testSimpleRosterInitialization() throws Exception {
|
||||
assertNotNull("Can't get the roster from the provided connection!", roster);
|
||||
assertFalse("Roster shouldn't be already loaded!",
|
||||
roster.isLoaded());
|
||||
|
||||
// Perform roster initialization
|
||||
initRoster();
|
||||
|
||||
// Verify roster
|
||||
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"));
|
||||
assertSame("Wrong number of roster entries.", 3, roster.getEntries().size());
|
||||
|
||||
// Verify roster listener
|
||||
assertTrue("The roster listener wasn't invoked for Romeo.",
|
||||
rosterListener.getAddedAddresses().contains("romeo@example.net"));
|
||||
assertTrue("The roster listener wasn't invoked for Mercutio.",
|
||||
rosterListener.getAddedAddresses().contains("mercutio@example.com"));
|
||||
assertTrue("The roster listener wasn't invoked for Benvolio.",
|
||||
rosterListener.getAddedAddresses().contains("benvolio@example.net"));
|
||||
assertSame("RosterListeners implies that a item was deleted!",
|
||||
0,
|
||||
rosterListener.getDeletedAddresses().size());
|
||||
assertSame("RosterListeners implies that a item was updated!",
|
||||
0,
|
||||
rosterListener.getUpdatedAddresses().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test adding a roster item according to the example in
|
||||
* <a href="http://xmpp.org/rfcs/rfc3921.html#roster-add"
|
||||
* >RFC3921: Adding a Roster Item</a>.
|
||||
*/
|
||||
@Test
|
||||
public void testAddRosterItem() throws Throwable {
|
||||
// Constants for the new contact
|
||||
final String contactJID = "nurse@example.com";
|
||||
final String contactName = "Nurse";
|
||||
final String[] contactGroup = {"Servants"};
|
||||
|
||||
// Setup
|
||||
assertNotNull("Can't get the roster from the provided connection!", roster);
|
||||
initRoster();
|
||||
rosterListener.reset();
|
||||
|
||||
// Adding the new roster item
|
||||
final RosterUpdateResponder serverSimulator = new RosterUpdateResponder() {
|
||||
void verifyUpdateRequest(final RosterPacket updateRequest) {
|
||||
final Item item = updateRequest.getRosterItems().iterator().next();
|
||||
assertSame("The provided JID doesn't match the requested!",
|
||||
contactJID,
|
||||
item.getUser());
|
||||
assertSame("The provided name doesn't match the requested!",
|
||||
contactName,
|
||||
item.getName());
|
||||
assertSame("The provided group number doesn't match the requested!",
|
||||
contactGroup.length,
|
||||
item.getGroupNames().size());
|
||||
assertSame("The provided group doesn't match the requested!",
|
||||
contactGroup[0],
|
||||
item.getGroupNames().iterator().next());
|
||||
}
|
||||
};
|
||||
serverSimulator.start();
|
||||
roster.createEntry(contactJID, contactName, contactGroup);
|
||||
serverSimulator.join();
|
||||
|
||||
// Check if an error occurred within the simulator
|
||||
final Throwable exception = serverSimulator.getException();
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
rosterListener.waitUntilInvocationOrTimeout();
|
||||
|
||||
// Verify the roster entry of the new contact
|
||||
final RosterEntry addedEntry = roster.getEntry(contactJID);
|
||||
assertNotNull("The new contact wasn't added to the roster!", addedEntry);
|
||||
assertTrue("The roster listener wasn't invoked for the new contact!",
|
||||
rosterListener.getAddedAddresses().contains(contactJID));
|
||||
assertSame("Setup wrong name for the new contact!",
|
||||
contactName,
|
||||
addedEntry.getName());
|
||||
assertSame("Setup wrong default subscription status!",
|
||||
ItemType.none,
|
||||
addedEntry.getType());
|
||||
assertSame("The new contact should be member of exactly one group!",
|
||||
1,
|
||||
addedEntry.getGroups().size());
|
||||
assertSame("Setup wrong group name for the added contact!",
|
||||
contactGroup[0],
|
||||
addedEntry.getGroups().iterator().next().getName());
|
||||
|
||||
// Verify the unchanged roster items
|
||||
verifyRomeosEntry(roster.getEntry("romeo@example.net"));
|
||||
verifyMercutiosEntry(roster.getEntry("mercutio@example.com"));
|
||||
verifyBenvoliosEntry(roster.getEntry("benvolio@example.net"));
|
||||
assertSame("Wrong number of roster entries.", 4, roster.getEntries().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test updating a roster item according to the example in
|
||||
* <a href="http://xmpp.org/rfcs/rfc3921.html#roster-update"
|
||||
* >RFC3921: Updating a Roster Item</a>.
|
||||
*/
|
||||
@Test
|
||||
public void testUpdateRosterItem() throws Throwable {
|
||||
// Constants for the updated contact
|
||||
final String contactJID = "romeo@example.net";
|
||||
final String contactName = "Romeo";
|
||||
final String[] contactGroups = {"Friends", "Lovers"};
|
||||
|
||||
// Setup
|
||||
assertNotNull("Can't get the roster from the provided connection!", roster);
|
||||
initRoster();
|
||||
rosterListener.reset();
|
||||
|
||||
// Updating the roster item
|
||||
final RosterUpdateResponder serverSimulator = new RosterUpdateResponder() {
|
||||
void verifyUpdateRequest(final RosterPacket updateRequest) {
|
||||
final Item item = updateRequest.getRosterItems().iterator().next();
|
||||
assertSame("The provided JID doesn't match the requested!",
|
||||
contactJID,
|
||||
item.getUser());
|
||||
assertSame("The provided name doesn't match the requested!",
|
||||
contactName,
|
||||
item.getName());
|
||||
assertTrue("The updated contact doesn't belong to the requested groups ("
|
||||
+ contactGroups[0] +")!",
|
||||
item.getGroupNames().contains(contactGroups[0]));
|
||||
assertTrue("The updated contact doesn't belong to the requested groups ("
|
||||
+ contactGroups[1] +")!",
|
||||
item.getGroupNames().contains(contactGroups[1]));
|
||||
assertSame("The provided group number doesn't match the requested!",
|
||||
contactGroups.length,
|
||||
item.getGroupNames().size());
|
||||
}
|
||||
};
|
||||
serverSimulator.start();
|
||||
roster.createGroup(contactGroups[1]).addEntry(roster.getEntry(contactJID));
|
||||
serverSimulator.join();
|
||||
|
||||
// Check if an error occurred within the simulator
|
||||
final Throwable exception = serverSimulator.getException();
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
rosterListener.waitUntilInvocationOrTimeout();
|
||||
|
||||
// Verify the roster entry of the updated contact
|
||||
final RosterEntry addedEntry = roster.getEntry(contactJID);
|
||||
assertNotNull("The contact was deleted from the roster!", addedEntry);
|
||||
assertTrue("The roster listener wasn't invoked for the updated contact!",
|
||||
rosterListener.getUpdatedAddresses().contains(contactJID));
|
||||
assertSame("Setup wrong name for the changed contact!",
|
||||
contactName,
|
||||
addedEntry.getName());
|
||||
assertTrue("The updated contact doesn't belong to the requested groups ("
|
||||
+ contactGroups[0] +")!",
|
||||
roster.getGroup(contactGroups[0]).contains(addedEntry));
|
||||
assertTrue("The updated contact doesn't belong to the requested groups ("
|
||||
+ contactGroups[1] +")!",
|
||||
roster.getGroup(contactGroups[1]).contains(addedEntry));
|
||||
assertSame("The updated contact should be member of two groups!",
|
||||
contactGroups.length,
|
||||
addedEntry.getGroups().size());
|
||||
|
||||
// Verify the unchanged roster items
|
||||
verifyMercutiosEntry(roster.getEntry("mercutio@example.com"));
|
||||
verifyBenvoliosEntry(roster.getEntry("benvolio@example.net"));
|
||||
assertSame("Wrong number of roster entries (" + roster.getEntries() + ").",
|
||||
3,
|
||||
roster.getEntries().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test deleting a roster item according to the example in
|
||||
* <a href="http://xmpp.org/rfcs/rfc3921.html#roster-delete"
|
||||
* >RFC3921: Deleting a Roster Item</a>.
|
||||
*/
|
||||
@Test
|
||||
public void testDeleteRosterItem() throws Throwable {
|
||||
// The contact which should be deleted
|
||||
final String contactJID = "romeo@example.net";
|
||||
|
||||
// Setup
|
||||
assertNotNull("Can't get the roster from the provided connection!", roster);
|
||||
initRoster();
|
||||
rosterListener.reset();
|
||||
|
||||
// Delete a roster item
|
||||
final RosterUpdateResponder serverSimulator = new RosterUpdateResponder() {
|
||||
void verifyUpdateRequest(final RosterPacket updateRequest) {
|
||||
final Item item = updateRequest.getRosterItems().iterator().next();
|
||||
assertSame("The provided JID doesn't match the requested!",
|
||||
contactJID,
|
||||
item.getUser());
|
||||
}
|
||||
};
|
||||
serverSimulator.start();
|
||||
roster.removeEntry(roster.getEntry(contactJID));
|
||||
serverSimulator.join();
|
||||
|
||||
// Check if an error occurred within the simulator
|
||||
final Throwable exception = serverSimulator.getException();
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
rosterListener.waitUntilInvocationOrTimeout();
|
||||
|
||||
// Verify
|
||||
final RosterEntry deletedEntry = roster.getEntry(contactJID);
|
||||
assertNull("The contact wasn't deleted from the roster!", deletedEntry);
|
||||
assertTrue("The roster listener wasn't invoked for the deleted contact!",
|
||||
rosterListener.getDeletedAddresses().contains(contactJID));
|
||||
verifyMercutiosEntry(roster.getEntry("mercutio@example.com"));
|
||||
verifyBenvoliosEntry(roster.getEntry("benvolio@example.net"));
|
||||
assertSame("Wrong number of roster entries (" + roster.getEntries() + ").",
|
||||
2,
|
||||
roster.getEntries().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a simple roster push according to the example in
|
||||
* <a href="http://xmpp.org/internet-drafts/draft-ietf-xmpp-3921bis-03.html#roster-syntax-actions-push"
|
||||
* >RFC3921bis-03: Roster Push</a>.
|
||||
*/
|
||||
@Test
|
||||
public void testSimpleRosterPush() throws Throwable {
|
||||
final String contactJID = "nurse@example.com";
|
||||
assertNotNull("Can't get the roster from the provided connection!", roster);
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("<iq id=\"rostertest1\" type=\"set\" ")
|
||||
.append("to=\"").append(connection.getUser()).append("\">")
|
||||
.append("<query xmlns=\"jabber:iq:roster\">")
|
||||
.append("<item jid=\"").append(contactJID).append("\"/>")
|
||||
.append("</query>")
|
||||
.append("</iq>");
|
||||
final XmlPullParser parser = TestUtils.getIQParser(sb.toString());
|
||||
final IQ rosterPush = PacketParserUtils.parseIQ(parser);
|
||||
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);
|
||||
assertNotNull("The new contact wasn't added to the roster!", addedEntry);
|
||||
assertTrue("The roster listener wasn't invoked for the new contact!",
|
||||
rosterListener.getAddedAddresses().contains(contactJID));
|
||||
assertSame("Setup wrong default subscription status!",
|
||||
ItemType.none,
|
||||
addedEntry.getType());
|
||||
assertSame("The new contact shouldn't be member of any group!",
|
||||
0,
|
||||
addedEntry.getGroups().size());
|
||||
|
||||
// Verify the unchanged roster items
|
||||
verifyRomeosEntry(roster.getEntry("romeo@example.net"));
|
||||
verifyMercutiosEntry(roster.getEntry("mercutio@example.com"));
|
||||
verifyBenvoliosEntry(roster.getEntry("benvolio@example.net"));
|
||||
assertSame("Wrong number of roster entries.", 4, roster.getEntries().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that roster pushes with invalid from are ignored.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/rfcs/rfc6121.html#roster-syntax-actions-push">RFC 6121, Section 2.1.6</a>
|
||||
*/
|
||||
@Test
|
||||
public void testIgnoreInvalidFrom() {
|
||||
RosterPacket packet = new RosterPacket();
|
||||
packet.setType(Type.set);
|
||||
packet.setTo(connection.getUser());
|
||||
packet.setFrom("mallory@example.com");
|
||||
packet.addRosterItem(new Item("spam@example.com", "Cool products!"));
|
||||
|
||||
final String requestId = packet.getPacketID();
|
||||
// Simulate receiving the roster push
|
||||
connection.processPacket(packet);
|
||||
|
||||
// Smack should reply with an error IQ
|
||||
ErrorIQ errorIQ = (ErrorIQ) connection.getSentPacket();
|
||||
assertEquals(requestId, errorIQ.getPacketID());
|
||||
assertEquals(Condition.service_unavailable, errorIQ.getError().getCondition());
|
||||
|
||||
assertNull("Contact was added to roster", connection.getRoster().getEntry("spam@example.com"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if adding an user with an empty group is equivalent with providing
|
||||
* no group.
|
||||
*
|
||||
* @see <a href="http://www.igniterealtime.org/issues/browse/SMACK-294">SMACK-294</a>
|
||||
*/
|
||||
@Test(timeout=5000)
|
||||
public void testAddEmptyGroupEntry() throws Throwable {
|
||||
// Constants for the new contact
|
||||
final String contactJID = "nurse@example.com";
|
||||
final String contactName = "Nurse";
|
||||
final String[] contactGroup = {""};
|
||||
|
||||
// Setup
|
||||
assertNotNull("Can't get the roster from the provided connection!", roster);
|
||||
initRoster();
|
||||
rosterListener.reset();
|
||||
|
||||
// Adding the new roster item
|
||||
final RosterUpdateResponder serverSimulator = new RosterUpdateResponder() {
|
||||
void verifyUpdateRequest(final RosterPacket updateRequest) {
|
||||
final Item item = updateRequest.getRosterItems().iterator().next();
|
||||
assertSame("The provided JID doesn't match the requested!",
|
||||
contactJID,
|
||||
item.getUser());
|
||||
assertSame("The provided name doesn't match the requested!",
|
||||
contactName,
|
||||
item.getName());
|
||||
assertSame("Shouldn't provide an empty group element!",
|
||||
0,
|
||||
item.getGroupNames().size());
|
||||
|
||||
}
|
||||
};
|
||||
serverSimulator.start();
|
||||
roster.createEntry(contactJID, contactName, contactGroup);
|
||||
serverSimulator.join();
|
||||
|
||||
// Check if an error occurred within the simulator
|
||||
final Throwable exception = serverSimulator.getException();
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
rosterListener.waitUntilInvocationOrTimeout();
|
||||
|
||||
// Verify the roster entry of the new contact
|
||||
final RosterEntry addedEntry = roster.getEntry(contactJID);
|
||||
assertNotNull("The new contact wasn't added to the roster!", addedEntry);
|
||||
assertTrue("The roster listener wasn't invoked for the new contact!",
|
||||
rosterListener.getAddedAddresses().contains(contactJID));
|
||||
assertSame("Setup wrong name for the new contact!",
|
||||
contactName,
|
||||
addedEntry.getName());
|
||||
assertSame("Setup wrong default subscription status!",
|
||||
ItemType.none,
|
||||
addedEntry.getType());
|
||||
assertSame("The new contact shouldn't be member of any group!",
|
||||
0,
|
||||
addedEntry.getGroups().size());
|
||||
|
||||
// Verify the unchanged roster items
|
||||
verifyRomeosEntry(roster.getEntry("romeo@example.net"));
|
||||
verifyMercutiosEntry(roster.getEntry("mercutio@example.com"));
|
||||
verifyBenvoliosEntry(roster.getEntry("benvolio@example.net"));
|
||||
assertSame("Wrong number of roster entries.", 4, roster.getEntries().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test processing a roster push with an empty group is equivalent with providing
|
||||
* no group.
|
||||
*
|
||||
* @see <a href="http://www.igniterealtime.org/issues/browse/SMACK-294">SMACK-294</a>
|
||||
*/
|
||||
@Test
|
||||
public void testEmptyGroupRosterPush() throws Throwable {
|
||||
final String contactJID = "nurse@example.com";
|
||||
assertNotNull("Can't get the roster from the provided connection!", roster);
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("<iq id=\"rostertest2\" type=\"set\" ")
|
||||
.append("to=\"").append(connection.getUser()).append("\">")
|
||||
.append("<query xmlns=\"jabber:iq:roster\">")
|
||||
.append("<item jid=\"").append(contactJID).append("\">")
|
||||
.append("<group></group>")
|
||||
.append("</item>")
|
||||
.append("</query>")
|
||||
.append("</iq>");
|
||||
final XmlPullParser parser = TestUtils.getIQParser(sb.toString());
|
||||
final IQ rosterPush = PacketParserUtils.parseIQ(parser);
|
||||
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);
|
||||
assertNotNull("The new contact wasn't added to the roster!", addedEntry);
|
||||
assertTrue("The roster listener wasn't invoked for the new contact!",
|
||||
rosterListener.getAddedAddresses().contains(contactJID));
|
||||
assertSame("Setup wrong default subscription status!",
|
||||
ItemType.none,
|
||||
addedEntry.getType());
|
||||
assertSame("The new contact shouldn't be member of any group!",
|
||||
0,
|
||||
addedEntry.getGroups().size());
|
||||
|
||||
// Verify the unchanged roster items
|
||||
verifyRomeosEntry(roster.getEntry("romeo@example.net"));
|
||||
verifyMercutiosEntry(roster.getEntry("mercutio@example.com"));
|
||||
verifyBenvoliosEntry(roster.getEntry("benvolio@example.net"));
|
||||
assertSame("Wrong number of roster entries.", 4, roster.getEntries().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all roster entries by iterating trough {@link Roster#getEntries()}
|
||||
* and simulating receiving roster pushes from the server.
|
||||
*
|
||||
* @param connection the dummy connection of which the provided roster belongs to.
|
||||
* @param roster the roster (or buddy list) which should be initialized.
|
||||
*/
|
||||
public static void removeAllRosterEntries(DummyConnection connection, Roster roster)
|
||||
throws InterruptedException, XMPPException {
|
||||
for(RosterEntry entry : roster.getEntries()) {
|
||||
// prepare the roster push packet
|
||||
final RosterPacket rosterPush= new RosterPacket();
|
||||
rosterPush.setType(Type.set);
|
||||
rosterPush.setTo(connection.getUser());
|
||||
|
||||
// prepare the buddy's item entry which should be removed
|
||||
final RosterPacket.Item item = new RosterPacket.Item(entry.getUser(), entry.getName());
|
||||
item.setItemType(ItemType.remove);
|
||||
rosterPush.addRosterItem(item);
|
||||
|
||||
// simulate receiving the roster push
|
||||
connection.processPacket(rosterPush);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the roster according to the example in
|
||||
* <a href="http://xmpp.org/rfcs/rfc3921.html#roster-login"
|
||||
* >RFC3921: Retrieving One's Roster on Login</a>.
|
||||
*
|
||||
* @param connection the dummy connection of which the provided roster belongs to.
|
||||
* @param roster the roster (or buddy list) which should be initialized.
|
||||
* @throws SmackException
|
||||
*/
|
||||
private void initRoster() throws InterruptedException, XMPPException, SmackException {
|
||||
roster.reload();
|
||||
while (true) {
|
||||
final Packet sentPacket = connection.getSentPacket();
|
||||
if (sentPacket instanceof RosterPacket && ((IQ) sentPacket).getType() == Type.get) {
|
||||
// setup the roster get request
|
||||
final RosterPacket rosterRequest = (RosterPacket) sentPacket;
|
||||
assertSame("The <query/> element MUST NOT contain any <item/> child elements!",
|
||||
0,
|
||||
rosterRequest.getRosterItemCount());
|
||||
|
||||
// prepare the roster result
|
||||
final RosterPacket rosterResult = new RosterPacket();
|
||||
rosterResult.setTo(connection.getUser());
|
||||
rosterResult.setType(Type.result);
|
||||
rosterResult.setPacketID(rosterRequest.getPacketID());
|
||||
|
||||
// prepare romeo's roster entry
|
||||
final Item romeo = new Item("romeo@example.net", "Romeo");
|
||||
romeo.addGroupName("Friends");
|
||||
romeo.setItemType(ItemType.both);
|
||||
rosterResult.addRosterItem(romeo);
|
||||
|
||||
// prepare mercutio's roster entry
|
||||
final Item mercutio = new Item("mercutio@example.com", "Mercutio");
|
||||
mercutio.setItemType(ItemType.from);
|
||||
rosterResult.addRosterItem(mercutio);
|
||||
|
||||
// prepare benvolio's roster entry
|
||||
final Item benvolio = new Item("benvolio@example.net", "Benvolio");
|
||||
benvolio.setItemType(ItemType.both);
|
||||
rosterResult.addRosterItem(benvolio);
|
||||
|
||||
// simulate receiving the roster result and exit the loop
|
||||
connection.processPacket(rosterResult);
|
||||
break;
|
||||
}
|
||||
}
|
||||
roster.waitUntilLoaded();
|
||||
rosterListener.waitUntilInvocationOrTimeout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Romeo's roster entry according to the example in
|
||||
* <a href="http://xmpp.org/rfcs/rfc3921.html#roster-login"
|
||||
* >RFC3921: Retrieving One's Roster on Login</a>.
|
||||
*
|
||||
* @param romeo the roster entry which should be verified.
|
||||
*/
|
||||
public static void verifyRomeosEntry(final RosterEntry romeo) {
|
||||
assertNotNull("Can't get Romeo's roster entry!", romeo);
|
||||
assertSame("Setup wrong name for Romeo!",
|
||||
"Romeo",
|
||||
romeo.getName());
|
||||
assertSame("Setup wrong subscription status for Romeo!",
|
||||
ItemType.both,
|
||||
romeo.getType());
|
||||
assertSame("Romeo should be member of exactly one group!",
|
||||
1,
|
||||
romeo.getGroups().size());
|
||||
assertSame("Setup wrong group name for Romeo!",
|
||||
"Friends",
|
||||
romeo.getGroups().iterator().next().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Mercutio's roster entry according to the example in
|
||||
* <a href="http://xmpp.org/rfcs/rfc3921.html#roster-login"
|
||||
* >RFC3921: Retrieving One's Roster on Login</a>.
|
||||
*
|
||||
* @param mercutio the roster entry which should be verified.
|
||||
*/
|
||||
public static void verifyMercutiosEntry(final RosterEntry mercutio) {
|
||||
assertNotNull("Can't get Mercutio's roster entry!", mercutio);
|
||||
assertSame("Setup wrong name for Mercutio!",
|
||||
"Mercutio",
|
||||
mercutio.getName());
|
||||
assertSame("Setup wrong subscription status for Mercutio!",
|
||||
ItemType.from,
|
||||
mercutio.getType());
|
||||
assertTrue("Mercutio shouldn't be a member of any group!",
|
||||
mercutio.getGroups().isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Benvolio's roster entry according to the example in
|
||||
* <a href="http://xmpp.org/rfcs/rfc3921.html#roster-login"
|
||||
* >RFC3921: Retrieving One's Roster on Login</a>.
|
||||
*
|
||||
* @param benvolio the roster entry which should be verified.
|
||||
*/
|
||||
public static void verifyBenvoliosEntry(final RosterEntry benvolio) {
|
||||
assertNotNull("Can't get Benvolio's roster entry!", benvolio);
|
||||
assertSame("Setup wrong name for Benvolio!",
|
||||
"Benvolio",
|
||||
benvolio.getName());
|
||||
assertSame("Setup wrong subscription status for Benvolio!",
|
||||
ItemType.both,
|
||||
benvolio.getType());
|
||||
assertTrue("Benvolio shouldn't be a member of any group!",
|
||||
benvolio.getGroups().isEmpty());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This class can be used to simulate the server response for
|
||||
* a roster update request.
|
||||
*/
|
||||
private abstract class RosterUpdateResponder extends Thread {
|
||||
private Throwable exception = null;
|
||||
|
||||
/**
|
||||
* Overwrite this method to check if the received update request is valid.
|
||||
*
|
||||
* @param updateRequest the request which would be sent to the server.
|
||||
*/
|
||||
abstract void verifyUpdateRequest(final RosterPacket updateRequest);
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
while (true) {
|
||||
final Packet packet = connection.getSentPacket();
|
||||
if (packet instanceof RosterPacket && ((IQ) packet).getType() == Type.set) {
|
||||
final RosterPacket rosterRequest = (RosterPacket) packet;
|
||||
|
||||
// Prepare and process the roster push
|
||||
final RosterPacket rosterPush = new RosterPacket();
|
||||
final Item item = rosterRequest.getRosterItems().iterator().next();
|
||||
if (item.getItemType() != ItemType.remove) {
|
||||
item.setItemType(ItemType.none);
|
||||
}
|
||||
rosterPush.setType(Type.set);
|
||||
rosterPush.setTo(connection.getUser());
|
||||
rosterPush.addRosterItem(item);
|
||||
connection.processPacket(rosterPush);
|
||||
|
||||
// Create and process the IQ response
|
||||
final IQ response = IQ.createResultIQ(rosterRequest);
|
||||
connection.processPacket(response);
|
||||
|
||||
// Verify the roster update request
|
||||
assertSame("A roster set MUST contain one and only one <item/> element.",
|
||||
1,
|
||||
rosterRequest.getRosterItemCount());
|
||||
verifyUpdateRequest(rosterRequest);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
exception = e;
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exception or error if something went wrong.
|
||||
*
|
||||
* @return the Throwable exception or error that occurred.
|
||||
*/
|
||||
public Throwable getException() {
|
||||
return exception;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This class can be used to check if the RosterListener was invoked.
|
||||
*/
|
||||
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);
|
||||
if (SmackConfiguration.DEBUG) {
|
||||
for (String address : addresses) {
|
||||
System.out.println("Roster entry for " + address + " added.");
|
||||
}
|
||||
}
|
||||
reportInvoked();
|
||||
}
|
||||
|
||||
public synchronized void entriesDeleted(Collection<String> addresses) {
|
||||
addressesDeleted.addAll(addresses);
|
||||
if (SmackConfiguration.DEBUG) {
|
||||
for (String address : addresses) {
|
||||
System.out.println("Roster entry for " + address + " deleted.");
|
||||
}
|
||||
}
|
||||
reportInvoked();
|
||||
}
|
||||
|
||||
public synchronized void entriesUpdated(Collection<String> addresses) {
|
||||
addressesUpdated.addAll(addresses);
|
||||
if (SmackConfiguration.DEBUG) {
|
||||
for (String address : addresses) {
|
||||
System.out.println("Roster entry for " + address + " updated.");
|
||||
}
|
||||
}
|
||||
reportInvoked();
|
||||
}
|
||||
|
||||
public void presenceChanged(Presence presence) {
|
||||
if (SmackConfiguration.DEBUG) {
|
||||
System.out.println("Roster presence changed: " + presence.toXML());
|
||||
}
|
||||
reportInvoked();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a collection of JIDs of the added roster items.
|
||||
*
|
||||
* @return the collection of addresses which were added.
|
||||
*/
|
||||
public Collection<String> getAddedAddresses() {
|
||||
return Collections.unmodifiableCollection(addressesAdded);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a collection of JIDs of the deleted roster items.
|
||||
*
|
||||
* @return the collection of addresses which were deleted.
|
||||
*/
|
||||
public Collection<String> getDeletedAddresses() {
|
||||
return Collections.unmodifiableCollection(addressesDeleted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a collection of JIDs of the updated roster items.
|
||||
*
|
||||
* @return the collection of addresses which were updated.
|
||||
*/
|
||||
public Collection<String> getUpdatedAddresses() {
|
||||
return Collections.unmodifiableCollection(addressesUpdated);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the lists of added, deleted or updated items.
|
||||
*/
|
||||
public synchronized void reset() {
|
||||
super.reset();
|
||||
addressesAdded.clear();
|
||||
addressesDeleted.clear();
|
||||
addressesUpdated.clear();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,258 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
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;
|
||||
import org.jivesoftware.smack.packet.RosterPacket;
|
||||
import org.jivesoftware.smack.packet.RosterPacket.Item;
|
||||
import org.jivesoftware.smack.packet.RosterPacket.ItemType;
|
||||
import org.jivesoftware.smack.rosterstore.DirectoryRosterStore;
|
||||
import org.jivesoftware.smack.rosterstore.RosterStore;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
/**
|
||||
* Tests that verify the correct behavior of the {@link Roster} implementation
|
||||
* with regard to roster versioning
|
||||
*
|
||||
* @see Roster
|
||||
* @see <a href="http://xmpp.org/rfcs/rfc6121.html#roster">Managing the Roster</a>
|
||||
* @author Fabian Schuetz
|
||||
* @author Lars Noschinski
|
||||
*/
|
||||
public class RosterVersioningTest {
|
||||
|
||||
private DummyConnection connection;
|
||||
private Roster roster;
|
||||
private TestRosterListener rosterListener;
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder tmpFolder = new TemporaryFolder();
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
DirectoryRosterStore store = DirectoryRosterStore.init(tmpFolder.newFolder("store"));
|
||||
populateStore(store);
|
||||
|
||||
Builder<?, ?> builder = DummyConnection.getDummyConfigurationBuilder();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that receiving an empty roster result causes the roster to be populated
|
||||
* by all entries of the roster store.
|
||||
* @throws SmackException
|
||||
* @throws XMPPException
|
||||
*/
|
||||
@Test(timeout = 5000)
|
||||
public void testEqualVersionStored() throws InterruptedException, IOException, XMPPException, SmackException {
|
||||
answerWithEmptyRosterResult();
|
||||
roster.waitUntilLoaded();
|
||||
|
||||
Collection<RosterEntry> entries = roster.getEntries();
|
||||
assertSame("Size of the roster", 3, entries.size());
|
||||
|
||||
HashSet<Item> items = new HashSet<Item>();
|
||||
for (RosterEntry entry : entries) {
|
||||
items.add(RosterEntry.toRosterItem(entry));
|
||||
}
|
||||
RosterStore store = DirectoryRosterStore.init(tmpFolder.newFolder());
|
||||
populateStore(store);
|
||||
assertEquals("Elements of the roster", new HashSet<Item>(store.getEntries()), items);
|
||||
|
||||
for (RosterEntry entry : entries) {
|
||||
assertTrue("joe stevens".equals(entry.getName()) || "geoff hurley".equals(entry.getName())
|
||||
|| "higgins mcmann".equals(entry.getName()));
|
||||
}
|
||||
Collection<RosterGroup> groups = roster.getGroups();
|
||||
assertSame(3, groups.size());
|
||||
|
||||
for (RosterGroup group : groups) {
|
||||
assertTrue("all".equals(group.getName()) || "friends".equals(group.getName())
|
||||
|| "partners".equals(group.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that a non-empty roster result empties the store.
|
||||
* @throws SmackException
|
||||
* @throws XMPPException
|
||||
*/
|
||||
@Test(timeout = 5000)
|
||||
public void testOtherVersionStored() throws InterruptedException, XMPPException, SmackException {
|
||||
Item vaglafItem = vaglafItem();
|
||||
|
||||
// We expect that the roster request is the only packet sent. This is not part of the specification,
|
||||
// but a shortcut in the test implementation.
|
||||
Packet sentPacket = connection.getSentPacket();
|
||||
if (sentPacket instanceof RosterPacket) {
|
||||
RosterPacket sentRP = (RosterPacket)sentPacket;
|
||||
RosterPacket answer = new RosterPacket();
|
||||
answer.setPacketID(sentRP.getPacketID());
|
||||
answer.setType(Type.result);
|
||||
answer.setTo(sentRP.getFrom());
|
||||
|
||||
answer.setVersion("newVersion");
|
||||
answer.addRosterItem(vaglafItem);
|
||||
|
||||
rosterListener.reset();
|
||||
connection.processPacket(answer);
|
||||
rosterListener.waitUntilInvocationOrTimeout();
|
||||
} else {
|
||||
assertTrue("Expected to get a RosterPacket ", false);
|
||||
}
|
||||
|
||||
Roster roster = connection.getRoster();
|
||||
assertEquals("Size of roster", 1, roster.getEntries().size());
|
||||
RosterEntry entry = roster.getEntry(vaglafItem.getUser());
|
||||
assertNotNull("Roster contains vaglaf entry", entry);
|
||||
assertEquals("vaglaf entry in roster equals the sent entry", vaglafItem, RosterEntry.toRosterItem(entry));
|
||||
|
||||
RosterStore store = connection.getConfiguration().getRosterStore();
|
||||
assertEquals("Size of store", 1, store.getEntries().size());
|
||||
Item item = store.getEntry(vaglafItem.getUser());
|
||||
assertNotNull("Store contains vaglaf entry");
|
||||
assertEquals("vaglaf entry in store equals the sent entry", vaglafItem, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test roster versioning with roster pushes
|
||||
*/
|
||||
@Test(timeout = 5000)
|
||||
public void testRosterVersioningWithCachedRosterAndPushes() throws Throwable {
|
||||
answerWithEmptyRosterResult();
|
||||
rosterListener.waitAndReset();
|
||||
|
||||
RosterStore store = connection.getConfiguration().getRosterStore();
|
||||
|
||||
// Simulate a roster push adding vaglaf
|
||||
{
|
||||
RosterPacket rosterPush = new RosterPacket();
|
||||
rosterPush.setTo("rostertest@example.com/home");
|
||||
rosterPush.setType(Type.set);
|
||||
rosterPush.setVersion("v97");
|
||||
|
||||
Item pushedItem = vaglafItem();
|
||||
rosterPush.addRosterItem(pushedItem);
|
||||
rosterListener.reset();
|
||||
connection.processPacket(rosterPush);
|
||||
rosterListener.waitAndReset();
|
||||
|
||||
assertEquals("Expect store version after push", "v97", store.getRosterVersion());
|
||||
|
||||
Item storedItem = store.getEntry("vaglaf@example.com");
|
||||
assertNotNull("Expect vaglaf to be added", storedItem);
|
||||
assertEquals("Expect vaglaf to be equal to pushed item", pushedItem, storedItem);
|
||||
|
||||
Collection<Item> rosterItems = new HashSet<Item>();
|
||||
for (RosterEntry entry : roster.getEntries()) {
|
||||
rosterItems.add(RosterEntry.toRosterItem(entry));
|
||||
}
|
||||
assertEquals(rosterItems, new HashSet<Item>(store.getEntries()));
|
||||
}
|
||||
|
||||
// Simulate a roster push removing vaglaf
|
||||
{
|
||||
RosterPacket rosterPush = new RosterPacket();
|
||||
rosterPush.setTo("rostertest@example.com/home");
|
||||
rosterPush.setType(Type.set);
|
||||
rosterPush.setVersion("v98");
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
private Item vaglafItem() {
|
||||
Item item = new Item("vaglaf@example.com", "vaglaf the only");
|
||||
item.setItemType(ItemType.both);
|
||||
item.addGroupName("all");
|
||||
item.addGroupName("friends");
|
||||
item.addGroupName("partners");
|
||||
return item;
|
||||
}
|
||||
|
||||
private void populateStore(RosterStore store) throws IOException {
|
||||
store.addEntry(new RosterPacket.Item("geoff@example.com", "geoff hurley"), "");
|
||||
|
||||
RosterPacket.Item item = new RosterPacket.Item("joe@example.com", "joe stevens");
|
||||
item.addGroupName("friends");
|
||||
item.addGroupName("partners");
|
||||
store.addEntry(item, "");
|
||||
|
||||
item = new RosterPacket.Item("higgins@example.com", "higgins mcmann");
|
||||
item.addGroupName("all");
|
||||
item.addGroupName("friends");
|
||||
store.addEntry(item, "v96");
|
||||
}
|
||||
|
||||
private void answerWithEmptyRosterResult() throws InterruptedException {
|
||||
// We expect that the roster request is the only packet sent. This is not part of the specification,
|
||||
// but a shortcut in the test implementation.
|
||||
Packet sentPacket = connection.getSentPacket();
|
||||
if (sentPacket instanceof RosterPacket) {
|
||||
final IQ emptyIQ = IQ.createResultIQ((RosterPacket)sentPacket);
|
||||
connection.processPacket(emptyIQ);
|
||||
} else {
|
||||
assertTrue("Expected to get a RosterPacket ", false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,224 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* 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.rosterstore;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smack.packet.RosterPacket;
|
||||
import org.jivesoftware.smack.packet.RosterPacket.Item;
|
||||
import org.jivesoftware.smack.packet.RosterPacket.ItemStatus;
|
||||
import org.jivesoftware.smack.packet.RosterPacket.ItemType;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
/**
|
||||
* Tests the implementation of {@link DirectoryRosterStore}.
|
||||
*
|
||||
* @author Lars Noschinski
|
||||
*/
|
||||
public class DirectoryRosterStoreTest {
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder tmpFolder = new TemporaryFolder();
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that opening an uninitialized directory fails.
|
||||
*/
|
||||
@Test
|
||||
public void testStoreUninitialized() throws IOException {
|
||||
File storeDir = tmpFolder.newFolder();
|
||||
assertNull(DirectoryRosterStore.open(storeDir));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that an initialized directory is empty.
|
||||
*/
|
||||
@Test
|
||||
public void testStoreInitializedEmpty() throws IOException {
|
||||
File storeDir = tmpFolder.newFolder();
|
||||
DirectoryRosterStore store = DirectoryRosterStore.init(storeDir);
|
||||
assertNotNull("Initialization returns store", store);
|
||||
assertEquals("Freshly initialized store must have empty version",
|
||||
"", store.getRosterVersion());
|
||||
assertEquals("Freshly initialized store must have no entries",
|
||||
0, store.getEntries().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests adding and removing entries
|
||||
*/
|
||||
@Test
|
||||
public void testStoreAddRemove() throws IOException {
|
||||
File storeDir = tmpFolder.newFolder();
|
||||
DirectoryRosterStore store = DirectoryRosterStore.init(storeDir);
|
||||
|
||||
assertEquals("Initial roster version", "", store.getRosterVersion());
|
||||
|
||||
String userName = "user@example.com";
|
||||
|
||||
final RosterPacket.Item item1 = new Item(userName, null);
|
||||
final String version1 = "1";
|
||||
store.addEntry(item1, version1);
|
||||
|
||||
assertEquals("Adding entry sets version correctly", version1, store.getRosterVersion());
|
||||
|
||||
RosterPacket.Item storedItem = store.getEntry(userName);
|
||||
assertNotNull("Added entry not found found", storedItem);
|
||||
assertEquals("User of added entry",
|
||||
item1.getUser(), storedItem.getUser());
|
||||
assertEquals("Name of added entry",
|
||||
item1.getName(), storedItem.getName());
|
||||
assertEquals("Groups", item1.getGroupNames(), storedItem.getGroupNames());
|
||||
assertEquals("ItemType of added entry",
|
||||
item1.getItemType(), storedItem.getItemType());
|
||||
assertEquals("ItemStatus of added entry",
|
||||
item1.getItemStatus(), storedItem.getItemStatus());
|
||||
|
||||
|
||||
final String version2 = "2";
|
||||
final RosterPacket.Item item2 = new Item(userName, "Ursula Example");
|
||||
item2.addGroupName("users");
|
||||
item2.addGroupName("examples");
|
||||
item2.setItemStatus(ItemStatus.subscribe);
|
||||
item2.setItemType(ItemType.none);
|
||||
store.addEntry(item2,version2);
|
||||
assertEquals("Updating entry sets version correctly", version2, store.getRosterVersion());
|
||||
storedItem = store.getEntry(userName);
|
||||
assertNotNull("Added entry not found", storedItem);
|
||||
assertEquals("User of added entry",
|
||||
item2.getUser(), storedItem.getUser());
|
||||
assertEquals("Name of added entry",
|
||||
item2.getName(), storedItem.getName());
|
||||
assertEquals("Groups", item2.getGroupNames(), storedItem.getGroupNames());
|
||||
assertEquals("ItemType of added entry",
|
||||
item2.getItemType(), storedItem.getItemType());
|
||||
assertEquals("ItemStatus of added entry",
|
||||
item2.getItemStatus(), storedItem.getItemStatus());
|
||||
|
||||
List<Item> entries = store.getEntries();
|
||||
assertEquals("Number of entries", 1, entries.size());
|
||||
|
||||
final RosterPacket.Item item3 = new Item("foobar@example.com", "Foo Bar");
|
||||
item3.addGroupName("The Foo Fighters");
|
||||
item3.addGroupName("Bar Friends");
|
||||
item3.setItemStatus(ItemStatus.unsubscribe);
|
||||
item3.setItemType(ItemType.both);
|
||||
|
||||
final RosterPacket.Item item4 = new Item("baz@example.com", "Baba Baz");
|
||||
item4.addGroupName("The Foo Fighters");
|
||||
item4.addGroupName("Bar Friends");
|
||||
item4.setItemStatus(ItemStatus.subscribe);
|
||||
item4.setItemType(ItemType.both);
|
||||
|
||||
ArrayList<Item> items34 = new ArrayList<RosterPacket.Item>();
|
||||
items34.add(item3);
|
||||
items34.add(item4);
|
||||
|
||||
String version3 = "3";
|
||||
store.resetEntries(items34, version3);
|
||||
|
||||
storedItem = store.getEntry("foobar@example.com");
|
||||
assertNotNull("Added entry not found", storedItem);
|
||||
assertEquals("User of added entry",
|
||||
item3.getUser(), storedItem.getUser());
|
||||
assertEquals("Name of added entry",
|
||||
item3.getName(), storedItem.getName());
|
||||
assertEquals("Groups", item3.getGroupNames(), storedItem.getGroupNames());
|
||||
assertEquals("ItemType of added entry",
|
||||
item3.getItemType(), storedItem.getItemType());
|
||||
assertEquals("ItemStatus of added entry",
|
||||
item3.getItemStatus(), storedItem.getItemStatus());
|
||||
|
||||
|
||||
storedItem = store.getEntry("baz@example.com");
|
||||
assertNotNull("Added entry not found", storedItem);
|
||||
assertEquals("User of added entry",
|
||||
item4.getUser(), storedItem.getUser());
|
||||
assertEquals("Name of added entry",
|
||||
item4.getName(), storedItem.getName());
|
||||
assertEquals("Groups", item4.getGroupNames(), storedItem.getGroupNames());
|
||||
assertEquals("ItemType of added entry",
|
||||
item4.getItemType(), storedItem.getItemType());
|
||||
assertEquals("ItemStatus of added entry",
|
||||
item4.getItemStatus(), storedItem.getItemStatus());
|
||||
|
||||
entries = store.getEntries();
|
||||
assertEquals("Number of entries", 2, entries.size());
|
||||
|
||||
String version4 = "4";
|
||||
store.removeEntry("baz@example.com", version4);
|
||||
assertEquals("Removing entry sets version correctly",
|
||||
version4, store.getRosterVersion());
|
||||
assertNull("Removed entry is gone", store.getEntry(userName));
|
||||
|
||||
entries = store.getEntries();
|
||||
assertEquals("Number of entries", 1, entries.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests adding entries with evil characters
|
||||
*/
|
||||
@Test
|
||||
public void testAddEvilChars() throws IOException {
|
||||
File storeDir = tmpFolder.newFolder();
|
||||
DirectoryRosterStore store = DirectoryRosterStore.init(storeDir);
|
||||
|
||||
String user = "../_#;\"'\\&@example.com";
|
||||
String name = "\n../_#\0\t;\"'&@\\";
|
||||
String group1 = "\t;\"'&@\\\n../_#\0";
|
||||
String group2 = "#\0\t;\"'&@\\\n../_";
|
||||
|
||||
Item item = new Item(user, name);
|
||||
item.setItemStatus(ItemStatus.unsubscribe);
|
||||
item.setItemType(ItemType.to);
|
||||
item.addGroupName(group1);
|
||||
item.addGroupName(group2);
|
||||
store.addEntry(item, "a-version");
|
||||
Item storedItem = store.getEntry(user);
|
||||
|
||||
assertNotNull("Added entry not found", storedItem);
|
||||
assertEquals("User of added entry",
|
||||
item.getUser(), storedItem.getUser());
|
||||
assertEquals("Name of added entry",
|
||||
item.getName(), storedItem.getName());
|
||||
assertEquals("Groups", item.getGroupNames(), storedItem.getGroupNames());
|
||||
assertEquals("ItemType of added entry",
|
||||
item.getItemType(), storedItem.getItemType());
|
||||
assertEquals("ItemStatus of added entry",
|
||||
item.getItemStatus(), storedItem.getItemStatus());
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue