mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2025-09-09 10:19:41 +02:00
Add support for "Caps Optimizations"
Smack's previous entity caps implementation assumed that an entity lost its entity caps feature as soon as a presence without caps from that entity was received. But according to XEP-0115 § 8.4, this is a perfectly normal optimization technique. We now reset the caps state after an available presence becomes unavailable. Also introduce PresenceEventListener, which is required for this feature. Also make Roster.preApprove() take a BareJid as argument. Fixes SMACK-723.
This commit is contained in:
parent
4248fbbb89
commit
d07ed60737
8 changed files with 280 additions and 22 deletions
|
@ -35,10 +35,10 @@ public abstract class AbstractSmackIntegrationTest extends AbstractSmackIntTest
|
|||
*/
|
||||
protected final XMPPConnection connection;
|
||||
|
||||
protected final long defaultTimeout;
|
||||
|
||||
protected final String testRunId;
|
||||
|
||||
protected final long defaultTimeout;
|
||||
|
||||
public AbstractSmackIntegrationTest(SmackIntegrationTestEnvironment environment) {
|
||||
this.connection = this.conOne = environment.conOne;
|
||||
this.conTwo = environment.conTwo;
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.roster;
|
||||
|
||||
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.igniterealtime.smack.inttest.AbstractSmackLowLevelIntegrationTest;
|
||||
import org.igniterealtime.smack.inttest.Configuration;
|
||||
import org.igniterealtime.smack.inttest.SmackIntegrationTest;
|
||||
import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
|
||||
import org.jxmpp.jid.FullJid;
|
||||
|
||||
public class LowLevelRosterIntegrationTest extends AbstractSmackLowLevelIntegrationTest {
|
||||
|
||||
public LowLevelRosterIntegrationTest(Configuration configuration, String testRunId) {
|
||||
super(configuration, testRunId);
|
||||
}
|
||||
|
||||
@SmackIntegrationTest
|
||||
public void testPresenceEventListenersOffline(final XMPPTCPConnection conOne, final XMPPTCPConnection conTwo) throws TimeoutException, Exception {
|
||||
RosterIntegrationTest.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo);
|
||||
|
||||
final Roster rosterOne = Roster.getInstanceFor(conOne);
|
||||
final Roster rosterTwo = Roster.getInstanceFor(conTwo);
|
||||
|
||||
// TODO create Roster.createEntry() with boolean flag for subscribe or not.
|
||||
rosterOne.createEntry(conTwo.getUser().asBareJid(), "Con Two", null);
|
||||
rosterTwo.createEntry(conOne.getUser().asBareJid(), "Con One", null);
|
||||
|
||||
// TODO Change timeout form '5000' to something configurable.
|
||||
final long timeout = 5000;
|
||||
RosterIntegrationTest.ensureBothAccountsAreSubscribedToEachOther(conOne, conTwo, timeout);
|
||||
|
||||
final SimpleResultSyncPoint offlineTriggered = new SimpleResultSyncPoint();
|
||||
|
||||
rosterOne.addPresenceEventListener(new AbstractPresenceEventListener() {
|
||||
@Override
|
||||
public void presenceUnavailable(FullJid jid, Presence presence) {
|
||||
if (!jid.equals(conTwo.getUser())) {
|
||||
return;
|
||||
}
|
||||
offlineTriggered.signal();
|
||||
}
|
||||
});
|
||||
|
||||
// Disconnect conTwo, this should cause an 'unavilable' presence to be send from conTwo to
|
||||
// conOne.
|
||||
conTwo.disconnect();
|
||||
|
||||
Boolean result = offlineTriggered.waitForResult(timeout);
|
||||
if (!result) {
|
||||
throw new Exception("presenceUnavailable() was not called");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2015 Florian Schmaus
|
||||
* Copyright 2015-2016 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -32,6 +32,7 @@ import org.jivesoftware.smack.XMPPConnection;
|
|||
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.roster.packet.RosterPacket.ItemType;
|
||||
import org.jxmpp.jid.BareJid;
|
||||
import org.jxmpp.jid.Jid;
|
||||
|
||||
public class RosterIntegrationTest extends AbstractSmackIntegrationTest {
|
||||
|
@ -47,7 +48,7 @@ public class RosterIntegrationTest extends AbstractSmackIntegrationTest {
|
|||
|
||||
@SmackIntegrationTest
|
||||
public void subscribeRequestListenerTest() throws TimeoutException, Exception {
|
||||
ensureBothAccountsAreNotInEachOthersRoster();
|
||||
ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo);
|
||||
|
||||
rosterTwo.setSubscribeListener(new SubscribeListener() {
|
||||
@Override
|
||||
|
@ -92,14 +93,14 @@ public class RosterIntegrationTest extends AbstractSmackIntegrationTest {
|
|||
assertTrue(addedAndSubscribed.waitForResult(2 * connection.getPacketReplyTimeout()));
|
||||
}
|
||||
|
||||
private void ensureBothAccountsAreNotInEachOthersRoster() throws NotLoggedInException,
|
||||
public static void ensureBothAccountsAreNotInEachOthersRoster(XMPPConnection conOne, XMPPConnection conTwo) throws NotLoggedInException,
|
||||
NoResponseException, XMPPErrorException, NotConnectedException,
|
||||
InterruptedException {
|
||||
notInRoster(conOne, conTwo);
|
||||
notInRoster(conTwo, conOne);
|
||||
}
|
||||
|
||||
private void notInRoster(XMPPConnection c1, XMPPConnection c2) throws NotLoggedInException,
|
||||
private static void notInRoster(XMPPConnection c1, XMPPConnection c2) throws NotLoggedInException,
|
||||
NoResponseException, XMPPErrorException, NotConnectedException,
|
||||
InterruptedException {
|
||||
Roster roster = Roster.getInstanceFor(c1);
|
||||
|
@ -109,4 +110,46 @@ public class RosterIntegrationTest extends AbstractSmackIntegrationTest {
|
|||
}
|
||||
roster.removeEntry(c2Entry);
|
||||
}
|
||||
|
||||
public static void ensureBothAccountsAreSubscribedToEachOther(XMPPConnection conOne, XMPPConnection conTwo, long timeout) throws TimeoutException, Exception {
|
||||
ensureSubscribedTo(conOne, conTwo, timeout);
|
||||
ensureSubscribedTo(conTwo, conOne, timeout);
|
||||
}
|
||||
|
||||
private static void ensureSubscribedTo(final XMPPConnection conOne, final XMPPConnection conTwo, long timeout) throws TimeoutException, Exception {
|
||||
Roster rosterOne = Roster.getInstanceFor(conOne);
|
||||
Roster rosterTwo = Roster.getInstanceFor(conTwo);
|
||||
|
||||
if (rosterOne.isSubscribedToMyPresence(conTwo.getUser())) {
|
||||
return;
|
||||
}
|
||||
|
||||
rosterOne.setSubscribeListener(new SubscribeListener() {
|
||||
@Override
|
||||
public SubscribeAnswer processSubscribe(Jid from, Presence subscribeRequest) {
|
||||
if (from.equals(conTwo.getUser().asBareJid())) {
|
||||
return SubscribeAnswer.Approve;
|
||||
}
|
||||
return SubscribeAnswer.Deny;
|
||||
}
|
||||
});
|
||||
|
||||
final SimpleResultSyncPoint syncPoint = new SimpleResultSyncPoint();
|
||||
rosterTwo.addPresenceEventListener(new AbstractPresenceEventListener() {
|
||||
@Override
|
||||
public void presenceSubscribed(BareJid address, Presence subscribedPresence) {
|
||||
if (!address.equals(conOne.getUser().asBareJid())) {
|
||||
return;
|
||||
}
|
||||
syncPoint.signal();
|
||||
}
|
||||
});
|
||||
rosterTwo.sendSubscriptionRequest(conOne.getUser().asBareJid());
|
||||
|
||||
try {
|
||||
syncPoint.waitForResult(timeout);
|
||||
} finally {
|
||||
rosterOne.setSubscribeListener(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue