You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by be...@apache.org on 2008/08/10 21:57:19 UTC

svn commit: r684582 - in /labs/vysper/src: main/java/org/apache/vysper/xmpp/delivery/ main/java/org/apache/vysper/xmpp/modules/core/im/handler/ main/java/org/apache/vysper/xmpp/modules/roster/handler/ main/java/org/apache/vysper/xmpp/resourcebinding/ t...

Author: berndf
Date: Sun Aug 10 12:57:19 2008
New Revision: 684582

URL: http://svn.apache.org/viewvc?rev=684582&view=rev
Log:
[vysper] improve initial and updated presence handling and testing, plus provide ability to distinguish intial presence before vs after roster request in ResourceState

Modified:
    labs/vysper/src/main/java/org/apache/vysper/xmpp/delivery/StanzaReceiverRelay.java
    labs/vysper/src/main/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceAvailabilityHandler.java
    labs/vysper/src/main/java/org/apache/vysper/xmpp/modules/roster/handler/RosterIQHandler.java
    labs/vysper/src/main/java/org/apache/vysper/xmpp/resourcebinding/ResourceRegistry.java
    labs/vysper/src/main/java/org/apache/vysper/xmpp/resourcebinding/ResourceState.java
    labs/vysper/src/test/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceHandlerTestCase.java
    labs/vysper/src/test/java/org/apache/vysper/xmpp/modules/roster/handler/RosterIQHandlerTestCase.java

Modified: labs/vysper/src/main/java/org/apache/vysper/xmpp/delivery/StanzaReceiverRelay.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/main/java/org/apache/vysper/xmpp/delivery/StanzaReceiverRelay.java?rev=684582&r1=684581&r2=684582&view=diff
==============================================================================
--- labs/vysper/src/main/java/org/apache/vysper/xmpp/delivery/StanzaReceiverRelay.java (original)
+++ labs/vysper/src/main/java/org/apache/vysper/xmpp/delivery/StanzaReceiverRelay.java Sun Aug 10 12:57:19 2008
@@ -30,7 +30,7 @@
  */
 public class StanzaReceiverRelay implements StanzaRelay {
 
-    private Map<Entity, StanzaReceiver> receiverMap = new HashMap<Entity, StanzaReceiver>();
+    private final Map<Entity, StanzaReceiver> receiverMap = new HashMap<Entity, StanzaReceiver>();
     private boolean exploitFailureStrategy = true;
     private ServerRuntimeContext serverRuntimeContext = null;
     private int countRelayed = 0;
@@ -74,4 +74,19 @@
     public int getCountDelivered() {
         return countDelivered;
     }
+    
+    public void resetAll() {
+        synchronized (receiverMap) {
+            for (StanzaReceiver receiver : receiverMap.values()) {
+                if (receiver instanceof StanzaReceiverQueue) {
+                    StanzaReceiverQueue stanzaReceiverQueue = (StanzaReceiverQueue) receiver;
+                    while (stanzaReceiverQueue.getNext() != null) {
+                        // continue
+                    }
+                }
+
+            }
+        }
+        countDelivered = 0;
+    }
 }

Modified: labs/vysper/src/main/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceAvailabilityHandler.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/main/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceAvailabilityHandler.java?rev=684582&r1=684581&r2=684582&view=diff
==============================================================================
--- labs/vysper/src/main/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceAvailabilityHandler.java (original)
+++ labs/vysper/src/main/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceAvailabilityHandler.java Sun Aug 10 12:57:19 2008
@@ -74,7 +74,7 @@
             if (!hasTo && available) {
                 ResourceState resourceState = registry.getResourceState(registry.getFirstResourceForSession(sessionContext));
 
-                boolean isPresenceUpdate = resourceState != null && resourceState == ResourceState.AVAILABLE;
+                boolean isPresenceUpdate = resourceState != null && ResourceState.isAvaliableOrInterested(resourceState);
             
                 // TODO in case of !isPresenceUpdate, should we check for resourceState != ResourceState.INTERESTED ? 
                 // RFC3921bis-04#4.2.2 Initial Presence
@@ -155,7 +155,7 @@
             
             // set resource state
             ResourceState currentState = registry.getResourceState(user.getResource());
-            if (currentState != null && currentState != ResourceState.INTERESTED) {
+            if (currentState != null && !ResourceState.isInterested(currentState)) {
                 // set to AVAILABLE, but do not override INTERESTED
                 registry.setResourceState(user.getResource(), ResourceState.AVAILABLE);
             }
@@ -171,8 +171,10 @@
 
         // broadcast presence from full JID to contacts
         // in roster with 'subscription' either 'from' or 'both'
-        // and user is not blocking outbound presence notifications
-        // above
+        // TODO: ...and user is not blocking outbound presence notifications above
+        // TODO (for pres updates): ...and last presence stanza received from the contact during the user's 
+        // presence session was not of type "error" or "unsubscribe". 
+        
         List<RosterItem> rosterContacts_FROM = new ArrayList<RosterItem>();
         rosterContacts_FROM.addAll(item_FROM);
         rosterContacts_FROM.addAll(item_BOTH);
@@ -182,25 +184,28 @@
         
         // broadcast presence notification to all resources of
         // current entity.
-        List<String> resources = registry.getAvailableResources(user);
+        List<String> resources = registry.getInterestedOrAvailableResources(user);
         for (String resource : resources) {
             Entity otherResource = new EntityImpl(user, resource);
             contacts.add(otherResource);
         }
 
-        // send them out
+        // and send them out
         relayTo(user, contacts, stanza, sessionContext);
-        
-        // send probes to all contacts of the current jid where
-        // 'subscription' is either 'to' or 'both'
-        // TODO and jid is not blocking inbound presence notification
-        List<RosterItem> rosterContacts_TO = new ArrayList<RosterItem>();
-        rosterContacts_TO.addAll(item_TO);
-        rosterContacts_TO.addAll(item_BOTH);
-        for (RosterItem rosterItem : rosterContacts_TO) {
-            Entity contact_TO = rosterItem.getJid();
-            Stanza probeStanza = buildPresenceStanza(user, contact_TO, PresenceStanzaType.PROBE, null);
-            relayStanza(contact_TO, probeStanza, sessionContext);
+
+        if (!presenceUpdate) {
+            // initial presence only:
+            // send probes to all contacts of the current jid where
+            // 'subscription' is either 'to' or 'both'
+            // TODO: ...and jid is not blocking inbound presence notification
+            List<RosterItem> rosterContacts_TO = new ArrayList<RosterItem>();
+            rosterContacts_TO.addAll(item_TO);
+            rosterContacts_TO.addAll(item_BOTH);
+            for (RosterItem rosterItem : rosterContacts_TO) {
+                Entity contact_TO = rosterItem.getJid();
+                Stanza probeStanza = buildPresenceStanza(user, contact_TO, PresenceStanzaType.PROBE, null);
+                relayStanza(contact_TO, probeStanza, sessionContext);
+            }
         }
     }
 

Modified: labs/vysper/src/main/java/org/apache/vysper/xmpp/modules/roster/handler/RosterIQHandler.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/main/java/org/apache/vysper/xmpp/modules/roster/handler/RosterIQHandler.java?rev=684582&r1=684581&r2=684582&view=diff
==============================================================================
--- labs/vysper/src/main/java/org/apache/vysper/xmpp/modules/roster/handler/RosterIQHandler.java (original)
+++ labs/vysper/src/main/java/org/apache/vysper/xmpp/modules/roster/handler/RosterIQHandler.java Sun Aug 10 12:57:19 2008
@@ -79,8 +79,12 @@
         
         String resourceId = registry.getFirstResourceForSession(sessionContext);
         ResourceState currentState = registry.getResourceState(resourceId);
-        if (currentState != null && currentState == ResourceState.CONNECTED) {
-            registry.setResourceState(resourceId, ResourceState.INTERESTED);
+        if (currentState != null) {
+            if (currentState == ResourceState.CONNECTED) {
+                registry.setResourceState(resourceId, ResourceState.INTERESTED_NOT_YET_AVAILABLE);
+            } else if (currentState == ResourceState.AVAILABLE) {
+                registry.setResourceState(resourceId, ResourceState.INTERESTED);
+            } 
         }
 
         Entity from = stanza.getFrom();

Modified: labs/vysper/src/main/java/org/apache/vysper/xmpp/resourcebinding/ResourceRegistry.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/main/java/org/apache/vysper/xmpp/resourcebinding/ResourceRegistry.java?rev=684582&r1=684581&r2=684582&view=diff
==============================================================================
--- labs/vysper/src/main/java/org/apache/vysper/xmpp/resourcebinding/ResourceRegistry.java (original)
+++ labs/vysper/src/main/java/org/apache/vysper/xmpp/resourcebinding/ResourceRegistry.java Sun Aug 10 12:57:19 2008
@@ -21,6 +21,7 @@
 import org.apache.vysper.xmpp.uuid.UUIDGenerator;
 import org.apache.vysper.xmpp.addressing.Entity;
 import org.apache.vysper.xmpp.addressing.EntityImpl;
+import static org.apache.vysper.xmpp.resourcebinding.ResourceState.*;
 
 import java.util.List;
 import java.util.ArrayList;
@@ -71,7 +72,7 @@
 			synchronized (entityResources) {
                 synchronized (sessionResources) {
                     boundResources.put(resourceId, new SessionData(sessionContext,
-                            ResourceState.CONNECTED, 0));
+                            CONNECTED, 0));
     
                     Entity initiatingEntity = sessionContext.getInitiatingEntity();
                     List<String> resourceForEntityList = getResourceList(initiatingEntity);
@@ -265,7 +266,7 @@
 	 * @return true if the resource is connected, false otherwise
 	 */
 	public boolean isResourceConnected(String resourceId) {
-		return ResourceState.CONNECTED.equals(getResourceState(resourceId));
+		return CONNECTED.equals(getResourceState(resourceId));
 	}
 
     /**
@@ -276,7 +277,7 @@
 	 * @return true if the resource is available, false otherwise.
 	 */
 	public boolean isResourceAvailable(String resourceId) {
-		return ResourceState.AVAILABLE.equals(getResourceState(resourceId));
+		return AVAILABLE.equals(getResourceState(resourceId));
 	}
 
 	/**
@@ -287,20 +288,20 @@
 	 * @return true if the resource is interested, false otherwise
 	 */
 	public boolean isResourceInterested(String resourceId) {
-		return ResourceState.INTERESTED.equals(getResourceState(resourceId));
+		return isInterested(getResourceState(resourceId));
 	}
 
 	public List<String> getInterestedResources(Entity entity) {
-		return filterResources(entity, ResourceState.INTERESTED);
+		return filterResources(entity, INTERESTED);
 	}
 
 	public List<String> getAvailableResources(Entity entity) {
-		return filterResources(entity, ResourceState.AVAILABLE);
+		return filterResources(entity, AVAILABLE);
 	}
 
 	public List<String> getInterestedOrAvailableResources(Entity entity) {
-        List<String> resources = filterResources(entity, ResourceState.INTERESTED);
-        resources.addAll(filterResources(entity, ResourceState.AVAILABLE));
+        List<String> resources = filterResources(entity, INTERESTED);
+        resources.addAll(filterResources(entity, AVAILABLE));
         return resources;
 	}
 
@@ -313,10 +314,13 @@
 		List<String> resources = getResourceList(entity);
 		List<String> result = new ArrayList<String>();
 		for (String resource : resources) {
-			if (state.equals(getResourceState(resource))) {
-				result.add(resource);
-			}
-		}
+            if (state == INTERESTED) {
+                if (ResourceState.isInterested(getResourceState(resource))) result.add(resource);
+            }
+            else if (state.equals(getResourceState(resource))) {
+                result.add(resource);
+            }
+        }
 		return result;
 	}
 }

Modified: labs/vysper/src/main/java/org/apache/vysper/xmpp/resourcebinding/ResourceState.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/main/java/org/apache/vysper/xmpp/resourcebinding/ResourceState.java?rev=684582&r1=684581&r2=684582&view=diff
==============================================================================
--- labs/vysper/src/main/java/org/apache/vysper/xmpp/resourcebinding/ResourceState.java (original)
+++ labs/vysper/src/main/java/org/apache/vysper/xmpp/resourcebinding/ResourceState.java Sun Aug 10 12:57:19 2008
@@ -14,6 +14,11 @@
 	 */
 	CONNECTED,
     /**
+     * A conntected resource has requested the
+     * entity's roster without sending initial presence first
+     */
+    INTERESTED_NOT_YET_AVAILABLE,
+    /**
     * A connected resource is considered "available" after successfully sending
       * its initial presence.
       */
@@ -26,5 +31,13 @@
     /**
       * A resource is no longer "available" 
       */
-    UNAVAILABLE
+    UNAVAILABLE;
+
+    public static boolean isInterested(ResourceState resourceState) {
+        return resourceState == INTERESTED_NOT_YET_AVAILABLE || resourceState == INTERESTED;
+    }
+    
+    public static boolean isAvaliableOrInterested(ResourceState resourceState) {
+        return resourceState == AVAILABLE || isInterested(resourceState);
+    }
 }

Modified: labs/vysper/src/test/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceHandlerTestCase.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/test/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceHandlerTestCase.java?rev=684582&r1=684581&r2=684582&view=diff
==============================================================================
--- labs/vysper/src/test/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceHandlerTestCase.java (original)
+++ labs/vysper/src/test/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceHandlerTestCase.java Sun Aug 10 12:57:19 2008
@@ -33,6 +33,7 @@
 import org.apache.vysper.xmpp.stanza.XMPPCoreStanza;
 import org.apache.vysper.xmpp.stanza.PresenceStanzaType;
 import org.apache.vysper.xmpp.xmlfragment.XMLElementVerifier;
+import org.apache.vysper.xmpp.xmlfragment.XMLSemanticError;
 
 /**
  */
@@ -66,12 +67,13 @@
         sessionContext.setInitiatingEntity(client);
         boundResourceId = sessionContext.bindResource();
         initiatorsQueue = sessionContext.addReceiver(client, boundResourceId);
-        setResourceState(boundResourceId, ResourceState.INTERESTED);
+        setResourceState(boundResourceId, ResourceState.CONNECTED);
         clientFullQualified = new EntityImpl(client, boundResourceId);
 
         // set up more resources for the same session
         anotherInterestedResourceId = sessionContext.bindResource();
         anotherInterestedResourceQueue = sessionContext.addReceiver(client, anotherInterestedResourceId);
+        setResourceState(anotherInterestedResourceId, ResourceState.INTERESTED);
         anotherAvailableResourceId = sessionContext.bindResource();
         anotherAvailableResourceQueue = sessionContext.addReceiver(client, anotherAvailableResourceId);
         setResourceState(anotherAvailableResourceId, ResourceState.AVAILABLE);
@@ -104,12 +106,17 @@
     public void testInitialPresence() throws BindException, EntityFormatException {
         XMPPCoreStanza initialPresence = XMPPCoreStanza.getWrapper(StanzaBuilder.createPresenceStanza(null, null, null, null, null, null).getFinalStanza());
 
-        assertEquals(ResourceState.INTERESTED, getResourceState());
+        assertEquals(ResourceState.CONNECTED, getResourceState());
         handler.executeCore(initialPresence, sessionContext);
         // check resource state change, do not override interested
-        assertEquals(ResourceState.INTERESTED, getResourceState());
+        assertEquals(ResourceState.AVAILABLE, getResourceState());
 
-        assertEquals(6, ((StanzaReceiverRelay) sessionContext.getServerRuntimeContext().getStanzaRelay()).getCountDelivered());
+        // 3 intial presence broadcasts to same session + 2 presence to subscribers + 2 probes to subscriptions
+        assertEquals(3+2+2, ((StanzaReceiverRelay) sessionContext.getServerRuntimeContext().getStanzaRelay()).getCountDelivered());
+        
+        //
+        // check presence broadcasts to resources of same session (self, interested & available)
+        //
         
         Stanza initiatorNotification = initiatorsQueue.getNext();
         assertNotNull(initiatorNotification);
@@ -122,8 +129,19 @@
         assertTrue(checkPresence(availableResourceNotification, null));
         assertTrue(availableResourceNotification.getVerifier().fromAttributeEquals(clientFullQualified.getFullQualifiedName()));
         assertTrue(availableResourceNotification.getVerifier().toAttributeEquals(client.getFullQualifiedName() + "/" + anotherAvailableResourceId));
+        assertNull(anotherAvailableResourceQueue.getNext()); // no more stanzas
+        
+        Stanza interestedResourceNotification = anotherInterestedResourceQueue.getNext();
+        assertNotNull(interestedResourceNotification);
+        assertTrue(checkPresence(interestedResourceNotification, null));
+        assertTrue(interestedResourceNotification.getVerifier().fromAttributeEquals(clientFullQualified.getFullQualifiedName()));
+        assertTrue(interestedResourceNotification.getVerifier().toAttributeEquals(client.getFullQualifiedName() + "/" + anotherInterestedResourceId));
+        assertNull(anotherInterestedResourceQueue.getNext()); // no more stanzas
+        
+        //
+        // check other presences
+        //        
         
-        assertNull(anotherInterestedResourceQueue.getNext()); // does not sent pres to un-available
         assertNull(unrelatedQueue.getNext()); // does not sent pres to everybody arbitrarily
         assertTrue(checkPresence(subscribed_FROM_Queue.getNext(), null)); // pres sent to FROM contacts
         assertNull(subscribed_FROM_Queue.getNext()); // no second stanza sent to FROMs 
@@ -137,21 +155,88 @@
         assertNull(subscribed_TO_Queue.getNext()); // pres NOT sent to TO contacts
     }
 
+    public void testUpdatedPresence() throws BindException, EntityFormatException {
+        StanzaReceiverRelay receiverRelay = (StanzaReceiverRelay) sessionContext.getServerRuntimeContext().getStanzaRelay();
+
+        // at first, initial presence
+        XMPPCoreStanza initialPresence = XMPPCoreStanza.getWrapper(StanzaBuilder.createPresenceStanza(null, null, null, null, null, null).getFinalStanza());
+        handler.executeCore(initialPresence, sessionContext);
+        assertTrue(0 < receiverRelay.getCountDelivered());
+        receiverRelay.resetAll(); // purge recorded 
+        assertTrue(0 == receiverRelay.getCountDelivered());
+        
+        // send update now
+        final String showValue = "chatty";
+        
+        XMPPCoreStanza updatePresence = XMPPCoreStanza.getWrapper(StanzaBuilder.createPresenceStanza(clientFullQualified, null, null, null, showValue, null).getFinalStanza());
+        handler.executeCore(updatePresence, sessionContext);
+        // check resource state 
+        assertEquals(ResourceState.AVAILABLE, getResourceState());
+
+        // 3 presence update broadcasts to same session + 2 presence to subscribers
+        assertEquals(3+2, ((StanzaReceiverRelay) sessionContext.getServerRuntimeContext().getStanzaRelay()).getCountDelivered());
+        
+        //
+        // check presence broadcasts to resources of same session (self, interested & available)
+        //
+        
+        Stanza initiatorNotification = initiatorsQueue.getNext();
+        assertNotNull(initiatorNotification);
+        assertTrue(checkPresence(initiatorNotification, null, showValue));
+        assertTrue(initiatorNotification.getVerifier().fromAttributeEquals(clientFullQualified.getFullQualifiedName()));
+        assertTrue(initiatorNotification.getVerifier().toAttributeEquals(clientFullQualified.getFullQualifiedName()));
+        
+        Stanza availableResourceNotification = anotherAvailableResourceQueue.getNext();
+        assertNotNull(availableResourceNotification);
+        assertTrue(checkPresence(availableResourceNotification, null, showValue));
+        assertTrue(availableResourceNotification.getVerifier().fromAttributeEquals(clientFullQualified.getFullQualifiedName()));
+        assertTrue(availableResourceNotification.getVerifier().toAttributeEquals(client.getFullQualifiedName() + "/" + anotherAvailableResourceId));
+        assertNull(anotherAvailableResourceQueue.getNext()); // no more stanzas
+        
+        Stanza interestedResourceNotification = anotherInterestedResourceQueue.getNext();
+        assertNotNull(interestedResourceNotification);
+        assertTrue(checkPresence(interestedResourceNotification, null, showValue));
+        assertTrue(interestedResourceNotification.getVerifier().fromAttributeEquals(clientFullQualified.getFullQualifiedName()));
+        assertTrue(interestedResourceNotification.getVerifier().toAttributeEquals(client.getFullQualifiedName() + "/" + anotherInterestedResourceId));
+        assertNull(anotherInterestedResourceQueue.getNext()); // no more stanzas
+        
+        //
+        // check other presences
+        //        
+        
+        assertNull(unrelatedQueue.getNext()); // does not sent pres to everybody arbitrarily
+        assertTrue(checkPresence(subscribed_FROM_Queue.getNext(), null, showValue)); // pres sent to FROM contacts
+        assertNull(subscribed_FROM_Queue.getNext()); // no second stanza sent to FROMs 
+
+        // initial pres and pres probe might come in different order
+        assertTrue(checkPresence(subscribed_BOTH_Queue.getNext(), null, showValue)); // pres sent to BOTH contacts
+        assertNull(subscribed_BOTH_Queue.getNext()); // no second stanza (especially probe) sent to BOTHs
+
+        assertNull(subscribed_TO_Queue.getNext()); // pres (especially probe)  NOT sent to TO contacts
+    }
+
     private boolean checkPresence(Stanza stanza, PresenceStanzaType presenceType) {
+        return checkPresence(stanza, presenceType, null);
+    }
+    
+    private boolean checkPresence(Stanza stanza, PresenceStanzaType presenceType, String show) {
         XMLElementVerifier xmlElementVerifier = stanza.getVerifier();
         if (!xmlElementVerifier.nameEquals("presence")) return false;
         if (presenceType == null && xmlElementVerifier.attributePresent("type")) return false;
         if (presenceType != null && !xmlElementVerifier.attributeEquals("type", presenceType.value())) return false;
+        try {
+            if (show != null && !xmlElementVerifier.subElementPresent("show")
+                    && !stanza.getSingleInnerElementsNamed("show").getSingleInnerText().getText().equals(show)) {
+                return false;
+            }
+        } catch (XMLSemanticError xmlSemanticError) {
+            return false;
+        }
         return true;
     }
 
     private ResourceState getResourceState() {
         return sessionContext.getServerRuntimeContext().getResourceRegistry().getResourceState(boundResourceId);
     }
-
-    public void testForwardedPresenceStanzaHasInnerElements() {
-        XMPPCoreStanza presence = XMPPCoreStanza.getWrapper(StanzaBuilder.createPresenceStanza(null, null, null, null, null, null).getFinalStanza());
-        fail("test incomplete");
-    }
     
 }

Modified: labs/vysper/src/test/java/org/apache/vysper/xmpp/modules/roster/handler/RosterIQHandlerTestCase.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/test/java/org/apache/vysper/xmpp/modules/roster/handler/RosterIQHandlerTestCase.java?rev=684582&r1=684581&r2=684582&view=diff
==============================================================================
--- labs/vysper/src/test/java/org/apache/vysper/xmpp/modules/roster/handler/RosterIQHandlerTestCase.java (original)
+++ labs/vysper/src/test/java/org/apache/vysper/xmpp/modules/roster/handler/RosterIQHandlerTestCase.java Sun Aug 10 12:57:19 2008
@@ -27,19 +27,19 @@
         client = EntityImpl.parse("tester@vysper.org");
         sessionContext.setInitiatingEntity(client);
         boundResourceId = sessionContext.bindResource();
-        sessionContext.getServerRuntimeContext().getResourceRegistry().setResourceState(boundResourceId, ResourceState.INTERESTED);
+        sessionContext.getServerRuntimeContext().getResourceRegistry().setResourceState(boundResourceId, ResourceState.CONNECTED);
         rosterManager = new MemoryRosterManager();
         sessionContext.getServerRuntimeContext().registerServerRuntimeContextService(rosterManager);
         handler = new RosterIQHandler();
     }
 
     public void testRosterGet() {
-        
-        StanzaBuilder stanzaBuilder = StanzaBuilder.createIQStanza(null, null, IQStanzaType.GET, "id1");
-        stanzaBuilder.addAttribute("from", client.getFullQualifiedName());
-        stanzaBuilder.startInnerElement("query").addNamespaceAttribute(NamespaceURIs.JABBER_IQ_ROSTER).endInnerElement();
 
+        StanzaBuilder stanzaBuilder = createRosterGet();
+
+        assertEquals(ResourceState.CONNECTED, getResourceState());
         handler.execute(stanzaBuilder.getFinalStanza(), sessionContext, null);
+        assertEquals(ResourceState.INTERESTED_NOT_YET_AVAILABLE, getResourceState());
         
 //        C: <iq from='juliet@example.com/balcony'
 //               type='get'
@@ -49,5 +49,27 @@
         
     }
 
+    public void testRosterState_WithRosterGetAfterInitialPresence() {
+
+        StanzaBuilder stanzaBuilder = createRosterGet();
+
+        // mock intial presence resource state change
+        sessionContext.getServerRuntimeContext().getResourceRegistry().setResourceState(boundResourceId, ResourceState.AVAILABLE);
+        
+        handler.execute(stanzaBuilder.getFinalStanza(), sessionContext, null);
+        assertEquals(ResourceState.INTERESTED, getResourceState());
+    }
+
+    private StanzaBuilder createRosterGet() {
+        StanzaBuilder stanzaBuilder = StanzaBuilder.createIQStanza(null, null, IQStanzaType.GET, "id1");
+        stanzaBuilder.addAttribute("from", client.getFullQualifiedName());
+        stanzaBuilder.startInnerElement("query").addNamespaceAttribute(NamespaceURIs.JABBER_IQ_ROSTER).endInnerElement();
+        return stanzaBuilder;
+    }
+
+
+    private ResourceState getResourceState() {
+        return sessionContext.getServerRuntimeContext().getResourceRegistry().getResourceState(boundResourceId);
+    }
     
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org