mirror of https://github.com/sipwise/jitsi.git
parent
21c68d779c
commit
921e04910e
@ -0,0 +1,203 @@
|
||||
package net.java.sip.communicator.slick.protocol.icq;
|
||||
|
||||
import junit.framework.*;
|
||||
import org.osgi.framework.*;
|
||||
import net.java.sip.communicator.util.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
/**
|
||||
* @author Emil Ivov
|
||||
*/
|
||||
public class IcqProtocolProviderSlick
|
||||
extends TestSuite
|
||||
implements BundleActivator
|
||||
{
|
||||
private Logger logger = Logger.getLogger(getClass().getName());
|
||||
|
||||
/**
|
||||
* The name of the system property that contains the id of the account
|
||||
* that will be used when signing the icq protocol provider on icq.
|
||||
*/
|
||||
public static final String TESTED_IMPL_ACCOUNT_ID_PROP_NAME =
|
||||
"accounts.icq.TESTED_IMPL_ACCOUNT_ID";
|
||||
|
||||
/**
|
||||
* The name of the system property that contains the password for the
|
||||
* account that will be used when signing the icq protocol provider on icq.
|
||||
*/
|
||||
public static final String TESTED_IMPL_PWD_PROP_NAME =
|
||||
"accounts.icq.TESTED_IMPL_PWD";
|
||||
|
||||
/**
|
||||
* The name of the system property that contains the id of the account
|
||||
* that will be used by the SLICK itself when signing on icq
|
||||
*/
|
||||
public static final String TESTING_IMPL_ACCOUNT_ID_PROP_NAME =
|
||||
"accounts.icq.TESTING_IMPL_ACCOUNT_ID";
|
||||
|
||||
/**
|
||||
* The name of the system property that contains the password for the
|
||||
* account that will be used when signing the icq protocol provider on icq.
|
||||
*/
|
||||
public static final String TESTING_IMPL_PWD_PROP_NAME =
|
||||
"accounts.icq.TESTING_IMPL_PWD";
|
||||
|
||||
/**
|
||||
* The name of the property the value of which is a formatted string that
|
||||
* contains the contact list that.
|
||||
*/
|
||||
public static final String CONTACT_LIST_PROPERTY_NAME
|
||||
= "accounts.icq.CONTACT_LIST";
|
||||
|
||||
/**
|
||||
* Start the Configuration Sevice Implementation Compatibility Kit.
|
||||
*
|
||||
* @param bundleContext BundleContext
|
||||
* @throws Exception
|
||||
*/
|
||||
public void start(BundleContext bundleContext) throws Exception
|
||||
{
|
||||
setName("IcqProtocolProviderSlick");
|
||||
Hashtable properties = new Hashtable();
|
||||
properties.put("service.pid", getName());
|
||||
|
||||
//store the bundle cache reference for usage by other others
|
||||
IcqSlickFixture.bc = bundleContext;
|
||||
|
||||
//register our testing agent on icq.
|
||||
IcqSlickFixture.testerAgent =
|
||||
new IcqTesterAgent(System.getProperty(
|
||||
TESTING_IMPL_ACCOUNT_ID_PROP_NAME, null));
|
||||
if (!IcqSlickFixture.testerAgent.register(System.getProperty(
|
||||
TESTING_IMPL_PWD_PROP_NAME, null)))
|
||||
throw new Exception(
|
||||
"Registering the IcqTesterAgent on icq has failed.(Possible "
|
||||
+"reasons: authetification failed, or Connection rate limit "
|
||||
+"exceeded.)");
|
||||
|
||||
//initialize the tested account's contact list so that it could be ready
|
||||
//when testing starts.
|
||||
initializeTestedContactList();
|
||||
|
||||
//First test account installation so that the service that has been
|
||||
//installed by it gets tested by the rest of the tests.
|
||||
addTestSuite(TestAccountInstallation.class);
|
||||
|
||||
//This must remain second as that's where the protocol would be made
|
||||
//to login/authenticate/signon its service provider.
|
||||
addTest(TestProtocolProviderServiceIcqImpl.suite());
|
||||
|
||||
addTest(TestOperationSetPresence.suite());
|
||||
|
||||
addTest(TestOperationSetPersistentPresence.suite());
|
||||
|
||||
addTestSuite(TestOperationSetBasicInstantMessaging.class);
|
||||
|
||||
//This must remain last since it tests account uninstallation and
|
||||
//the accounts we use for testing won't be available after that.
|
||||
addTestSuite(TestAccountUninstallation.class);
|
||||
|
||||
bundleContext.registerService(getClass().getName(), this, properties);
|
||||
|
||||
logger.debug("Successfully registered " + getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Signs the testerAgent off the icq servers
|
||||
*
|
||||
* @param bundleContext a valid OSGI bundle context.
|
||||
* @throws Exception in case anything goes wrong
|
||||
*/
|
||||
public void stop(BundleContext bundleContext) throws Exception
|
||||
{
|
||||
IcqSlickFixture.testerAgent.unregister();
|
||||
uninstallTestIcqAccount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstalls the test icq account used IcqProtocolProvider tests
|
||||
*/
|
||||
private void uninstallTestIcqAccount()
|
||||
{
|
||||
//sign the corresponding protocol provider off icq
|
||||
|
||||
//uninstall the account
|
||||
}
|
||||
|
||||
/**
|
||||
* The method would make a tester agent sign on icq, ERASE the contact list
|
||||
* of the account that is being used, fill it in with dummy data (stored
|
||||
* in the CONTACT_LIST property) that we will later fetch from the tested
|
||||
* implementation, and sign out.
|
||||
*/
|
||||
private void initializeTestedContactList()
|
||||
{
|
||||
String contactList = System.getProperty(CONTACT_LIST_PROPERTY_NAME, null);
|
||||
|
||||
logger.debug("The " + CONTACT_LIST_PROPERTY_NAME
|
||||
+ " property is set to=" +contactList);
|
||||
|
||||
if( contactList == null
|
||||
|| contactList.trim().length() < 6)//at least 4 for a UIN, 1 for the
|
||||
// dot and 1 for the grp name
|
||||
throw new IllegalArgumentException(
|
||||
"The " + CONTACT_LIST_PROPERTY_NAME +
|
||||
" property did not contain a contact list.");
|
||||
StringTokenizer tokenizer = new StringTokenizer(contactList, " \n\t");
|
||||
|
||||
logger.debug("tokens contained by the CL tokenized="
|
||||
+tokenizer.countTokens());
|
||||
|
||||
Hashtable contactListToCreate = new Hashtable();
|
||||
|
||||
//go over all group.uin tokens
|
||||
while (tokenizer.hasMoreTokens())
|
||||
{
|
||||
String groupUinToken = tokenizer.nextToken();
|
||||
int dotIndex = groupUinToken.indexOf(".");
|
||||
|
||||
if ( dotIndex == -1 ){
|
||||
throw new IllegalArgumentException(groupUinToken
|
||||
+ " is not a valid Group.UIN token");
|
||||
}
|
||||
|
||||
String groupName = groupUinToken.substring(0, dotIndex);
|
||||
String uin = groupUinToken.substring(dotIndex + 1);
|
||||
|
||||
if( groupName.trim().length() < 1
|
||||
|| uin.trim().length() < 4 ){
|
||||
throw new IllegalArgumentException(
|
||||
groupName + " or " + uin +
|
||||
" are not a valid group name or ICQ UIN.");
|
||||
}
|
||||
|
||||
//check if we've already seen this group and if not - add it
|
||||
List uinInThisGroup = (List)contactListToCreate.get(groupName);
|
||||
if (uinInThisGroup == null){
|
||||
uinInThisGroup = new ArrayList();
|
||||
contactListToCreate.put(groupName, uinInThisGroup);
|
||||
}
|
||||
|
||||
uinInThisGroup.add(uin);
|
||||
}
|
||||
|
||||
//Create a tester agent that would connect with the tested impl account
|
||||
//and initialize the contact list according to what we just parsed.
|
||||
|
||||
|
||||
IcqTesterAgent cListInitTesterAgent = new IcqTesterAgent(
|
||||
System.getProperty(TESTED_IMPL_ACCOUNT_ID_PROP_NAME, null)
|
||||
);
|
||||
cListInitTesterAgent.register(
|
||||
System.getProperty(TESTED_IMPL_PWD_PROP_NAME, null)
|
||||
);
|
||||
|
||||
cListInitTesterAgent.initializeBuddyList(contactListToCreate);
|
||||
|
||||
cListInitTesterAgent.unregister();
|
||||
|
||||
//store the created contact list for later reference
|
||||
IcqSlickFixture.preInstalledBuddyList = contactListToCreate;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,102 @@
|
||||
package net.java.sip.communicator.slick.protocol.icq;
|
||||
|
||||
import net.java.sip.communicator.service.protocol.*;
|
||||
import org.osgi.framework.*;
|
||||
import junit.framework.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Provides utility code, such as locating and obtaining references towards
|
||||
* base services that anyother service would need.
|
||||
*
|
||||
* @author Emil Ivov
|
||||
*/
|
||||
public class IcqSlickFixture extends TestCase
|
||||
{
|
||||
/**
|
||||
* To be set by the slick itself upon activation.
|
||||
*/
|
||||
public static BundleContext bc = null;
|
||||
|
||||
/**
|
||||
* The tested account id obtained during installation.
|
||||
*/
|
||||
public static AccountID icqAccountID = null;
|
||||
|
||||
/**
|
||||
* The agent that we use to verify whether the tested implementation is
|
||||
* being honest with us. The icq tester agent is instantiated and registered
|
||||
* by the icq slick activator.
|
||||
*/
|
||||
static IcqTesterAgent testerAgent = null;
|
||||
|
||||
/**
|
||||
* A Hashtable containing group names mapped against array lists of buddy
|
||||
* screen names. This is a snapshot of the server stored buddy list for
|
||||
* the icq account that is going to be used by the tested implementation.
|
||||
* It is filled in by the icq tester agent who'd login with that account
|
||||
* and initialise the ss contact list before the tested implementation has
|
||||
* actually done so.
|
||||
*/
|
||||
public static Hashtable preInstalledBuddyList = null;
|
||||
|
||||
public ServiceReference icqServiceRef = null;
|
||||
public ProtocolProviderService provider = null;
|
||||
public AccountManager accManager = null;
|
||||
public String ourAccountID = null;
|
||||
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
// first obtain a reference to the account manager
|
||||
ServiceReference[] serRefs = null;
|
||||
String osgiFilter = "(" + AccountManager.PROTOCOL_PROPERTY_NAME
|
||||
+ "="+ProtocolNames.ICQ+")";
|
||||
try{
|
||||
serRefs = IcqSlickFixture.bc.getServiceReferences(
|
||||
AccountManager.class.getName(), osgiFilter);
|
||||
}
|
||||
catch (InvalidSyntaxException ex){
|
||||
//this really shouldhn't occur as the filter expression is static.
|
||||
fail(osgiFilter + " is not a valid osgi filter");
|
||||
}
|
||||
|
||||
assertTrue(
|
||||
"Failed to find an account manager service for protocol ICQ",
|
||||
serRefs != null || serRefs.length > 0);
|
||||
|
||||
//Keep the reference for later usage.
|
||||
accManager = (AccountManager)
|
||||
IcqSlickFixture.bc.getService(serRefs[0]);
|
||||
|
||||
ourAccountID =
|
||||
System.getProperty(
|
||||
IcqProtocolProviderSlick.TESTED_IMPL_ACCOUNT_ID_PROP_NAME);
|
||||
|
||||
|
||||
//find the protocol provider service
|
||||
ServiceReference[] icqProviderRefs
|
||||
= bc.getServiceReferences(
|
||||
ProtocolProviderService.class.getName(),
|
||||
"(&"
|
||||
+"("+AccountManager.PROTOCOL_PROPERTY_NAME+"="+ProtocolNames.ICQ+")"
|
||||
+"("+AccountManager.ACCOUNT_ID_PROPERTY_NAME+"="
|
||||
+ ourAccountID +")"
|
||||
+")");
|
||||
|
||||
//make sure we found a service
|
||||
assertNotNull("No Protocol Provider was found for ICQ UIN:"+ ourAccountID,
|
||||
icqProviderRefs);
|
||||
assertTrue("No Protocol Provider was found for ICQ UIN:"+ ourAccountID,
|
||||
icqProviderRefs.length > 0);
|
||||
|
||||
//save the service for other tests to use.
|
||||
icqServiceRef = icqProviderRefs[0];
|
||||
provider = (ProtocolProviderService)bc.getService(icqServiceRef);
|
||||
}
|
||||
|
||||
public void tearDown()
|
||||
{
|
||||
bc.ungetService(icqServiceRef);
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.slick.protocol.icq;
|
||||
|
||||
import junit.framework.*;
|
||||
import net.java.sip.communicator.service.protocol.*;
|
||||
import java.util.*;
|
||||
import org.osgi.framework.*;
|
||||
|
||||
/**
|
||||
* Tests basic account manager functionalitites
|
||||
* @author Emil Ivov
|
||||
*/
|
||||
public class TestAccountInstallation extends TestCase
|
||||
{
|
||||
AccountManager icqAccountManager = null;
|
||||
|
||||
public TestAccountInstallation(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception
|
||||
{
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs an account and verifies whether the installation has gone well.
|
||||
*/
|
||||
public void testInstallAccount()
|
||||
{
|
||||
// first obtain a reference to the account manager
|
||||
ServiceReference[] serRefs = null;
|
||||
String osgiFilter = "(" + AccountManager.PROTOCOL_PROPERTY_NAME
|
||||
+ "="+ProtocolNames.ICQ+")";
|
||||
try{
|
||||
serRefs = IcqSlickFixture.bc.getServiceReferences(
|
||||
AccountManager.class.getName(), osgiFilter);
|
||||
}
|
||||
catch (InvalidSyntaxException ex){
|
||||
//this really shouldhn't occur as the filter expression is static.
|
||||
fail(osgiFilter + " is not a valid osgi filter");
|
||||
}
|
||||
|
||||
assertTrue(
|
||||
"Failed to find an account manager service for protocol ICQ",
|
||||
serRefs != null || serRefs.length > 0);
|
||||
|
||||
//Keep the reference for later usage.
|
||||
icqAccountManager = (AccountManager)
|
||||
IcqSlickFixture.bc.getService(serRefs[0]);
|
||||
|
||||
//make sure the account is empty
|
||||
assertTrue("There was an account registered with the account mananger "
|
||||
+"before we've installed any",
|
||||
icqAccountManager.getRegisteredAcounts().size() == 0);
|
||||
|
||||
|
||||
//Prepare the properties of the icq account.
|
||||
|
||||
String passwd = System.getProperty( IcqProtocolProviderSlick
|
||||
.TESTED_IMPL_PWD_PROP_NAME, null );
|
||||
String uin = System.getProperty( IcqProtocolProviderSlick
|
||||
.TESTED_IMPL_ACCOUNT_ID_PROP_NAME, null);
|
||||
|
||||
assertNotNull(
|
||||
"In the " + IcqProtocolProviderSlick.TESTED_IMPL_ACCOUNT_ID_PROP_NAME
|
||||
+" system property, you need to provide a valid icq UIN for the "
|
||||
+" slick to use when signing on icq. It's passwd must be set in "
|
||||
|
||||
+ IcqProtocolProviderSlick.TESTED_IMPL_PWD_PROP_NAME,
|
||||
uin);
|
||||
assertNotNull(
|
||||
"In the " + IcqProtocolProviderSlick.TESTED_IMPL_PWD_PROP_NAME
|
||||
+" system property, you need to provide a password for the "
|
||||
+ uin +" account.",
|
||||
passwd);
|
||||
|
||||
|
||||
Hashtable icqAccountProperties = new Hashtable();
|
||||
icqAccountProperties.put(AccountProperties.PASSWORD, passwd);
|
||||
|
||||
//try to install an account with a null bundle context
|
||||
try{
|
||||
icqAccountManager.installAccount( null, uin, icqAccountProperties);
|
||||
fail("installing an account with a null BundleContext must result "
|
||||
+"in a NullPointerException");
|
||||
}catch(NullPointerException exc){
|
||||
//that's what had to happen
|
||||
}
|
||||
|
||||
//try to install an account with a null account id
|
||||
try{
|
||||
icqAccountManager.installAccount(
|
||||
IcqSlickFixture.bc, null, icqAccountProperties);
|
||||
fail("installing an account with a null account id must result "
|
||||
+"in a NullPointerException");
|
||||
}catch(NullPointerException exc){
|
||||
//that's what had to happen
|
||||
}
|
||||
|
||||
//now really install the account
|
||||
IcqSlickFixture.icqAccountID = icqAccountManager.installAccount(
|
||||
IcqSlickFixture.bc, uin, icqAccountProperties);
|
||||
|
||||
//try to install the account one more time and verify that an excepion
|
||||
//is thrown.
|
||||
try{
|
||||
IcqSlickFixture.icqAccountID = icqAccountManager.installAccount(
|
||||
IcqSlickFixture.bc, uin, icqAccountProperties);
|
||||
fail("An IllegalStateException must be thrown when trying to "+
|
||||
"install a duplicate account");
|
||||
|
||||
}catch(IllegalStateException exc)
|
||||
{
|
||||
//that's what supposed to happen.
|
||||
}
|
||||
|
||||
//Verify that the account manager is aware of our installation
|
||||
assertTrue(
|
||||
"The newly installed account was not in the acc man's "
|
||||
+"registered accounts!",
|
||||
icqAccountManager.getRegisteredAcounts().size() == 1);
|
||||
|
||||
//Verify that the protocol provider corresponding to the new account has
|
||||
//been properly registered with the osgi framework.
|
||||
|
||||
osgiFilter =
|
||||
"(&("+AccountManager.PROTOCOL_PROPERTY_NAME +"="+ProtocolNames.ICQ+")"
|
||||
+"(" + AccountManager.ACCOUNT_ID_PROPERTY_NAME
|
||||
+ "=" + IcqSlickFixture.icqAccountID.getAccountID() + "))";
|
||||
|
||||
try
|
||||
{
|
||||
serRefs = IcqSlickFixture.bc.getServiceReferences(
|
||||
ProtocolProviderService.class.getName(),
|
||||
osgiFilter);
|
||||
}
|
||||
catch (InvalidSyntaxException ex)
|
||||
{
|
||||
//this really shouldhn't occur as the filter expression is static.
|
||||
fail(osgiFilter + "is not a valid osgi filter");
|
||||
}
|
||||
|
||||
assertTrue("An ICQ protocol provider was apparently not installed as "
|
||||
+ "requested."
|
||||
, serRefs != null && serRefs.length > 0);
|
||||
|
||||
Object icqProtocolProvider
|
||||
= IcqSlickFixture.bc.getService(serRefs[0]);
|
||||
|
||||
assertTrue("The installed protocol provider does not implement "
|
||||
+ "the protocol provider service."
|
||||
,icqProtocolProvider instanceof ProtocolProviderService);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.slick.protocol.icq;
|
||||
|
||||
import junit.framework.*;
|
||||
import net.java.sip.communicator.service.protocol.*;
|
||||
import org.osgi.framework.*;
|
||||
|
||||
/**
|
||||
* Tests whether accaounts are uninstalled properly. It is important that
|
||||
* tests from this class be called last since they will install the accounts
|
||||
* that have been used to test the implementations.
|
||||
*
|
||||
* @author Emil Ivov
|
||||
*/
|
||||
public class TestAccountUninstallation
|
||||
extends TestCase
|
||||
{
|
||||
IcqSlickFixture fixture = new IcqSlickFixture();
|
||||
|
||||
public TestAccountUninstallation(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
fixture.setUp();
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception
|
||||
{
|
||||
fixture.tearDown();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Uinstalls our test account and makes sure it really has been removed.
|
||||
*/
|
||||
public void testUninstallAccount()
|
||||
{
|
||||
assertFalse("No installed accaounts found",
|
||||
fixture.accManager.getRegisteredAcounts().isEmpty());
|
||||
|
||||
assertNotNull(
|
||||
"Found no provider corresponding to account ID "
|
||||
+ fixture.icqAccountID,
|
||||
fixture.accManager.getProviderForAccount(fixture.icqAccountID));
|
||||
|
||||
assertTrue(
|
||||
"Failed to remove a provider corresponding to acc id "
|
||||
+ fixture.icqAccountID,
|
||||
fixture.accManager.uninstallAccount(fixture.icqAccountID));
|
||||
|
||||
ServiceReference[] icqProviderRefs = null;
|
||||
try
|
||||
{
|
||||
icqProviderRefs = fixture.bc.getServiceReferences(
|
||||
ProtocolProviderService.class.getName(),
|
||||
"(&"
|
||||
+ "(" + AccountManager.PROTOCOL_PROPERTY_NAME + "=" +ProtocolNames.ICQ + ")"
|
||||
+ "(" + AccountManager.ACCOUNT_ID_PROPERTY_NAME + "="+ fixture.icqAccountID + ")"
|
||||
+ ")");
|
||||
}
|
||||
catch (InvalidSyntaxException ex)
|
||||
{
|
||||
fail("We apparently got our filter wrhong");
|
||||
}
|
||||
|
||||
//make sure we didn't see a service
|
||||
assertTrue("A Protocol Provider Service was still regged as an osgi service "
|
||||
+"for ICQ UIN:" + fixture.icqAccountID
|
||||
+ "After it was explicitly uninstalled"
|
||||
,icqProviderRefs == null || icqProviderRefs.length == 0);
|
||||
|
||||
//verify that the provider knows that we have uninstalled the service.
|
||||
assertTrue(
|
||||
"The ICQ account manager kept a reference to the provider we just "
|
||||
+"uninstalled (accID="+fixture.icqAccountID+")",
|
||||
fixture.accManager.getRegisteredAcounts().isEmpty()
|
||||
&& fixture.accManager.getProviderForAccount(fixture.icqAccountID) == null
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.slick.protocol.icq;
|
||||
|
||||
import junit.framework.*;
|
||||
|
||||
/**
|
||||
* @todo describe
|
||||
* @author Emil Ivov
|
||||
*/
|
||||
public class TestOperationSetBasicInstantMessaging
|
||||
extends TestCase
|
||||
{
|
||||
IcqSlickFixture fixture = new IcqSlickFixture();
|
||||
|
||||
public TestOperationSetBasicInstantMessaging(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
fixture.setUp();
|
||||
|
||||
/** @todo extract corresponding presence set here */
|
||||
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception
|
||||
{
|
||||
fixture.tearDown();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public void testSendMessage()
|
||||
{
|
||||
/** @todo implement testSendMessage() */
|
||||
}
|
||||
|
||||
public void testReceiveMessage()
|
||||
{
|
||||
/**
|
||||
* @todo implement testReceiveMessage()
|
||||
*/
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,564 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.slick.protocol.icq;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import junit.framework.*;
|
||||
import net.java.sip.communicator.service.protocol.*;
|
||||
import net.java.sip.communicator.service.protocol.event.*;
|
||||
import net.java.sip.communicator.util.*;
|
||||
|
||||
/**
|
||||
* @todo describe
|
||||
*
|
||||
* @todo testing here would probably be best done if we could first log in
|
||||
* with one of the agents retrieve the contact list and then check that we
|
||||
* have the same thing with the other agent
|
||||
*
|
||||
* @author Emil Ivov
|
||||
*/
|
||||
public class TestOperationSetPersistentPresence
|
||||
extends TestCase
|
||||
{
|
||||
private static final Logger logger =
|
||||
Logger.getLogger(TestOperationSetPersistentPresence.class);
|
||||
|
||||
private IcqSlickFixture fixture = new IcqSlickFixture();
|
||||
private OperationSetPersistentPresence opSetPersPresence = null;
|
||||
private static final String testGroupName = "NewGroup";
|
||||
private static final String testGroupName2 = "Renamed";
|
||||
|
||||
public TestOperationSetPersistentPresence(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a test suite containing all tests of this class followed by
|
||||
* test methods that we want executed in a specified order.
|
||||
* @return the Test suite to run
|
||||
*/
|
||||
public static Test suite()
|
||||
{
|
||||
TestSuite suite =
|
||||
new TestSuite(TestOperationSetPersistentPresence.class);
|
||||
|
||||
//the following 2 need to be run in the specified order.
|
||||
//(postTestRemoveGroup() needs the group created from
|
||||
//postTestCreateGroup() )
|
||||
suite.addTest(
|
||||
new TestOperationSetPersistentPresence("postTestCreateGroup"));
|
||||
|
||||
// suite.addTest( new TestOperationSetPersistentPresence(
|
||||
// "postTestPersistentSubscribe"));
|
||||
// suite.addTest( new TestOperationSetPersistentPresence(
|
||||
// "postTestPersistentUnsubscribe"));
|
||||
|
||||
//rename
|
||||
suite.addTest( new TestOperationSetPersistentPresence(
|
||||
"postTestRenameGroup"));
|
||||
|
||||
suite.addTest(
|
||||
new TestOperationSetPersistentPresence("postTestRemoveGroup"));
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
fixture.setUp();
|
||||
|
||||
Map supportedOperationSets =
|
||||
fixture.provider.getSupportedOperationSets();
|
||||
|
||||
if ( supportedOperationSets == null
|
||||
|| supportedOperationSets.size() < 1)
|
||||
throw new NullPointerException(
|
||||
"No OperationSet implementations are supported by "
|
||||
+"this ICQ implementation. ");
|
||||
|
||||
//get the operation set presence here.
|
||||
opSetPersPresence =
|
||||
(OperationSetPersistentPresence)supportedOperationSets.get(
|
||||
OperationSetPersistentPresence.class.getName());
|
||||
|
||||
//if still null then the implementation doesn't offer a presence
|
||||
//operation set which is unacceptable for icq.
|
||||
if (opSetPersPresence == null)
|
||||
throw new NullPointerException(
|
||||
"An implementation of the ICQ service must provide an "
|
||||
+ "implementation of at least the one of the Presence "
|
||||
+ "Operation Sets");
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception
|
||||
{
|
||||
fixture.tearDown();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a server stored contact list and checks whether it contains
|
||||
* all contacts that have been added there during the initialization
|
||||
* phase by the icqTesterAgent.
|
||||
*/
|
||||
public void testRetrievingServerStoredContactList()
|
||||
{
|
||||
ContactGroup rootGroup
|
||||
= opSetPersPresence.getServerStoredContactListRoot();
|
||||
|
||||
logger.debug("=========== Server Stored Contact List =================");
|
||||
|
||||
logger.debug("rootGroup="+rootGroup.getGroupName()
|
||||
+" rootGroup.childContacts="+rootGroup.countContacts()
|
||||
+ "rootGroup.childGroups="+rootGroup.countSubGroups()
|
||||
+ "Printing rootGroupContents=\n"+rootGroup.toString());
|
||||
|
||||
Hashtable expectedContactList = fixture.preInstalledBuddyList;
|
||||
|
||||
logger.debug("============== Expected Contact List ===================");
|
||||
logger.debug(expectedContactList);
|
||||
|
||||
//Go through the contact list retrieved by the persistence presence set
|
||||
//and remove the name of every contact and group that we find there from
|
||||
//the expected contct list hashtable.
|
||||
Iterator groups = rootGroup.subGroups();
|
||||
while (groups.hasNext() ){
|
||||
ContactGroup group = (ContactGroup)groups.next();
|
||||
|
||||
List expectedContactsInGroup
|
||||
= (List)expectedContactList.get(group.getGroupName());
|
||||
|
||||
assertNotNull("Group " + group.getGroupName() + " was returned by "
|
||||
+"the server but was not in the expected contact list."
|
||||
, expectedContactsInGroup );
|
||||
|
||||
Iterator contactsIter = group.contacts();
|
||||
while (contactsIter.hasNext()){
|
||||
String contactID = ((Contact)contactsIter.next()).getAddress();
|
||||
expectedContactsInGroup.remove(contactID);
|
||||
}
|
||||
|
||||
//If we've removed all the sub contacts, remove the group too.
|
||||
if (expectedContactsInGroup.size() == 0 )
|
||||
expectedContactList.remove(group.getGroupName());
|
||||
}
|
||||
|
||||
//whatever we now have in the expected contact list snapshot are groups,
|
||||
//that have been added by the IcqTesterAgent but that were not retrieved
|
||||
//by the persistent presence operation set.
|
||||
assertTrue("The following contacts were on the server sidec contact "
|
||||
+"list, but were not returned by the pers. pres. op. set"
|
||||
+ expectedContactList.toString()
|
||||
, expectedContactList.isEmpty());
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the a contact to a group in our contact list. Verifies that event
|
||||
* dispatching goes ok. Makes sure that the contact is where it is supposed
|
||||
* to be.
|
||||
* <p>
|
||||
* Note that the method won't be testing presence event notifications since
|
||||
* these are being tested in TestOperationSetPresence.
|
||||
*
|
||||
* @throws java.lang.Exception in case network operations fail.
|
||||
*/
|
||||
public void postTestPersistentSubscribe()
|
||||
throws Exception
|
||||
{
|
||||
logger.trace("Testing persistent subscriptions.");
|
||||
//find the group where we'll be adding the new contact
|
||||
ContactGroup group = opSetPersPresence.getServerStoredContactListRoot()
|
||||
.getGroup(testGroupName);
|
||||
|
||||
//register a subscription event listener
|
||||
SubscriptionEventCollector evtCollector
|
||||
= new SubscriptionEventCollector();
|
||||
opSetPersPresence.addSubsciptionListener(evtCollector);
|
||||
|
||||
//create the subscription and wait for a confirmation event.
|
||||
opSetPersPresence.subscribe(group, "38687470");
|
||||
|
||||
evtCollector.waitForEvent(10000);
|
||||
|
||||
opSetPersPresence.removeSubsciptionListener(evtCollector);
|
||||
|
||||
//make sure the event delivery went as expected
|
||||
assertEquals("Number of dispatched events",
|
||||
1, evtCollector.collectedEvents.size());
|
||||
|
||||
assertEquals(
|
||||
"The SubscriptionEvent had a wrong event id.",
|
||||
SubscriptionEvent.SUBSCRIPTION_CREATED,
|
||||
((SubscriptionEvent)evtCollector.collectedEvents.get(0)).getEventID());
|
||||
|
||||
assertEquals(
|
||||
"The parent group in the subscription event did not match.",
|
||||
group, ((SubscriptionEvent)evtCollector.collectedEvents.get(0))
|
||||
.getParentGroup());
|
||||
|
||||
Contact contact = group.getContact(fixture.testerAgent.getIcqUIN());
|
||||
|
||||
//make sure that the contact appears in the new group.
|
||||
assertNotNull("Couldn't find contact where we created it", contact);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Removes a contact from a group in our contact list. Verifies that event
|
||||
* dispatching goes ok. Makes sure that the contact is not in the group
|
||||
* any more.
|
||||
* <p>
|
||||
* Note that the method won't be testing presence event notifications since
|
||||
* these are being tested in TestOperationSetPresence.
|
||||
*
|
||||
* @throws java.lang.Exception in case network operations fail.
|
||||
*/
|
||||
public void postTestPersistentUnsubscribe()
|
||||
throws Exception
|
||||
{
|
||||
logger.trace("Testing removal of persistent subscriptions.");
|
||||
//find the group where we'll be adding the new contact
|
||||
ContactGroup group = opSetPersPresence.getServerStoredContactListRoot()
|
||||
.getGroup(testGroupName);
|
||||
|
||||
Contact contact = group.getContact(fixture.testerAgent.getIcqUIN());
|
||||
|
||||
//register a subscription event listener
|
||||
SubscriptionEventCollector evtCollector
|
||||
= new SubscriptionEventCollector();
|
||||
opSetPersPresence.addSubsciptionListener(evtCollector);
|
||||
|
||||
//remove the subscription and wait for a confirmation event.
|
||||
opSetPersPresence.unsubscribe(contact);
|
||||
|
||||
evtCollector.waitForEvent(10000);
|
||||
|
||||
opSetPersPresence.removeSubsciptionListener(evtCollector);
|
||||
|
||||
//make sure the event delivery went as expected
|
||||
assertEquals("Number of dispatched events",
|
||||
1, evtCollector.collectedEvents.size());
|
||||
|
||||
assertEquals(
|
||||
"The SubscriptionEvent had a wrong event id.",
|
||||
SubscriptionEvent.SUBSCRIPTION_REMOVED,
|
||||
((SubscriptionEvent)evtCollector.collectedEvents.get(0)).getEventID());
|
||||
|
||||
assertEquals(
|
||||
"The parent group in the subscription event did not match.",
|
||||
group, ((SubscriptionEvent)evtCollector.collectedEvents.get(0))
|
||||
.getParentGroup());
|
||||
|
||||
contact = group.getContact(fixture.testerAgent.getIcqUIN());
|
||||
|
||||
//make sure that the contact is not in the group any more.
|
||||
assertNull("A contact was still present after removing its "
|
||||
+"corresponding subscription", contact);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a group in the server stored contact list, makes sure that the
|
||||
* corresponding event has been generated and verifies that the group is
|
||||
* in the list.
|
||||
*/
|
||||
public void postTestCreateGroup()
|
||||
{
|
||||
logger.trace("testing creation of server stored groups");
|
||||
//first add a listener
|
||||
GroupChangeCollector groupChangeCollector = new GroupChangeCollector();
|
||||
opSetPersPresence
|
||||
.addServerStoredGroupChangeListener(groupChangeCollector);
|
||||
|
||||
//create the group
|
||||
opSetPersPresence.createServerStoredContactGroup(
|
||||
opSetPersPresence.getServerStoredContactListRoot(), testGroupName);
|
||||
|
||||
groupChangeCollector.waitForEvent(10000);
|
||||
|
||||
opSetPersPresence
|
||||
.removeServerStoredGroupChangeListener(groupChangeCollector);
|
||||
|
||||
// check whether we got group created event
|
||||
assertEquals("Collected Group Change events: ",
|
||||
1, groupChangeCollector.collectedEvents.size());
|
||||
|
||||
assertEquals("Group name.", testGroupName,
|
||||
((ServerStoredGroupEvent)groupChangeCollector.collectedEvents
|
||||
.get(0)).getSrouceGroup().getGroupName());
|
||||
|
||||
// check whether the group is retrievable
|
||||
ContactGroup group = opSetPersPresence.getServerStoredContactListRoot()
|
||||
.getGroup(testGroupName);
|
||||
|
||||
assertNotNull("A newly created group was not in the contact list.",
|
||||
group);
|
||||
|
||||
assertEquals("New group name", testGroupName, group.getGroupName());
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes the group created in the server stored contact list by the create
|
||||
* group test, makes sure that the corresponding event has been generated
|
||||
* and verifies that the group is not in the list any more.
|
||||
*/
|
||||
public void postTestRemoveGroup()
|
||||
{
|
||||
logger.trace("testing removal of server stored groups");
|
||||
|
||||
//first add a listener
|
||||
GroupChangeCollector groupChangeCollector = new GroupChangeCollector();
|
||||
opSetPersPresence
|
||||
.addServerStoredGroupChangeListener(groupChangeCollector);
|
||||
|
||||
//create the group
|
||||
opSetPersPresence.removeServerStoredContactGroup(
|
||||
opSetPersPresence.getServerStoredContactListRoot()
|
||||
.getGroup(testGroupName2));
|
||||
|
||||
groupChangeCollector.waitForEvent(10000);
|
||||
|
||||
opSetPersPresence
|
||||
.removeServerStoredGroupChangeListener(groupChangeCollector);
|
||||
|
||||
// check whether we got group created event
|
||||
assertEquals("Collected Group Change event",
|
||||
1, groupChangeCollector.collectedEvents.size());
|
||||
|
||||
assertEquals("Group name.", testGroupName2,
|
||||
((ServerStoredGroupEvent)groupChangeCollector.collectedEvents
|
||||
.get(0)).getSrouceGroup().getGroupName());
|
||||
|
||||
// check whether the group is still on the contact list
|
||||
ContactGroup group = opSetPersPresence.getServerStoredContactListRoot()
|
||||
.getGroup(testGroupName2);
|
||||
|
||||
assertNull("A freshly removed group was still on the contact list.",
|
||||
group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames our test group and checks whether corresponding events are
|
||||
* triggered. Verifies whether the group has really changed its name and
|
||||
* whether it is findable by its new name. Also makes sure that it does
|
||||
* not exist under its previous name any more.
|
||||
*/
|
||||
public void postTestRenameGroup()
|
||||
{
|
||||
logger.trace("Testing renaming groups.");
|
||||
|
||||
ContactGroup group = opSetPersPresence.getServerStoredContactListRoot()
|
||||
.getGroup(testGroupName);
|
||||
|
||||
//first add a listener
|
||||
GroupChangeCollector groupChangeCollector = new GroupChangeCollector();
|
||||
opSetPersPresence
|
||||
.addServerStoredGroupChangeListener(groupChangeCollector);
|
||||
|
||||
//change the name and wait for a confirmation event
|
||||
opSetPersPresence.renameServerStoredContactGroup(group, testGroupName2);
|
||||
|
||||
groupChangeCollector.waitForEvent(10000);
|
||||
|
||||
opSetPersPresence
|
||||
.removeServerStoredGroupChangeListener(groupChangeCollector);
|
||||
|
||||
//examine the event
|
||||
assertEquals("Collected Group Change event",
|
||||
1, groupChangeCollector.collectedEvents.size());
|
||||
|
||||
assertEquals("Group name.", testGroupName2,
|
||||
((ServerStoredGroupEvent)groupChangeCollector.collectedEvents
|
||||
.get(0)).getSrouceGroup().getGroupName());
|
||||
|
||||
// check whether the group is still on the contact list
|
||||
ContactGroup oldGroup = opSetPersPresence.getServerStoredContactListRoot()
|
||||
.getGroup(testGroupName);
|
||||
|
||||
assertNull("A group was still findable by its old name after renaming.",
|
||||
oldGroup);
|
||||
|
||||
//make sure that we could find the group by its new name.
|
||||
ContactGroup newGroup = opSetPersPresence.getServerStoredContactListRoot()
|
||||
.getGroup(testGroupName2);
|
||||
|
||||
assertNotNull("Could not find a renamed group by its new name.",
|
||||
newGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* The class would listen for and store received events delivered to
|
||||
* <code>ServerStoredGroupListener</code>s.
|
||||
*/
|
||||
private class GroupChangeCollector implements ServerStoredGroupListener
|
||||
{
|
||||
public ArrayList collectedEvents = new ArrayList();
|
||||
|
||||
/**
|
||||
* Blocks until at least one event is received or until waitFor
|
||||
* miliseconds pass (whicever happens first).
|
||||
*
|
||||
* @param waitFor the number of miliseconds that we should be waiting
|
||||
* for an event before simply bailing out.
|
||||
*/
|
||||
public void waitForEvent(long waitFor)
|
||||
{
|
||||
synchronized(this){
|
||||
if(collectedEvents.size() > 0)
|
||||
return;
|
||||
|
||||
try{
|
||||
wait(waitFor);
|
||||
}
|
||||
catch (InterruptedException ex){
|
||||
logger.debug(
|
||||
"Interrupted while waiting for a subscription evt", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whnever an indication is received that a new server stored
|
||||
* group is created.
|
||||
* @param evt a ServerStoredGroupChangeEvent containing a reference to
|
||||
* the newly created group.
|
||||
*/
|
||||
public void groupCreated(ServerStoredGroupEvent evt)
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
|
||||
collectedEvents.add(evt);
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an indication is received that the name of a server stored
|
||||
* contact group has changed.
|
||||
* @param evt a ServerStoredGroupChangeEvent containing the details of the
|
||||
* name change.
|
||||
*/
|
||||
public void groupNameChanged(ServerStoredGroupEvent evt)
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
|
||||
collectedEvents.add(evt);
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whnever an indication is received that an existing server stored
|
||||
* group has been removed.
|
||||
* @param evt a ServerStoredGroupChangeEvent containing a reference to the
|
||||
* newly created group.
|
||||
*/
|
||||
public void groupRemoved(ServerStoredGroupEvent evt)
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
|
||||
collectedEvents.add(evt);
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The class would listen for and store received subscription modification
|
||||
* events.
|
||||
*/
|
||||
private class SubscriptionEventCollector implements SubscriptionListener
|
||||
{
|
||||
public ArrayList collectedEvents = new ArrayList();
|
||||
|
||||
/**
|
||||
* Blocks until at least one event is received or until waitFor
|
||||
* miliseconds pass (whicever happens first).
|
||||
*
|
||||
* @param waitFor the number of miliseconds that we should be waiting
|
||||
* for an event before simply bailing out.
|
||||
*/
|
||||
public void waitForEvent(long waitFor)
|
||||
{
|
||||
logger.trace("Waiting for a persistent subscription event");
|
||||
|
||||
synchronized(this){
|
||||
if(collectedEvents.size() > 0){
|
||||
logger.trace("SubEvt already received. " + collectedEvents);
|
||||
return;
|
||||
}
|
||||
|
||||
try{
|
||||
wait(waitFor);
|
||||
if(collectedEvents.size() > 0)
|
||||
logger.trace("Received a SubEvt in provider status.");
|
||||
else
|
||||
logger.trace("No SubEvt received for "+waitFor+"ms.");
|
||||
}
|
||||
catch (InterruptedException ex){
|
||||
logger.debug(
|
||||
"Interrupted while waiting for a subscription evt", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the received subsctiption and notifies all waiting on this
|
||||
* object
|
||||
* @param evt the SubscriptionEvent containing the corresponding contact
|
||||
*/
|
||||
public void subscriptionCreated(SubscriptionEvent evt)
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
|
||||
collectedEvents.add(evt);
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the received subsctiption and notifies all waiting on this
|
||||
* object
|
||||
* @param evt the SubscriptionEvent containing the corresponding contact
|
||||
*/
|
||||
public void subscriptionRemoved(SubscriptionEvent evt)
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
|
||||
collectedEvents.add(evt);
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the received subsctiption and notifies all waiting on this
|
||||
* object
|
||||
* @param evt the SubscriptionEvent containing the corresponding contact
|
||||
*/
|
||||
public void subscriptionFailed(SubscriptionEvent evt)
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
|
||||
collectedEvents.add(evt);
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,844 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.slick.protocol.icq;
|
||||
|
||||
import junit.framework.*;
|
||||
|
||||
import net.java.sip.communicator.service.protocol.*;
|
||||
import java.util.*;
|
||||
|
||||
import net.java.sip.communicator.service.protocol.icqconstants.*;
|
||||
import net.java.sip.communicator.service.protocol.event.*;
|
||||
import net.java.sip.communicator.util.*;
|
||||
import net.kano.joscar.snaccmd.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
|
||||
/**
|
||||
* Tests ICQ implementations of a Presence Operation Set. Tests in this class
|
||||
* verify functionality such as: Changing local (our own) status and
|
||||
* corresponding event dispatching; Querying status of contacts, Subscribing
|
||||
* for presence notifications upong status changes of specific contacts.
|
||||
* <p>
|
||||
* Using a custom suite() method, we make sure that apart from standard test
|
||||
* methods (those with a <code>test</code> prefix) we also execute those that
|
||||
* we want run in a specific order like for example - postTestSubscribe() and
|
||||
* postTestUnsubscribe().
|
||||
* <p>
|
||||
* @author Emil Ivov
|
||||
*/
|
||||
public class TestOperationSetPresence
|
||||
extends TestCase
|
||||
{
|
||||
private static final Logger logger =
|
||||
Logger.getLogger(TestOperationSetPresence.class);
|
||||
|
||||
private IcqSlickFixture fixture = new IcqSlickFixture();
|
||||
private OperationSetPresence operationSetPresence = null;
|
||||
private String statusMessageRoot = new String("Our status is now: ");
|
||||
|
||||
public TestOperationSetPresence(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
fixture.setUp();
|
||||
|
||||
Map supportedOperationSets =
|
||||
fixture.provider.getSupportedOperationSets();
|
||||
|
||||
if ( supportedOperationSets == null
|
||||
|| supportedOperationSets.size() < 1)
|
||||
throw new NullPointerException(
|
||||
"No OperationSet implementations are supported by "
|
||||
+"this ICQ implementation. ");
|
||||
|
||||
//get the operation set presence here.
|
||||
operationSetPresence =
|
||||
(OperationSetPresence)supportedOperationSets.get(
|
||||
OperationSetPresence.class.getName());
|
||||
|
||||
if (operationSetPresence == null)
|
||||
{
|
||||
//if the operation set is still null, it's maybe because the impl
|
||||
//only registers a persistence operation set. Let's see if that is
|
||||
//the case.
|
||||
operationSetPresence =
|
||||
(OperationSetPersistentPresence) supportedOperationSets.get(
|
||||
OperationSetPersistentPresence.class.getName());
|
||||
|
||||
//if still null then the implementation doesn't offer a presence
|
||||
//operation set which is unacceptable for icq.
|
||||
if (operationSetPresence == null)
|
||||
throw new NullPointerException(
|
||||
"An implementation of the ICQ service must provide an "
|
||||
+ "implementation of at least the one of the Presence "
|
||||
+ "Operation Sets");
|
||||
}
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception
|
||||
{
|
||||
super.tearDown();
|
||||
|
||||
fixture.tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a test suite containing all tests of this class followed by
|
||||
* test methods that we want executed in a specified order.
|
||||
* @return Test
|
||||
*/
|
||||
public static Test suite()
|
||||
{
|
||||
TestSuite suite = new TestSuite(TestOperationSetPresence.class);
|
||||
|
||||
//the following 2 need to be run in the specified order.
|
||||
//(postTestUnsubscribe() needs the subscription created from
|
||||
//postTestSubscribe() )
|
||||
suite.addTest(new TestOperationSetPresence("postTestSubscribe"));
|
||||
suite.addTest(new TestOperationSetPresence("postTestUnsubscribe"));
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that all necessary ICQ test states are supported by the
|
||||
* implementation.
|
||||
*/
|
||||
public void testSupportedStatusSetForCompleteness()
|
||||
{
|
||||
//first create a local list containing the presence status instances
|
||||
//supported by the underlying implementation.
|
||||
Iterator supportedStatusSetIter =
|
||||
operationSetPresence.getSupportedStatusSet();
|
||||
|
||||
List supportedStatusSet = new LinkedList();
|
||||
while (supportedStatusSetIter.hasNext()){
|
||||
supportedStatusSet.add(supportedStatusSetIter.next());
|
||||
}
|
||||
|
||||
//create a copy of the MUST status set and remove any matching status
|
||||
//that is also present in the supported set.
|
||||
List requiredStatusSetCopy = (List)IcqStatusEnum.icqStatusSet.clone();
|
||||
|
||||
requiredStatusSetCopy.removeAll(supportedStatusSet);
|
||||
|
||||
//if we have anything left then the implementation is wrong.
|
||||
int unsupported = requiredStatusSetCopy.size();
|
||||
assertTrue( "There are " + unsupported + " statuses as follows:"
|
||||
+ requiredStatusSetCopy,
|
||||
unsupported == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that changing state to AWAY works as supposed to and that it
|
||||
* generates the corresponding event.
|
||||
* @throws Exception in case a failure occurs while the operation set
|
||||
* is switching to the new state.
|
||||
*/
|
||||
public void testChangingStateToAway() throws Exception
|
||||
{
|
||||
subtestStateTransition(IcqStatusEnum.AWAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that changing state to NOT_AVAILABLE works as supposed to and that it
|
||||
* generates the corresponding event.
|
||||
* @throws Exception in case a failure occurs while the operation set
|
||||
* is switching to the new state.
|
||||
*/
|
||||
public void testChangingStateToNotAvailable() throws Exception
|
||||
{
|
||||
subtestStateTransition(IcqStatusEnum.NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that changing state to DND works as supposed to and that it
|
||||
* generates the corresponding event.
|
||||
* @throws Exception in case a failure occurs while the operation set
|
||||
* is switching to the new state.
|
||||
*/
|
||||
public void testChangingStateToDnd() throws Exception
|
||||
{
|
||||
subtestStateTransition(IcqStatusEnum.DO_NOT_DISTURB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that changing state to INVISIBLE works as supposed to and that it
|
||||
* generates the corresponding event.
|
||||
* @throws Exception in case a failure occurs while the operation set
|
||||
* is switching to the new state.
|
||||
*/
|
||||
public void testChangingStateToInvisible() throws Exception
|
||||
{
|
||||
subtestStateTransition(IcqStatusEnum.INVISIBLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that changing state to OCCUPIED works as supposed to and that it
|
||||
* generates the corresponding event.
|
||||
* @throws Exception in case a failure occurs while the operation set
|
||||
* is switching to the new state.
|
||||
*/
|
||||
public void testChangingStateToOccupied() throws Exception
|
||||
{
|
||||
subtestStateTransition(IcqStatusEnum.OCCUPIED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that changing state to FREE_FOR_CHAT works as supposed to and that it
|
||||
* generates the corresponding event.
|
||||
* @throws Exception in case a failure occurs while the operation set
|
||||
* is switching to the new state.
|
||||
*/
|
||||
public void testChangingStateToFreeForChat() throws Exception
|
||||
{
|
||||
subtestStateTransition(IcqStatusEnum.FREE_FOR_CHAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that changing state to ONLINE works as supposed to and that it
|
||||
* generates the corresponding event.
|
||||
* @throws Exception in case a failure occurs while the operation set
|
||||
* is switching to the new state.
|
||||
*/
|
||||
public void testChangingStateToOnline() throws Exception
|
||||
{
|
||||
java.util.logging.Logger.getLogger("net.kano").setLevel(java.util.logging.Level.FINEST);
|
||||
subtestStateTransition(IcqStatusEnum.ONLINE);
|
||||
java.util.logging.Logger.getLogger("net.kano").setLevel(java.util.logging.Level.WARNING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by methods testing state transiotions
|
||||
*
|
||||
* @param newStatus the IcqStatusEnum field corresponding to the status
|
||||
* that we'd like the opeation set to enter.
|
||||
*
|
||||
* @throws Exception in case changing the state causes an exception
|
||||
*/
|
||||
public void subtestStateTransition( IcqStatusEnum newStatus)
|
||||
throws Exception
|
||||
{
|
||||
logger.trace(" --=== beginning state transition test ===--");
|
||||
|
||||
PresenceStatus oldStatus = operationSetPresence.getPresenceStatus();
|
||||
String oldStatusMessage = operationSetPresence.getCurrentStatusMessage();
|
||||
String newStatusMessage = statusMessageRoot + newStatus;
|
||||
|
||||
logger.debug( "old status is=" + oldStatus.getStatusName()
|
||||
+ " new status=" + newStatus.getStatusName());
|
||||
|
||||
//First register a listener to make sure that all corresponding
|
||||
//events have been generated.
|
||||
PresenceStatusEventCollector statusEventCollector
|
||||
= new PresenceStatusEventCollector();
|
||||
operationSetPresence.addProviderPresenceStatusListener(
|
||||
statusEventCollector);
|
||||
|
||||
//change the status
|
||||
operationSetPresence.publishPresenceStatus(newStatus, newStatusMessage);
|
||||
|
||||
//test event notification.
|
||||
statusEventCollector.waitForPresEvent(10000);
|
||||
statusEventCollector.waitForStatMsgEvent(10000);
|
||||
|
||||
operationSetPresence.removeProviderPresenceStatusListener(
|
||||
statusEventCollector);
|
||||
|
||||
assertEquals("Events dispatched during an event transition.",
|
||||
1, statusEventCollector.collectedPresEvents.size());
|
||||
assertEquals("A status changed event contained wrong old status.",
|
||||
oldStatus,
|
||||
((ProviderPresenceStatusChangeEvent)
|
||||
statusEventCollector.collectedPresEvents.get(0))
|
||||
.getOldStatus());
|
||||
assertEquals("A status changed event contained wrong new status.",
|
||||
newStatus,
|
||||
((ProviderPresenceStatusChangeEvent)
|
||||
statusEventCollector.collectedPresEvents.get(0))
|
||||
.getNewStatus());
|
||||
|
||||
// verify that the operation set itself is aware of the status change
|
||||
assertEquals("opSet.getPresenceStatus() did not return properly.",
|
||||
newStatus,
|
||||
operationSetPresence.getPresenceStatus());
|
||||
|
||||
IcqStatusEnum actualStatus = fixture.testerAgent.getBuddyStatus(
|
||||
fixture.icqAccountID.getAccountID());
|
||||
assertEquals("The underlying implementation did not switch to the "
|
||||
+"requested presence status.",
|
||||
newStatus,
|
||||
actualStatus);
|
||||
|
||||
//check whether the server returned the status message that we've set.
|
||||
assertEquals("No status message events.",
|
||||
1, statusEventCollector.collectedStatMsgEvents.size());
|
||||
assertEquals("A status message event contained wrong old value.",
|
||||
oldStatusMessage,
|
||||
((PropertyChangeEvent)
|
||||
statusEventCollector.collectedStatMsgEvents.get(0))
|
||||
.getOldValue());
|
||||
assertEquals("A status message event contained wrong new value.",
|
||||
newStatusMessage,
|
||||
((PropertyChangeEvent)
|
||||
statusEventCollector.collectedStatMsgEvents.get(0))
|
||||
.getNewValue());
|
||||
|
||||
// verify that the operation set itself is aware of the new status msg.
|
||||
assertEquals("opSet.getCurrentStatusMessage() did not return properly.",
|
||||
newStatusMessage,
|
||||
operationSetPresence.getCurrentStatusMessage());
|
||||
|
||||
logger.trace(" --=== finished test ===--");
|
||||
//make it sleep a bit cause the aol server gets mad otherwise.
|
||||
pauseBetweenStateChanges();
|
||||
}
|
||||
|
||||
/**
|
||||
* The AIM server doesn't like it if we change states too often and we
|
||||
* use this method to slow things down.
|
||||
*/
|
||||
private void pauseBetweenStateChanges()
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.currentThread().sleep(2000);
|
||||
}
|
||||
catch (InterruptedException ex)
|
||||
{
|
||||
logger.debug("Pausing between state changes was interrupted", ex);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Verifies that querying status works fine. The ICQ tester agent would
|
||||
* change status and the operation set would have to return the right status
|
||||
* after every change.
|
||||
*
|
||||
* @throws java.lang.Exception if one of the transitions fails
|
||||
*/
|
||||
public void testQueryContactStatus()
|
||||
throws Exception
|
||||
{
|
||||
// --- AWAY ---
|
||||
logger.debug("Will Query an AWAY contact.");
|
||||
subtestQueryContactStatus(FullUserInfo.ICQSTATUS_AWAY,
|
||||
IcqStatusEnum.AWAY);
|
||||
|
||||
pauseBetweenStateChanges();
|
||||
|
||||
// --- NA ---
|
||||
logger.debug("Will Query an NA contact.");
|
||||
subtestQueryContactStatus(FullUserInfo.ICQSTATUS_NA,
|
||||
IcqStatusEnum.NOT_AVAILABLE);
|
||||
|
||||
pauseBetweenStateChanges();
|
||||
|
||||
// --- DND ---
|
||||
logger.debug("Will Query a DND contact.");
|
||||
subtestQueryContactStatus(FullUserInfo.ICQSTATUS_DND,
|
||||
IcqStatusEnum.DO_NOT_DISTURB);
|
||||
|
||||
pauseBetweenStateChanges();
|
||||
|
||||
// --- FFC ---
|
||||
logger.debug("Will Query a Free For Chat contact.");
|
||||
subtestQueryContactStatus(FullUserInfo.ICQSTATUS_FFC,
|
||||
IcqStatusEnum.FREE_FOR_CHAT);
|
||||
|
||||
pauseBetweenStateChanges();
|
||||
|
||||
// --- INVISIBLE ---
|
||||
logger.debug("Will Query an Invisible contact.");
|
||||
subtestQueryContactStatus(FullUserInfo.ICQSTATUS_INVISIBLE,
|
||||
IcqStatusEnum.INVISIBLE);
|
||||
|
||||
pauseBetweenStateChanges();
|
||||
|
||||
// --- Occupied ---
|
||||
logger.debug("Will Query an Occupied contact.");
|
||||
subtestQueryContactStatus(FullUserInfo.ICQSTATUS_OCCUPIED,
|
||||
IcqStatusEnum.OCCUPIED);
|
||||
|
||||
pauseBetweenStateChanges();
|
||||
|
||||
// --- Online ---
|
||||
logger.debug("Will Query an Online contact.");
|
||||
subtestQueryContactStatus(IcqTesterAgent.ICQ_ONLINE_MASK,
|
||||
IcqStatusEnum.ONLINE);
|
||||
|
||||
pauseBetweenStateChanges();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by functions testing the queryContactStatus method of the
|
||||
* presence operation set.
|
||||
* @param taStatusLong the icq status as specified by FullUserInfo, that
|
||||
* the tester agent should switch to.
|
||||
* @param expectedReturn the PresenceStatus that the presence operation
|
||||
* set should see the tester agent in once it has switched to taStatusLong.
|
||||
*
|
||||
* @throws java.lang.Exception if querying the status causes some exception.
|
||||
*/
|
||||
public void subtestQueryContactStatus(long taStatusLong,
|
||||
PresenceStatus expectedReturn)
|
||||
throws Exception
|
||||
{
|
||||
if ( !fixture.testerAgent.enterStatus(taStatusLong) ){
|
||||
throw new RuntimeException(
|
||||
"Tester UserAgent Failed to switch to the "
|
||||
+ expectedReturn.getStatusName() + " state.");
|
||||
}
|
||||
|
||||
PresenceStatus actualReturn
|
||||
= operationSetPresence.queryContactStatus(
|
||||
fixture.testerAgent.getIcqUIN());
|
||||
assertEquals("Querying a "
|
||||
+ expectedReturn.getStatusName()
|
||||
+ " state did not return as expected"
|
||||
, expectedReturn, actualReturn);
|
||||
}
|
||||
|
||||
/**
|
||||
* The method would add a subscription for a contact, wait for a
|
||||
* subscription event confirming the subscription, then change the status
|
||||
* of the newly added contact (which is actually the IcqTesterAgent) and
|
||||
* make sure that the corresponding notification events have been generated.
|
||||
*
|
||||
* @throws java.lang.Exception if an exception occurs during testing.
|
||||
*/
|
||||
public void postTestSubscribe()
|
||||
throws Exception
|
||||
{
|
||||
logger.debug("Testing Subscription and Subscription Event Dispatch.");
|
||||
|
||||
// First create a subscription and verify that it really gets created.
|
||||
SubscriptionEventCollector subEvtCollector
|
||||
= new SubscriptionEventCollector();
|
||||
operationSetPresence.addSubsciptionListener(subEvtCollector);
|
||||
|
||||
synchronized(subEvtCollector){
|
||||
operationSetPresence.subscribe(fixture.testerAgent.getIcqUIN());
|
||||
subEvtCollector.waitForEvent(10000);
|
||||
//don't want any more events
|
||||
operationSetPresence.removeSubsciptionListener(subEvtCollector);
|
||||
}
|
||||
|
||||
assertEquals("Subscription event dispatching failed."
|
||||
, 1, subEvtCollector.collectedEvents.size());
|
||||
SubscriptionEvent subEvt =
|
||||
(SubscriptionEvent)subEvtCollector.collectedEvents.get(0);
|
||||
|
||||
assertEquals("SubscriptionEvent Source:",
|
||||
fixture.testerAgent.getIcqUIN(),
|
||||
((Contact)subEvt.getSource()).getAddress());
|
||||
assertEquals("SubscriptionEvent Source Contact:",
|
||||
fixture.testerAgent.getIcqUIN(),
|
||||
subEvt.getSourceContact().getAddress());
|
||||
assertSame("SubscriptionEvent Source Provider:",
|
||||
fixture.provider,
|
||||
subEvt.getSourceProvider());
|
||||
|
||||
subEvtCollector.collectedEvents.clear();
|
||||
|
||||
// make the user agent tester change its states and make sure we are
|
||||
// notified
|
||||
logger.debug("Testing presence notifications.");
|
||||
IcqStatusEnum testerAgentOldStatus
|
||||
= fixture.testerAgent.getPresneceStatus();
|
||||
IcqStatusEnum testerAgentNewStatus = IcqStatusEnum.FREE_FOR_CHAT;
|
||||
long testerAgentNewStatusLong = FullUserInfo.ICQSTATUS_FFC;
|
||||
|
||||
//in case we are by any chance already in a FREE_FOR_CHAT status, we'll
|
||||
//be changing to something else
|
||||
if(testerAgentOldStatus.equals(testerAgentNewStatus)){
|
||||
testerAgentNewStatus = IcqStatusEnum.DO_NOT_DISTURB;
|
||||
testerAgentNewStatusLong = FullUserInfo.ICQSTATUS_DND;
|
||||
}
|
||||
|
||||
//now do the actual status notification testing
|
||||
ContactPresenceEventCollector contactPresEvtCollector
|
||||
= new ContactPresenceEventCollector(
|
||||
fixture.testerAgent.getIcqUIN(), testerAgentNewStatus);
|
||||
operationSetPresence.addContactPresenceStatusListener(
|
||||
contactPresEvtCollector);
|
||||
|
||||
synchronized (contactPresEvtCollector){
|
||||
if (!fixture.testerAgent.enterStatus(testerAgentNewStatusLong))
|
||||
{
|
||||
throw new RuntimeException(
|
||||
"Tester UserAgent Failed to switch to the "
|
||||
+ testerAgentNewStatus.getStatusName() + " state.");
|
||||
}
|
||||
//we may already have the event, but it won't hurt to check.
|
||||
contactPresEvtCollector.waitForEvent(10000);
|
||||
operationSetPresence
|
||||
.removeContactPresenceStatusListener(contactPresEvtCollector);
|
||||
}
|
||||
|
||||
assertEquals("Presence Notif. event dispatching failed."
|
||||
, 1, contactPresEvtCollector.collectedEvents.size());
|
||||
ContactPresenceStatusChangeEvent presEvt =
|
||||
(ContactPresenceStatusChangeEvent)
|
||||
contactPresEvtCollector.collectedEvents.get(0);
|
||||
|
||||
assertEquals("Presence Notif. event Source:",
|
||||
fixture.testerAgent.getIcqUIN(),
|
||||
((Contact)presEvt.getSource()).getAddress());
|
||||
assertEquals("Presence Notif. event Source Contact:",
|
||||
fixture.testerAgent.getIcqUIN(),
|
||||
presEvt.getSourceContact().getAddress());
|
||||
assertSame("Presence Notif. event Source Provider:",
|
||||
fixture.provider,
|
||||
presEvt.getSourceProvider());
|
||||
|
||||
PresenceStatus reportedNewStatus = presEvt.getNewStatus();
|
||||
PresenceStatus reportedOldStatus = presEvt.getOldStatus();
|
||||
|
||||
assertEquals( "Reported new PresenceStatus: ",
|
||||
testerAgentNewStatus, reportedNewStatus );
|
||||
|
||||
//don't require equality between the reported old PresenceStatus and
|
||||
//the actual presence status of the tester agent because a first
|
||||
//notification is not supposed to have the old status as it really was.
|
||||
assertNotNull( "Reported old PresenceStatus: ", reportedOldStatus );
|
||||
|
||||
/** @todo tester agent changes status message we see the new message */
|
||||
/** @todo we should see the alias of the tester agent. */
|
||||
}
|
||||
|
||||
/**
|
||||
* We unsubscribe from presence notification deliveries concerning
|
||||
* IcqTesterAgent's presence status and verify that we receive the
|
||||
* subscription removed event. We then make the tester agent change status
|
||||
* and make sure that no notifications are delivered.
|
||||
*
|
||||
* @throws java.lang.Exception in case unsubscribing fails.
|
||||
*/
|
||||
public void postTestUnsubscribe()
|
||||
throws Exception
|
||||
{
|
||||
logger.debug("Testing Unsubscribe and unsubscription event dispatch.");
|
||||
|
||||
// First create a subscription and verify that it really gets created.
|
||||
SubscriptionEventCollector subEvtCollector
|
||||
= new SubscriptionEventCollector();
|
||||
operationSetPresence.addSubsciptionListener(subEvtCollector);
|
||||
|
||||
Contact icqTesterAgentContact = operationSetPresence
|
||||
.findContactByID(fixture.testerAgent.getIcqUIN());
|
||||
|
||||
assertNotNull(
|
||||
"Failed to find an existing subscription for the tester agent"
|
||||
, icqTesterAgentContact);
|
||||
|
||||
synchronized(subEvtCollector){
|
||||
operationSetPresence.unsubscribe(icqTesterAgentContact);
|
||||
subEvtCollector.waitForEvent(10000);
|
||||
//don't want any more events
|
||||
operationSetPresence.removeSubsciptionListener(subEvtCollector);
|
||||
}
|
||||
|
||||
assertEquals("Subscription event dispatching failed."
|
||||
, 1, subEvtCollector.collectedEvents.size());
|
||||
SubscriptionEvent subEvt =
|
||||
(SubscriptionEvent)subEvtCollector.collectedEvents.get(0);
|
||||
|
||||
assertEquals("SubscriptionEvent Source:",
|
||||
icqTesterAgentContact, subEvt.getSource());
|
||||
|
||||
assertEquals("SubscriptionEvent Source Contact:",
|
||||
icqTesterAgentContact, subEvt.getSourceContact());
|
||||
|
||||
assertSame("SubscriptionEvent Source Provider:",
|
||||
fixture.provider,
|
||||
subEvt.getSourceProvider());
|
||||
|
||||
subEvtCollector.collectedEvents.clear();
|
||||
|
||||
// make the user agent tester change its states and make sure we don't
|
||||
// get notifications as we're now unsubscribed.
|
||||
logger.debug("Testing (lack of) presence notifications.");
|
||||
IcqStatusEnum testerAgentOldStatus
|
||||
= fixture.testerAgent.getPresneceStatus();
|
||||
IcqStatusEnum testerAgentNewStatus = IcqStatusEnum.FREE_FOR_CHAT;
|
||||
long testerAgentNewStatusLong = FullUserInfo.ICQSTATUS_FFC;
|
||||
|
||||
//in case we are by any chance already in a FREE_FOR_CHAT status, we'll
|
||||
//be changing to something else
|
||||
if(testerAgentOldStatus.equals(testerAgentNewStatus)){
|
||||
testerAgentNewStatus = IcqStatusEnum.DO_NOT_DISTURB;
|
||||
testerAgentNewStatusLong = FullUserInfo.ICQSTATUS_DND;
|
||||
}
|
||||
|
||||
//now do the actual status notification testing
|
||||
ContactPresenceEventCollector contactPresEvtCollector
|
||||
= new ContactPresenceEventCollector(
|
||||
fixture.testerAgent.getIcqUIN(), null);
|
||||
operationSetPresence.addContactPresenceStatusListener(
|
||||
contactPresEvtCollector);
|
||||
|
||||
synchronized (contactPresEvtCollector){
|
||||
if (!fixture.testerAgent.enterStatus(testerAgentNewStatusLong))
|
||||
{
|
||||
throw new RuntimeException(
|
||||
"Tester UserAgent Failed to switch to the "
|
||||
+ testerAgentNewStatus.getStatusName() + " state.");
|
||||
}
|
||||
//we may already have the event, but it won't hurt to check.
|
||||
contactPresEvtCollector.waitForEvent(10000);
|
||||
operationSetPresence
|
||||
.removeContactPresenceStatusListener(contactPresEvtCollector);
|
||||
}
|
||||
|
||||
assertEquals("Presence Notifications were received after unsubscibing."
|
||||
, 0, contactPresEvtCollector.collectedEvents.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* An event collector that would collect all events generated by a
|
||||
* provider after a status change. The collector would also do a notidyAll
|
||||
* every time it receives an event.
|
||||
*/
|
||||
private class PresenceStatusEventCollector
|
||||
implements ProviderPresenceStatusListener
|
||||
{
|
||||
public ArrayList collectedPresEvents = new ArrayList();
|
||||
public ArrayList collectedStatMsgEvents = new ArrayList();
|
||||
|
||||
public void providerStatusChanged(ProviderPresenceStatusChangeEvent evt)
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
logger.debug("Collected evt("+collectedPresEvents.size()+")= "+evt);
|
||||
collectedPresEvents.add(evt);
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void providerStatusMessageChanged(PropertyChangeEvent evt)
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
logger.debug("Collected stat.msg. evt("
|
||||
+collectedPresEvents.size()+")= "+evt);
|
||||
collectedStatMsgEvents.add(evt);
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks until at least one event is received or until waitFor
|
||||
* miliseconds pass (whicever happens first).
|
||||
*
|
||||
* @param waitFor the number of miliseconds that we should be waiting
|
||||
* for an event before simply bailing out.
|
||||
*/
|
||||
public void waitForPresEvent(long waitFor)
|
||||
{
|
||||
logger.trace("Waiting for a change in provider status.");
|
||||
synchronized(this){
|
||||
if(collectedPresEvents.size() > 0){
|
||||
logger.trace("Change already received. " + collectedPresEvents);
|
||||
return;
|
||||
}
|
||||
|
||||
try{
|
||||
wait(waitFor);
|
||||
if(collectedPresEvents.size() > 0)
|
||||
logger.trace("Received a change in provider status.");
|
||||
else
|
||||
logger.trace("No change received for "+waitFor+"ms.");
|
||||
}
|
||||
catch (InterruptedException ex){
|
||||
logger.debug("Interrupted while waiting for a provider evt"
|
||||
, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks until at least one staus message event is received or until
|
||||
* waitFor miliseconds pass (whichever happens first).
|
||||
*
|
||||
* @param waitFor the number of miliseconds that we should be waiting
|
||||
* for a status message event before simply bailing out.
|
||||
*/
|
||||
public void waitForStatMsgEvent(long waitFor)
|
||||
{
|
||||
logger.trace("Waiting for a provider status message event.");
|
||||
synchronized(this){
|
||||
if(collectedStatMsgEvents.size() > 0){
|
||||
logger.trace("Stat msg. evt already received. "
|
||||
+ collectedStatMsgEvents);
|
||||
return;
|
||||
}
|
||||
|
||||
try{
|
||||
wait(waitFor);
|
||||
if(collectedStatMsgEvents.size() > 0)
|
||||
logger.trace("Received a prov. stat. msg. evt.");
|
||||
else
|
||||
logger.trace("No prov. stat msg. received for "
|
||||
+waitFor+"ms.");
|
||||
}
|
||||
catch (InterruptedException ex){
|
||||
logger.debug("Interrupted while waiting for a status msg evt"
|
||||
, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The class would listen for and store received subscription modification
|
||||
* events.
|
||||
*/
|
||||
private class SubscriptionEventCollector implements SubscriptionListener
|
||||
{
|
||||
public ArrayList collectedEvents = new ArrayList();
|
||||
|
||||
/**
|
||||
* Blocks until at least one event is received or until waitFor
|
||||
* miliseconds pass (whicever happens first).
|
||||
*
|
||||
* @param waitFor the number of miliseconds that we should be waiting
|
||||
* for an event before simply bailing out.
|
||||
*/
|
||||
public void waitForEvent(long waitFor)
|
||||
{
|
||||
synchronized(this){
|
||||
if(collectedEvents.size() > 0)
|
||||
return;
|
||||
|
||||
try{
|
||||
wait(waitFor);
|
||||
}
|
||||
catch (InterruptedException ex){
|
||||
logger.debug(
|
||||
"Interrupted while waiting for a subscription evt", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the received subsctiption and notifies all waiting on this
|
||||
* object
|
||||
* @param evt the SubscriptionEvent containing the corresponding contact
|
||||
*/
|
||||
public void subscriptionCreated(SubscriptionEvent evt)
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
|
||||
collectedEvents.add(evt);
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the received subsctiption and notifies all waiting on this
|
||||
* object
|
||||
* @param evt the SubscriptionEvent containing the corresponding contact
|
||||
*/
|
||||
public void subscriptionRemoved(SubscriptionEvent evt)
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
|
||||
collectedEvents.add(evt);
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the received subsctiption and notifies all waiting on this
|
||||
* object
|
||||
* @param evt the SubscriptionEvent containing the corresponding contact
|
||||
*/
|
||||
public void subscriptionFailed(SubscriptionEvent evt)
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
|
||||
collectedEvents.add(evt);
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The class would listen for and store received events caused by changes
|
||||
* in contact presence states.
|
||||
*/
|
||||
private class ContactPresenceEventCollector
|
||||
implements ContactPresenceStatusListener
|
||||
{
|
||||
public ArrayList collectedEvents = new ArrayList();
|
||||
private String trackedScreenName = null;
|
||||
private IcqStatusEnum status = null;
|
||||
|
||||
ContactPresenceEventCollector(String screenname,
|
||||
IcqStatusEnum wantedStatus)
|
||||
{
|
||||
this.trackedScreenName = screenname;
|
||||
this.status = wantedStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks until at least one event is received or until waitFor
|
||||
* miliseconds pass (whicever happens first).
|
||||
*
|
||||
* @param waitFor the number of miliseconds that we should be waiting
|
||||
* for an event before simply bailing out.
|
||||
*/
|
||||
public void waitForEvent(long waitFor)
|
||||
{
|
||||
synchronized(this){
|
||||
if(collectedEvents.size() > 0)
|
||||
return;
|
||||
|
||||
try{
|
||||
wait(waitFor);
|
||||
}
|
||||
catch (InterruptedException ex){
|
||||
logger.debug(
|
||||
"Interrupted while waiting for a subscription evt", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the received status change event and notifies all waiting on
|
||||
* this object
|
||||
* @param evt the SubscriptionEvent containing the corresponding contact
|
||||
*/
|
||||
public void contactPresenceStatusChanged(
|
||||
ContactPresenceStatusChangeEvent evt)
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
//if the user has specified event details and the received
|
||||
//event does not match - then ignore it.
|
||||
if( this.trackedScreenName != null
|
||||
&& !evt.getSourceContact().getAddress()
|
||||
.equals(trackedScreenName))
|
||||
return;
|
||||
if( status != null
|
||||
&& status != evt.getNewStatus())
|
||||
return;
|
||||
|
||||
logger.debug("Collected evt("+collectedEvents.size()+")= "+evt);
|
||||
collectedEvents.add(evt);
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,267 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.slick.protocol.icq;
|
||||
|
||||
import junit.framework.*;
|
||||
import net.java.sip.communicator.service.protocol.*;
|
||||
import java.util.*;
|
||||
import net.java.sip.communicator.service.protocol.event.*;
|
||||
import net.java.sip.communicator.util.*;
|
||||
import net.java.sip.communicator.service.protocol.icqconstants.*;
|
||||
|
||||
/**
|
||||
* Test icq/aim specific behaviour for OSCAR (AIM/ICQ) implementations of the
|
||||
* protocol provider service. The class would basically test that registration
|
||||
* succeeds, that the provider registration state is updated accordingly and
|
||||
* that the corrsponding registration change events are generated and dispatched.
|
||||
*
|
||||
* In the case of a registration failure we try to remain consistent and do
|
||||
* assertions accordingly.
|
||||
*
|
||||
* It is important to note that it is critical to execute tests in this class
|
||||
* in a particular order because of protocol limitations (we cannot login and
|
||||
* logoff to most of the existing protocol services as often as we'd like to).
|
||||
* This is why we have overridden the suite() method which kind of solves the
|
||||
* problem but adds the limitation of making extending developers manually add
|
||||
* the tests they write to the suite method.
|
||||
*
|
||||
* @author Emil Ivov
|
||||
*/
|
||||
public class TestProtocolProviderServiceIcqImpl extends TestCase
|
||||
{
|
||||
private static final Logger logger =
|
||||
Logger.getLogger(TestProtocolProviderServiceIcqImpl.class);
|
||||
|
||||
private IcqSlickFixture fixture = new IcqSlickFixture();
|
||||
|
||||
/**
|
||||
* The lock that we wait on until registration is finalized.
|
||||
*/
|
||||
private Object registrationLock = new Object();
|
||||
|
||||
/**
|
||||
* An event adapter that would collec registation state change events
|
||||
*/
|
||||
public RegistrationEventCollector regEvtCollector
|
||||
= new RegistrationEventCollector();
|
||||
|
||||
public TestProtocolProviderServiceIcqImpl(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
fixture.setUp();
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception
|
||||
{
|
||||
fixture.tearDown();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
// -------------------------- IMPORTANT ----------------------
|
||||
/**
|
||||
* Since we cannot afford to log on and off to the icq service as many
|
||||
* times as we want we're obliged to do our testing in a predfined order.
|
||||
* That's why we explicitely difine a suite with the order that suits us ;).
|
||||
* @return a TestSuite with the tests of this class ordered for execution
|
||||
* the way we want them to be.
|
||||
*/
|
||||
public static Test suite()
|
||||
{
|
||||
TestSuite suite = new TestSuite();
|
||||
suite.addTest(
|
||||
new TestProtocolProviderServiceIcqImpl("testRegister"));
|
||||
suite.addTest(
|
||||
new TestProtocolProviderServiceIcqImpl("testIsRegistered"));
|
||||
suite.addTest(
|
||||
new TestProtocolProviderServiceIcqImpl("testGetRegistrationState"));
|
||||
suite.addTest(
|
||||
new TestProtocolProviderServiceIcqImpl("testOperationSetTypes"));
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure that the instance of the ICQ protocol provider that we're
|
||||
* going to use for testing is properly initialized and signed on ICQ. This
|
||||
* method only makes sense if called before any other icq testing.
|
||||
*
|
||||
* The method also verifies that a registration event is fired upond
|
||||
* succesful registration and collected by our event collector.
|
||||
*/
|
||||
public void testRegister()
|
||||
{
|
||||
//add an event collector that will collect all events during the
|
||||
//registration and allows us to later inspect them and make sure
|
||||
//they were properly dispatched.
|
||||
fixture.provider.addRegistrationStateChangeListener(regEvtCollector);
|
||||
|
||||
fixture.provider.register(null);
|
||||
|
||||
//give it enough time to register. We won't really have to wait all this
|
||||
//time since the registration event collector would notify us the moment
|
||||
//we get signed on.
|
||||
try{
|
||||
synchronized(registrationLock){
|
||||
logger.debug("Waiting for registration to complete ...");
|
||||
registrationLock.wait(40000);
|
||||
logger.debug("Registration was completed or we lost patience.");
|
||||
}
|
||||
}
|
||||
catch (InterruptedException ex){
|
||||
logger.debug("Interrupted while waiting for registration", ex);
|
||||
}
|
||||
catch(Throwable t)
|
||||
{
|
||||
logger.debug("We got thrown out while waiting for registration", t);
|
||||
}
|
||||
|
||||
//give time for the AIM server to notify everyone of our arrival
|
||||
//simply waitinf is really not a reliable way of doing things but I
|
||||
//can't think of anything better
|
||||
Object lock = new Object();
|
||||
synchronized(lock)
|
||||
{
|
||||
try
|
||||
{
|
||||
logger.debug("Giving the aim server time to notify for our arrival!");
|
||||
lock.wait(5000);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{}
|
||||
}
|
||||
//make sure the provider is on-line
|
||||
assertTrue(
|
||||
"The tested ICQ implementation on-line status was OFFLINE",
|
||||
!IcqStatusEnum.OFFLINE.equals(
|
||||
fixture.testerAgent.getBuddyStatus(fixture.ourAccountID))
|
||||
);
|
||||
|
||||
//make sure that the registration process trigerred the corresponding
|
||||
//events.
|
||||
assertTrue(
|
||||
"No events were dispatched during the registration process."
|
||||
,regEvtCollector.collectedNewStates.size() > 0);
|
||||
|
||||
assertTrue(
|
||||
"No registration event notifying of registration was dispatched. "
|
||||
+"All events were: " + regEvtCollector.collectedNewStates
|
||||
,regEvtCollector.collectedNewStates
|
||||
.contains(RegistrationState.REGISTERED));
|
||||
|
||||
fixture.provider.removeRegistrationStateChangeListener(regEvtCollector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies whether the isRegistered method returns whatever it has to.
|
||||
*/
|
||||
public void testIsRegistered()
|
||||
{
|
||||
if (!IcqStatusEnum.OFFLINE.equals(
|
||||
fixture.testerAgent.getBuddyStatus(fixture.ourAccountID)))
|
||||
assertTrue(
|
||||
"provider.isRegistered() returned false while registered"
|
||||
,fixture.provider.isRegistered());
|
||||
else
|
||||
//in case registration failed - the provider needs to know that.:
|
||||
assertFalse(
|
||||
"provider.isRegistered() returned true while unregistered"
|
||||
,fixture.provider.isRegistered());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that getRegistrationState returns properly after registration
|
||||
* has completed (or failed)
|
||||
*/
|
||||
public void testGetRegistrationState()
|
||||
{
|
||||
if (!IcqStatusEnum.OFFLINE.equals(
|
||||
fixture.testerAgent.getBuddyStatus(fixture.ourAccountID)))
|
||||
assertEquals(
|
||||
"a provider was not in a REGISTERED state while registered."
|
||||
,RegistrationState.REGISTERED
|
||||
,fixture.provider.getRegistrationState());
|
||||
else
|
||||
assertFalse(
|
||||
"a provider had a REGISTERED reg state while unregistered."
|
||||
,fixture
|
||||
.provider.getRegistrationState()
|
||||
.equals(RegistrationState.REGISTERED));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that all operation sets have the type they are declarded to
|
||||
* have.
|
||||
*
|
||||
* @throws java.lang.Exception if a class indicated in one of the keys
|
||||
* could not be forName()ed.
|
||||
*/
|
||||
public void testOperationSetTypes() throws Exception
|
||||
{
|
||||
Map supportedOperationSets
|
||||
= fixture.provider.getSupportedOperationSets();
|
||||
|
||||
//make sure that keys (which are supposed to be class names) correspond
|
||||
//what the class of the values recorded against them.
|
||||
Iterator setNames = supportedOperationSets.keySet().iterator();
|
||||
while (setNames.hasNext())
|
||||
{
|
||||
String setName = (String) setNames.next();
|
||||
Object opSet = supportedOperationSets.get(setName);
|
||||
|
||||
assertTrue(opSet + " was not an instance of "
|
||||
+ setName + " as declared"
|
||||
, Class.forName(setName).isInstance(opSet));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A class that would plugin as a registration listener to a protocol
|
||||
* provider and simply record all events that it sees and notify the
|
||||
* registrationLock if it sees an event that notifies us of a completed
|
||||
* registration.
|
||||
* @author Emil Ivov
|
||||
*/
|
||||
public class RegistrationEventCollector implements RegistrationStateChangeListener
|
||||
{
|
||||
public List collectedNewStates = new LinkedList();
|
||||
|
||||
/**
|
||||
* The method would simply register all received events so that they
|
||||
* could be available for later inspection by the unit tests. In the
|
||||
* case where a registraiton event notifying us of a completed
|
||||
* registration is seen, the method would call notifyAll() on the
|
||||
* registrationLock.
|
||||
*
|
||||
* @param evt ProviderStatusChangeEvent the event describing the status
|
||||
* change.
|
||||
*/
|
||||
public void registrationStateChanged(RegistrationStateChangeEvent evt)
|
||||
{
|
||||
logger.debug("Received a RegistrationStateChangeEvent: " + evt);
|
||||
|
||||
collectedNewStates.add(evt.getNewState());
|
||||
|
||||
if(evt.getNewState().equals( RegistrationState.REGISTERED))
|
||||
{
|
||||
logger.debug("We're registered and will notify those who wait");
|
||||
synchronized(registrationLock){
|
||||
logger.debug(".");
|
||||
registrationLock.notifyAll();
|
||||
logger.debug(".");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
Bundle-Activator: net.java.sip.communicator.slick.protocol.icq.IcqProtocolProviderSlick
|
||||
Bundle-Name: ICQ Protocol Provider Service Leveraging Implementation Compatibility Kit
|
||||
Bundle-Description: A Service Leveraging Implementation Compatibility Kit for the ICQ implementation of the ProtocolProvider Service
|
||||
Bundle-Vendor: sip-communicator.org
|
||||
Bundle-Version: 0.0.1
|
||||
Import-Package: net.java.sip.communicator.service.configuration,
|
||||
net.java.sip.communicator.service.configuration.event,
|
||||
junit.framework,
|
||||
org.osgi.framework,
|
||||
net.java.sip.communicator.util,
|
||||
net.java.sip.communicator.service.protocol,
|
||||
net.java.sip.communicator.service.protocol.icqconstants,
|
||||
net.java.sip.communicator.service.protocol.event
|
||||
Loading…
Reference in new issue