From 5240f5cca0de5a688d2bc0ce0d5bd834fcd38979 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Wed, 30 Jun 2021 21:02:17 +0200 Subject: [PATCH 1/4] [sint] new presence subscription tests This adds a few basic tests that verify that presence subscription stanzas are received 'as intended', notably when they include extension elements. --- .../SubscriptionIntegrationTest.java | 196 ++++++++++++++++++ .../smack/subscription/package-info.java | 20 ++ 2 files changed, 216 insertions(+) create mode 100644 smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/SubscriptionIntegrationTest.java create mode 100644 smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/package-info.java diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/SubscriptionIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/SubscriptionIntegrationTest.java new file mode 100644 index 0000000000..f07039c93e --- /dev/null +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/SubscriptionIntegrationTest.java @@ -0,0 +1,196 @@ +/** + * + * Copyright 2021 Guus der Kinderen + * + * 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.subscription; + +import org.jivesoftware.smack.AbstractXMPPConnection; +import org.jivesoftware.smack.packet.Presence; +import org.jivesoftware.smack.packet.StandardExtensionElement; + +import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; +import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; +import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; +import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; + +/** + * Integration tests that verify that sent presence subscription requests are received as intended. + * + * @author Guus der Kinderen, guus.der.kinderen@gmail.com + */ +public class SubscriptionIntegrationTest extends AbstractSmackIntegrationTest { + + public SubscriptionIntegrationTest(SmackIntegrationTestEnvironment environment) { + super(environment); + } + + /** + * This test verifies that a subscription request is received. + * + * @throws Exception on anything unexpected or undesired. + */ + @SmackIntegrationTest + public void testSubscriptionRequest() throws Exception { + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); + + final Presence subscriptionRequest = conTwo.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.subscribe) + .to(conOne.getUser()) + .build(); + + final SimpleResultSyncPoint received = new SimpleResultSyncPoint(); + + conOne.addAsyncStanzaListener(p -> received.signal(), + stanza -> { + if (!(stanza instanceof Presence)) { + return false; + } + if (!stanza.getFrom().asBareJid().equals(conTwo.getUser().asBareJid())) { + return false; + } + final Presence presence = (Presence) stanza; + return Presence.Type.subscribe.equals(presence.getType()); + } + ); + + conTwo.sendStanza(subscriptionRequest); + received.waitForResult(timeout); + } + + /** + * This test verifies that a subscription request is received, in a scenario where the intended recipient was + * offline when the request was made. + * + * @throws Exception on anything unexpected or undesired. + */ + @SmackIntegrationTest + public void testSubscriptionRequestOffline() throws Exception { + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); + + ((AbstractXMPPConnection) conOne).disconnect(); + + final Presence subscriptionRequest = conTwo.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.subscribe) + .to(conOne.getUser()) + .build(); + + conTwo.sendStanza(subscriptionRequest); + + ((AbstractXMPPConnection) conOne).connect(); + + final SimpleResultSyncPoint received = new SimpleResultSyncPoint(); + + conOne.addAsyncStanzaListener(p -> received.signal(), + stanza -> { + if (!(stanza instanceof Presence)) { + return false; + } + if (!stanza.getFrom().asBareJid().equals(conTwo.getUser().asBareJid())) { + return false; + } + final Presence presence = (Presence) stanza; + return Presence.Type.subscribe.equals(presence.getType()); + } + ); + + ((AbstractXMPPConnection) conOne).login(); + received.waitForResult(timeout); + } + + /** + * When a subscription request is made, the stanza can have additional extension elements. This test verifies that + * such extension elements are received. + * + * @throws Exception on anything unexpected or undesired. + */ + @SmackIntegrationTest + public void testSubscriptionRequestWithExtension() throws Exception { + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); + + final Presence subscriptionRequest = conTwo.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.subscribe) + .to(conOne.getUser()) + .addExtension(new StandardExtensionElement("test", "org.example.test")) + .build(); + + final SimpleResultSyncPoint received = new SimpleResultSyncPoint(); + + conOne.addAsyncStanzaListener(p -> received.signal(), + stanza -> { + if (!(stanza instanceof Presence)) { + return false; + } + if (!stanza.getFrom().asBareJid().equals(conTwo.getUser().asBareJid())) { + return false; + } + final Presence presence = (Presence) stanza; + if (!Presence.Type.subscribe.equals(presence.getType())) { + return false; + } + return stanza.hasExtension("test", "org.example.test"); + } + ); + + conTwo.sendStanza(subscriptionRequest); + received.waitForResult(timeout); + } + + /** + * When a subscription request is made, the stanza can have additional extension elements. This test verifies that + * such extension elements are received, in a scenario where the intended recipient was offline when the request + * was made. + * + * @see Openfire issue OF-2244 + * @throws Exception on anything unexpected or undesired. + */ + @SmackIntegrationTest + public void testSubscriptionRequestOfflineWithExtension() throws Exception { + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); + + ((AbstractXMPPConnection) conOne).disconnect(); + + final Presence subscriptionRequest = conTwo.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.subscribe) + .to(conOne.getUser()) + .addExtension(new StandardExtensionElement("test", "org.example.test")) + .build(); + + conTwo.sendStanza(subscriptionRequest); + + ((AbstractXMPPConnection) conOne).connect(); + + final SimpleResultSyncPoint received = new SimpleResultSyncPoint(); + + conOne.addAsyncStanzaListener(p -> received.signal(), + stanza -> { + if (!(stanza instanceof Presence)) { + return false; + } + if (!stanza.getFrom().asBareJid().equals(conTwo.getUser().asBareJid())) { + return false; + } + final Presence presence = (Presence) stanza; + if (!Presence.Type.subscribe.equals(presence.getType())) { + return false; + } + return stanza.hasExtension("test", "org.example.test"); + } + ); + + ((AbstractXMPPConnection) conOne).login(); + received.waitForResult(timeout); + } +} diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/package-info.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/package-info.java new file mode 100644 index 0000000000..5bf5a0422d --- /dev/null +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright 2021 Guus der Kinderen + * + * 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. + */ + +/** + * Integration Tests for presence subscription exchange. + */ +package org.jivesoftware.smack.subscription; From 5e567ad2167b0b232ccde719c8ed05092edff037 Mon Sep 17 00:00:00 2001 From: Dan Caseley Date: Sat, 16 Oct 2021 16:40:13 +0100 Subject: [PATCH 2/4] Fix linter error --- .../java/org/jivesoftware/smack/subscription/package-info.java | 1 + 1 file changed, 1 insertion(+) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/package-info.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/package-info.java index 5bf5a0422d..8251312110 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/package-info.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/package-info.java @@ -1,4 +1,5 @@ /** + * * Copyright 2021 Guus der Kinderen * * Licensed under the Apache License, Version 2.0 (the "License"); From acbc4a507b279c0ad703c130963c995d707a078f Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Sun, 26 Nov 2023 12:09:03 +0100 Subject: [PATCH 3/4] [sint] use idiomatic filters in presence subscription tests --- .../SubscriptionIntegrationTest.java | 79 +++++++------------ 1 file changed, 28 insertions(+), 51 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/SubscriptionIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/SubscriptionIntegrationTest.java index f07039c93e..7551adbafa 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/SubscriptionIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/SubscriptionIntegrationTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2021 Guus der Kinderen + * Copyright 2021-2023 Guus der Kinderen * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,11 @@ package org.jivesoftware.smack.subscription; import org.jivesoftware.smack.AbstractXMPPConnection; +import org.jivesoftware.smack.filter.AndFilter; +import org.jivesoftware.smack.filter.FromMatchesFilter; +import org.jivesoftware.smack.filter.PresenceTypeFilter; +import org.jivesoftware.smack.filter.StanzaExtensionFilter; +import org.jivesoftware.smack.filter.StanzaFilter; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.StandardExtensionElement; @@ -53,19 +58,13 @@ public void testSubscriptionRequest() throws Exception { final SimpleResultSyncPoint received = new SimpleResultSyncPoint(); - conOne.addAsyncStanzaListener(p -> received.signal(), - stanza -> { - if (!(stanza instanceof Presence)) { - return false; - } - if (!stanza.getFrom().asBareJid().equals(conTwo.getUser().asBareJid())) { - return false; - } - final Presence presence = (Presence) stanza; - return Presence.Type.subscribe.equals(presence.getType()); - } + final StanzaFilter resultFilter = new AndFilter( + PresenceTypeFilter.SUBSCRIBE, + FromMatchesFilter.createBare(conTwo.getUser()) ); + conOne.addAsyncStanzaListener(p -> received.signal(), resultFilter); + conTwo.sendStanza(subscriptionRequest); received.waitForResult(timeout); } @@ -93,19 +92,13 @@ public void testSubscriptionRequestOffline() throws Exception { final SimpleResultSyncPoint received = new SimpleResultSyncPoint(); - conOne.addAsyncStanzaListener(p -> received.signal(), - stanza -> { - if (!(stanza instanceof Presence)) { - return false; - } - if (!stanza.getFrom().asBareJid().equals(conTwo.getUser().asBareJid())) { - return false; - } - final Presence presence = (Presence) stanza; - return Presence.Type.subscribe.equals(presence.getType()); - } + final StanzaFilter resultFilter = new AndFilter( + PresenceTypeFilter.SUBSCRIBE, + FromMatchesFilter.createBare(conTwo.getUser()) ); + conOne.addAsyncStanzaListener(p -> received.signal(), resultFilter); + ((AbstractXMPPConnection) conOne).login(); received.waitForResult(timeout); } @@ -128,22 +121,14 @@ public void testSubscriptionRequestWithExtension() throws Exception { final SimpleResultSyncPoint received = new SimpleResultSyncPoint(); - conOne.addAsyncStanzaListener(p -> received.signal(), - stanza -> { - if (!(stanza instanceof Presence)) { - return false; - } - if (!stanza.getFrom().asBareJid().equals(conTwo.getUser().asBareJid())) { - return false; - } - final Presence presence = (Presence) stanza; - if (!Presence.Type.subscribe.equals(presence.getType())) { - return false; - } - return stanza.hasExtension("test", "org.example.test"); - } + final StanzaFilter resultFilter = new AndFilter( + PresenceTypeFilter.SUBSCRIBE, + FromMatchesFilter.createBare(conTwo.getUser()), + new StanzaExtensionFilter("test", "org.example.test") ); + conOne.addAsyncStanzaListener(p -> received.signal(), resultFilter); + conTwo.sendStanza(subscriptionRequest); received.waitForResult(timeout); } @@ -174,22 +159,14 @@ public void testSubscriptionRequestOfflineWithExtension() throws Exception { final SimpleResultSyncPoint received = new SimpleResultSyncPoint(); - conOne.addAsyncStanzaListener(p -> received.signal(), - stanza -> { - if (!(stanza instanceof Presence)) { - return false; - } - if (!stanza.getFrom().asBareJid().equals(conTwo.getUser().asBareJid())) { - return false; - } - final Presence presence = (Presence) stanza; - if (!Presence.Type.subscribe.equals(presence.getType())) { - return false; - } - return stanza.hasExtension("test", "org.example.test"); - } + final StanzaFilter resultFilter = new AndFilter( + PresenceTypeFilter.SUBSCRIBE, + FromMatchesFilter.createBare(conTwo.getUser()), + new StanzaExtensionFilter("test", "org.example.test") ); + conOne.addAsyncStanzaListener(p -> received.signal(), resultFilter); + ((AbstractXMPPConnection) conOne).login(); received.waitForResult(timeout); } From 9a90e7b091e3b1e819a2c98e2b6b35812b59c9c2 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Sun, 26 Nov 2023 13:06:25 +0100 Subject: [PATCH 4/4] [sint] split off low-level tests --- .../LowLevelSubscriptionIntegrationTest.java | 121 ++++++++++++++++++ .../SubscriptionIntegrationTest.java | 73 ----------- 2 files changed, 121 insertions(+), 73 deletions(-) create mode 100644 smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/LowLevelSubscriptionIntegrationTest.java diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/LowLevelSubscriptionIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/LowLevelSubscriptionIntegrationTest.java new file mode 100644 index 0000000000..69fa5110cd --- /dev/null +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/LowLevelSubscriptionIntegrationTest.java @@ -0,0 +1,121 @@ +/** + * + * Copyright 2023 Guus der Kinderen + * + * 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.subscription; + +import org.jivesoftware.smack.AbstractXMPPConnection; +import org.jivesoftware.smack.filter.AndFilter; +import org.jivesoftware.smack.filter.FromMatchesFilter; +import org.jivesoftware.smack.filter.PresenceTypeFilter; +import org.jivesoftware.smack.filter.StanzaExtensionFilter; +import org.jivesoftware.smack.filter.StanzaFilter; +import org.jivesoftware.smack.packet.Presence; +import org.jivesoftware.smack.packet.StandardExtensionElement; + +import org.igniterealtime.smack.inttest.AbstractSmackLowLevelIntegrationTest; +import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; +import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; +import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; + +/** + * Integration tests that verify that sent presence subscription requests are received as intended. + * + * @author Guus der Kinderen, guus.der.kinderen@gmail.com + */ +public class LowLevelSubscriptionIntegrationTest extends AbstractSmackLowLevelIntegrationTest { + public LowLevelSubscriptionIntegrationTest(SmackIntegrationTestEnvironment environment) { + super(environment); + } + + /** + * This test verifies that a subscription request is received, in a scenario where the intended recipient was + * offline when the request was made. + * + * @param conOne Connection used to receive subscription request. + * @param conTwo Conenction used to send subscription request. + * @throws Exception on anything unexpected or undesired. + */ + @SmackIntegrationTest + public void testSubscriptionRequestOffline(final AbstractXMPPConnection conOne, + final AbstractXMPPConnection conTwo) throws Exception { + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); + + final Presence subscriptionRequest = conTwo.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.subscribe) + .to(conOne.getUser().asBareJid()) + .build(); + + conOne.disconnect(); + + conTwo.sendStanza(subscriptionRequest); + + conOne.connect(); + + final SimpleResultSyncPoint received = new SimpleResultSyncPoint(); + + final StanzaFilter resultFilter = new AndFilter( + PresenceTypeFilter.SUBSCRIBE, + FromMatchesFilter.createBare(conTwo.getUser()) + ); + + conOne.addAsyncStanzaListener(p -> received.signal(), resultFilter); + + conOne.login(); + received.waitForResult(timeout); + } + + /** + * When a subscription request is made, the stanza can have additional extension elements. This test verifies that + * such extension elements are received, in a scenario where the intended recipient was offline when the request + * was made. + * + * @param conOne Connection used to receive subscription request. + * @param conTwo Conenction used to send subscription request. + * @see Openfire issue OF-2244 + * @throws Exception on anything unexpected or undesired. + */ + @SmackIntegrationTest + public void testSubscriptionRequestOfflineWithExtension(final AbstractXMPPConnection conOne, + final AbstractXMPPConnection conTwo) throws Exception { + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); + + final Presence subscriptionRequest = conTwo.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.subscribe) + .to(conOne.getUser().asBareJid()) + .addExtension(new StandardExtensionElement("test", "org.example.test")) + .build(); + + conOne.disconnect(); + + conTwo.sendStanza(subscriptionRequest); + + conOne.connect(); + + final SimpleResultSyncPoint received = new SimpleResultSyncPoint(); + + final StanzaFilter resultFilter = new AndFilter( + PresenceTypeFilter.SUBSCRIBE, + FromMatchesFilter.createBare(conTwo.getUser()), + new StanzaExtensionFilter("test", "org.example.test") + ); + + conOne.addAsyncStanzaListener(p -> received.signal(), resultFilter); + + conOne.login(); + received.waitForResult(timeout); + } +} diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/SubscriptionIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/SubscriptionIntegrationTest.java index 7551adbafa..d0373a878c 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/SubscriptionIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/subscription/SubscriptionIntegrationTest.java @@ -16,7 +16,6 @@ */ package org.jivesoftware.smack.subscription; -import org.jivesoftware.smack.AbstractXMPPConnection; import org.jivesoftware.smack.filter.AndFilter; import org.jivesoftware.smack.filter.FromMatchesFilter; import org.jivesoftware.smack.filter.PresenceTypeFilter; @@ -69,40 +68,6 @@ public void testSubscriptionRequest() throws Exception { received.waitForResult(timeout); } - /** - * This test verifies that a subscription request is received, in a scenario where the intended recipient was - * offline when the request was made. - * - * @throws Exception on anything unexpected or undesired. - */ - @SmackIntegrationTest - public void testSubscriptionRequestOffline() throws Exception { - IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); - - ((AbstractXMPPConnection) conOne).disconnect(); - - final Presence subscriptionRequest = conTwo.getStanzaFactory().buildPresenceStanza() - .ofType(Presence.Type.subscribe) - .to(conOne.getUser()) - .build(); - - conTwo.sendStanza(subscriptionRequest); - - ((AbstractXMPPConnection) conOne).connect(); - - final SimpleResultSyncPoint received = new SimpleResultSyncPoint(); - - final StanzaFilter resultFilter = new AndFilter( - PresenceTypeFilter.SUBSCRIBE, - FromMatchesFilter.createBare(conTwo.getUser()) - ); - - conOne.addAsyncStanzaListener(p -> received.signal(), resultFilter); - - ((AbstractXMPPConnection) conOne).login(); - received.waitForResult(timeout); - } - /** * When a subscription request is made, the stanza can have additional extension elements. This test verifies that * such extension elements are received. @@ -132,42 +97,4 @@ public void testSubscriptionRequestWithExtension() throws Exception { conTwo.sendStanza(subscriptionRequest); received.waitForResult(timeout); } - - /** - * When a subscription request is made, the stanza can have additional extension elements. This test verifies that - * such extension elements are received, in a scenario where the intended recipient was offline when the request - * was made. - * - * @see Openfire issue OF-2244 - * @throws Exception on anything unexpected or undesired. - */ - @SmackIntegrationTest - public void testSubscriptionRequestOfflineWithExtension() throws Exception { - IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); - - ((AbstractXMPPConnection) conOne).disconnect(); - - final Presence subscriptionRequest = conTwo.getStanzaFactory().buildPresenceStanza() - .ofType(Presence.Type.subscribe) - .to(conOne.getUser()) - .addExtension(new StandardExtensionElement("test", "org.example.test")) - .build(); - - conTwo.sendStanza(subscriptionRequest); - - ((AbstractXMPPConnection) conOne).connect(); - - final SimpleResultSyncPoint received = new SimpleResultSyncPoint(); - - final StanzaFilter resultFilter = new AndFilter( - PresenceTypeFilter.SUBSCRIBE, - FromMatchesFilter.createBare(conTwo.getUser()), - new StanzaExtensionFilter("test", "org.example.test") - ); - - conOne.addAsyncStanzaListener(p -> received.signal(), resultFilter); - - ((AbstractXMPPConnection) conOne).login(); - received.waitForResult(timeout); - } }