mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-22 12:02:05 +01:00
Merge pull request #482 from Fishbowler/xep-0045-coverage-part4
[sinttest] Additional tests covering s7 of XEP-0045
This commit is contained in:
commit
36d6ff2995
8 changed files with 1393 additions and 72 deletions
|
@ -223,6 +223,15 @@ public class MucConfigFormManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the room supports its visibility being controlled vioa configuration.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if supported, <code>false</code> if not.
|
||||||
|
*/
|
||||||
|
public boolean supportsPublicRoom() {
|
||||||
|
return answerForm.hasField(MUC_ROOMCONFIG_PUBLICLYSEARCHABLEROOM);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the room publicly searchable.
|
* Make the room publicly searchable.
|
||||||
*
|
*
|
||||||
|
@ -251,7 +260,7 @@ public class MucConfigFormManager {
|
||||||
* @throws MucConfigurationNotSupportedException if the requested MUC configuration is not supported by the MUC service.
|
* @throws MucConfigurationNotSupportedException if the requested MUC configuration is not supported by the MUC service.
|
||||||
*/
|
*/
|
||||||
public MucConfigFormManager setPublic(boolean isPublic) throws MucConfigurationNotSupportedException {
|
public MucConfigFormManager setPublic(boolean isPublic) throws MucConfigurationNotSupportedException {
|
||||||
if (!supportsModeration()) {
|
if (!supportsPublicRoom()) {
|
||||||
throw new MucConfigurationNotSupportedException(MUC_ROOMCONFIG_PUBLICLYSEARCHABLEROOM);
|
throw new MucConfigurationNotSupportedException(MUC_ROOMCONFIG_PUBLICLYSEARCHABLEROOM);
|
||||||
}
|
}
|
||||||
answerForm.setAnswer(MUC_ROOMCONFIG_PUBLICLYSEARCHABLEROOM, isPublic);
|
answerForm.setAnswer(MUC_ROOMCONFIG_PUBLICLYSEARCHABLEROOM, isPublic);
|
||||||
|
@ -299,7 +308,7 @@ public class MucConfigFormManager {
|
||||||
*/
|
*/
|
||||||
public MucConfigFormManager setIsPasswordProtected(boolean isPasswordProtected)
|
public MucConfigFormManager setIsPasswordProtected(boolean isPasswordProtected)
|
||||||
throws MucConfigurationNotSupportedException {
|
throws MucConfigurationNotSupportedException {
|
||||||
if (!supportsMembersOnly()) {
|
if (!supportsPasswordProtected()) {
|
||||||
throw new MucConfigurationNotSupportedException(MUC_ROOMCONFIG_PASSWORDPROTECTEDROOM);
|
throw new MucConfigurationNotSupportedException(MUC_ROOMCONFIG_PASSWORDPROTECTEDROOM);
|
||||||
}
|
}
|
||||||
answerForm.setAnswer(MUC_ROOMCONFIG_PASSWORDPROTECTEDROOM, isPasswordProtected);
|
answerForm.setAnswer(MUC_ROOMCONFIG_PASSWORDPROTECTEDROOM, isPasswordProtected);
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.igniterealtime.smack.inttest.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.util.Objects;
|
||||||
|
|
||||||
|
public class MultiResultSyncPoint<R, E extends Exception> {
|
||||||
|
|
||||||
|
private final List<R> results;
|
||||||
|
private E exception;
|
||||||
|
private final int expectedResultCount;
|
||||||
|
|
||||||
|
public MultiResultSyncPoint(int expectedResultCount) {
|
||||||
|
this.expectedResultCount = expectedResultCount;
|
||||||
|
this.results = new ArrayList<>(expectedResultCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized List<R> waitForResults(long timeout) throws E, InterruptedException, TimeoutException {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
final long deadline = now + timeout;
|
||||||
|
while (results.size() < expectedResultCount && exception == null && now < deadline) {
|
||||||
|
wait(deadline - now);
|
||||||
|
now = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
if (now >= deadline) throw new TimeoutException("Timeout waiting " + timeout + " millis");
|
||||||
|
if (exception != null) throw exception;
|
||||||
|
return new ArrayList<>(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void signal(R result) {
|
||||||
|
this.results.add(Objects.requireNonNull(result));
|
||||||
|
if (expectedResultCount <= results.size()) {
|
||||||
|
notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void signal(E exception) {
|
||||||
|
this.exception = Objects.requireNonNull(exception);
|
||||||
|
notifyAll();
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,8 @@ import java.util.List;
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.util.StringUtils;
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
|
import org.jivesoftware.smackx.xdata.form.FillableForm;
|
||||||
|
import org.jivesoftware.smackx.xdata.form.Form;
|
||||||
|
|
||||||
import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest;
|
import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest;
|
||||||
import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment;
|
import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment;
|
||||||
|
@ -140,4 +142,75 @@ public abstract class AbstractMultiUserChatIntegrationTest extends AbstractSmack
|
||||||
.makeHidden()
|
.makeHidden()
|
||||||
.submitConfigurationForm();
|
.submitConfigurationForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a non-anonymous room.
|
||||||
|
*
|
||||||
|
* <p>From XEP-0045 § 10.1.3:</p>
|
||||||
|
* <blockquote>
|
||||||
|
* Note: The _whois configuration option specifies whether the room is non-anonymous (a value of "anyone"),
|
||||||
|
* semi-anonymous (a value of "moderators"), or fully anonmyous (a value of "none", not shown here).
|
||||||
|
* </blockquote>
|
||||||
|
*/
|
||||||
|
static void createNonAnonymousMuc(MultiUserChat muc, Resourcepart resourceName) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, InterruptedException, MultiUserChatException.MucAlreadyJoinedException, SmackException.NotConnectedException, MultiUserChatException.MissingMucCreationAcknowledgeException, MultiUserChatException.NotAMucServiceException {
|
||||||
|
muc.create(resourceName);
|
||||||
|
Form configForm = muc.getConfigurationForm();
|
||||||
|
FillableForm answerForm = configForm.getFillableForm();
|
||||||
|
answerForm.setAnswer("muc#roomconfig_whois", "anyone");
|
||||||
|
muc.sendConfigurationForm(answerForm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a semi-anonymous room.
|
||||||
|
*
|
||||||
|
* <p>From XEP-0045 § 10.1.3:</p>
|
||||||
|
* <blockquote>
|
||||||
|
* Note: The _whois configuration option specifies whether the room is non-anonymous (a value of "anyone"),
|
||||||
|
* semi-anonymous (a value of "moderators"), or fully anonmyous (a value of "none", not shown here).
|
||||||
|
* </blockquote>
|
||||||
|
*/
|
||||||
|
static void createSemiAnonymousMuc(MultiUserChat muc, Resourcepart resourceName) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, InterruptedException, MultiUserChatException.MucAlreadyJoinedException, SmackException.NotConnectedException, MultiUserChatException.MissingMucCreationAcknowledgeException, MultiUserChatException.NotAMucServiceException {
|
||||||
|
muc.create(resourceName);
|
||||||
|
Form configForm = muc.getConfigurationForm();
|
||||||
|
FillableForm answerForm = configForm.getFillableForm();
|
||||||
|
answerForm.setAnswer("muc#roomconfig_whois", "moderators");
|
||||||
|
muc.sendConfigurationForm(answerForm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a password-protected room.
|
||||||
|
*/
|
||||||
|
static void createPasswordProtectedMuc(MultiUserChat muc, Resourcepart resourceName, String password) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, InterruptedException, MultiUserChatException.MucAlreadyJoinedException, SmackException.NotConnectedException, MultiUserChatException.MissingMucCreationAcknowledgeException, MultiUserChatException.NotAMucServiceException {
|
||||||
|
muc.create(resourceName);
|
||||||
|
Form configForm = muc.getConfigurationForm();
|
||||||
|
FillableForm answerForm = configForm.getFillableForm();
|
||||||
|
answerForm.setAnswer("muc#roomconfig_passwordprotectedroom", true);
|
||||||
|
answerForm.setAnswer("muc#roomconfig_roomsecret", password);
|
||||||
|
muc.sendConfigurationForm(answerForm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void createLockedMuc(MultiUserChat muc, Resourcepart resourceName) throws
|
||||||
|
SmackException.NoResponseException, XMPPException.XMPPErrorException,
|
||||||
|
InterruptedException, MultiUserChatException.MucAlreadyJoinedException,
|
||||||
|
SmackException.NotConnectedException,
|
||||||
|
MultiUserChatException.MissingMucCreationAcknowledgeException,
|
||||||
|
MultiUserChatException.NotAMucServiceException {
|
||||||
|
muc.create(resourceName);
|
||||||
|
// Note the absence of handle.makeInstant() here. The room is still being created at this point, until a
|
||||||
|
// configuration is set.
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setMaxUsers(MultiUserChat muc, int maxUsers) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, InterruptedException, SmackException.NotConnectedException {
|
||||||
|
Form configForm = muc.getConfigurationForm();
|
||||||
|
FillableForm answerForm = configForm.getFillableForm();
|
||||||
|
answerForm.setAnswer("muc#roomconfig_maxusers", maxUsers);
|
||||||
|
muc.sendConfigurationForm(answerForm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setPublicLogging(MultiUserChat muc, boolean publicLogging) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, InterruptedException, SmackException.NotConnectedException {
|
||||||
|
Form configForm = muc.getConfigurationForm();
|
||||||
|
FillableForm answerForm = configForm.getFillableForm();
|
||||||
|
answerForm.setAnswer("muc#roomconfig_enablelogging", publicLogging);
|
||||||
|
muc.sendConfigurationForm(answerForm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
|
@ -30,11 +31,13 @@ import org.jivesoftware.smack.packet.StanzaError;
|
||||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||||
import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
|
import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
|
||||||
import org.jivesoftware.smackx.disco.packet.DiscoverItems;
|
import org.jivesoftware.smackx.disco.packet.DiscoverItems;
|
||||||
|
import org.jivesoftware.smackx.muc.packet.MUCInitialPresence;
|
||||||
|
|
||||||
import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment;
|
import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment;
|
||||||
import org.igniterealtime.smack.inttest.TestNotPossibleException;
|
import org.igniterealtime.smack.inttest.TestNotPossibleException;
|
||||||
import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest;
|
import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest;
|
||||||
import org.igniterealtime.smack.inttest.annotations.SpecificationReference;
|
import org.igniterealtime.smack.inttest.annotations.SpecificationReference;
|
||||||
|
|
||||||
import org.jxmpp.jid.DomainBareJid;
|
import org.jxmpp.jid.DomainBareJid;
|
||||||
import org.jxmpp.jid.EntityBareJid;
|
import org.jxmpp.jid.EntityBareJid;
|
||||||
import org.jxmpp.jid.EntityFullJid;
|
import org.jxmpp.jid.EntityFullJid;
|
||||||
|
@ -49,6 +52,21 @@ public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatInt
|
||||||
super(environment);
|
super(environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that a MUC service can be discovered.
|
||||||
|
*
|
||||||
|
* @throws Exception when errors occur
|
||||||
|
*/
|
||||||
|
@SmackIntegrationTest(section = "6.1", quote =
|
||||||
|
"An entity often discovers a MUC service by sending a Service Discovery items (\"disco#items\") request to " +
|
||||||
|
"its own server. The server then returns the services that are associated with it.")
|
||||||
|
public void mucTestForDiscoveringMuc() throws Exception {
|
||||||
|
// This repeats some logic from the `AbstractMultiUserChatIntegrationTest` constructor, but is preserved here
|
||||||
|
// as an explicit test, because that might not always be true.
|
||||||
|
List<DomainBareJid> services = ServiceDiscoveryManager.getInstanceFor(conOne).findServices(MUCInitialPresence.NAMESPACE, true, false);
|
||||||
|
assertFalse(services.isEmpty(), "Expected to be able to find MUC services on the domain that '" + conOne.getUser() + "' is connecting to (but could not).");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asserts that a MUC service can have its features discovered.
|
* Asserts that a MUC service can have its features discovered.
|
||||||
*
|
*
|
||||||
|
@ -56,13 +74,12 @@ public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatInt
|
||||||
*/
|
*/
|
||||||
@SmackIntegrationTest(section = "6.2", quote =
|
@SmackIntegrationTest(section = "6.2", quote =
|
||||||
"An entity may wish to discover if a service implements the Multi-User Chat protocol; in order to do so, it " +
|
"An entity may wish to discover if a service implements the Multi-User Chat protocol; in order to do so, it " +
|
||||||
"sends a service discovery information (\"disco#info\") query to the MUC service's JID. The service MUST " +
|
"sends a service discovery information (\"disco#info\") query to the MUC service's JID. The service MUST " +
|
||||||
"return its identity and the features it supports.")
|
"return its identity and the features it supports.")
|
||||||
public void mucTestForDiscoveringFeatures() throws Exception {
|
public void mucTestForDiscoveringFeatures() throws Exception {
|
||||||
final DomainBareJid mucServiceAddress = mucManagerOne.getMucServiceDomains().get(0);
|
DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(conOne).discoverInfo(mucService);
|
||||||
DiscoverInfo info = mucManagerOne.getMucServiceDiscoInfo(mucServiceAddress);
|
assertFalse(info.getIdentities().isEmpty(), "Expected the service discovery information for service " + mucService + " to include identities (but it did not).");
|
||||||
assertFalse(info.getIdentities().isEmpty(), "Expected the service discovery information for service " + mucServiceAddress + " to include identities (but it did not).");
|
assertFalse(info.getFeatures().isEmpty(), "Expected the service discovery information for service " + mucService + " to include features (but it did not).");
|
||||||
assertFalse(info.getFeatures().isEmpty(), "Expected the service discovery information for service " + mucServiceAddress + " to include features (but it did not).");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -120,6 +137,7 @@ public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatInt
|
||||||
|
|
||||||
assertFalse(discoInfo.getIdentities().isEmpty(), "Expected the service discovery information for room " + mucAddress + " to include identities (but it did not).");
|
assertFalse(discoInfo.getIdentities().isEmpty(), "Expected the service discovery information for room " + mucAddress + " to include identities (but it did not).");
|
||||||
assertFalse(discoInfo.getFeatures().isEmpty(), "Expected the service discovery information for room " + mucAddress + " to include features (but it did not).");
|
assertFalse(discoInfo.getFeatures().isEmpty(), "Expected the service discovery information for room " + mucAddress + " to include features (but it did not).");
|
||||||
|
assertTrue(discoInfo.getFeatures().stream().anyMatch(feature -> MultiUserChatConstants.NAMESPACE.equals(feature.getVar())), "Expected the service discovery information for room " + mucAddress + " to include the '" + MultiUserChatConstants.NAMESPACE + "' feature (but it did not).");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -17,9 +17,7 @@
|
||||||
package org.jivesoftware.smackx.muc;
|
package org.jivesoftware.smackx.muc;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
@ -27,9 +25,6 @@ import org.jivesoftware.smack.MessageListener;
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.packet.Message;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
import org.jivesoftware.smack.packet.Presence;
|
|
||||||
|
|
||||||
import org.jivesoftware.smackx.muc.packet.MUCUser;
|
|
||||||
|
|
||||||
import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment;
|
import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment;
|
||||||
import org.igniterealtime.smack.inttest.TestNotPossibleException;
|
import org.igniterealtime.smack.inttest.TestNotPossibleException;
|
||||||
|
@ -48,62 +43,6 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati
|
||||||
super(environment);
|
super(environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Asserts that when a user joins a room, they are themselves included on the list of users notified (self-presence).
|
|
||||||
*
|
|
||||||
* @throws Exception when errors occur
|
|
||||||
*/
|
|
||||||
@SmackIntegrationTest(section = "7.2.2", quote =
|
|
||||||
"... the service MUST also send presence from the new participant's occupant JID to the full JIDs of all the " +
|
|
||||||
"occupants (including the new occupant)")
|
|
||||||
public void mucJoinTest() throws Exception {
|
|
||||||
EntityBareJid mucAddress = getRandomRoom("smack-inttest-join");
|
|
||||||
|
|
||||||
MultiUserChat muc = mucManagerOne.getMultiUserChat(mucAddress);
|
|
||||||
try {
|
|
||||||
Presence reflectedJoinPresence = muc.join(Resourcepart.from("nick-one"));
|
|
||||||
|
|
||||||
MUCUser mucUser = MUCUser.from(reflectedJoinPresence);
|
|
||||||
|
|
||||||
assertNotNull(mucUser, "Expected, but unable, to create a MUCUser instance from reflected join presence: " + reflectedJoinPresence);
|
|
||||||
assertTrue(mucUser.getStatus().contains(MUCUser.Status.PRESENCE_TO_SELF_110), "Expected the reflected join presence of " + conOne.getUser() + " of room " + mucAddress + " to include 'presence-to-self' (" + MUCUser.Status.PRESENCE_TO_SELF_110 + ") but it did not.");
|
|
||||||
assertEquals(mucAddress + "/nick-one", reflectedJoinPresence.getFrom().toString(), "Unexpected 'from' attribute value in the reflected join presence of " + conOne.getUser() + " of room " + mucAddress);
|
|
||||||
assertEquals(conOne.getUser().asEntityFullJidIfPossible().toString(), reflectedJoinPresence.getTo().toString(), "Unexpected 'to' attribute value in the reflected join presence of " + conOne.getUser() + " of room " + mucAddress);
|
|
||||||
} finally {
|
|
||||||
tryDestroy(muc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Asserts that when a user leaves a room, they are themselves included on the list of users notified (self-presence).
|
|
||||||
*
|
|
||||||
* @throws Exception when errors occur
|
|
||||||
*/
|
|
||||||
@SmackIntegrationTest(section = "7.14", quote =
|
|
||||||
"The service MUST then send a presence stanzas of type \"unavailable\" from the departing user's occupant " +
|
|
||||||
"JID to the departing occupant's full JIDs, including a status code of \"110\" to indicate that this " +
|
|
||||||
"notification is \"self-presence\"")
|
|
||||||
public void mucLeaveTest() throws Exception {
|
|
||||||
EntityBareJid mucAddress = getRandomRoom("smack-inttest-leave");
|
|
||||||
|
|
||||||
MultiUserChat muc = mucManagerOne.getMultiUserChat(mucAddress);
|
|
||||||
try {
|
|
||||||
muc.join(Resourcepart.from("nick-one"));
|
|
||||||
|
|
||||||
Presence reflectedLeavePresence = muc.leave();
|
|
||||||
|
|
||||||
MUCUser mucUser = MUCUser.from(reflectedLeavePresence);
|
|
||||||
assertNotNull(mucUser, "Expected, but unable, to create a MUCUser instance from reflected leave presence: " + reflectedLeavePresence);
|
|
||||||
|
|
||||||
assertTrue(mucUser.getStatus().contains(MUCUser.Status.PRESENCE_TO_SELF_110), "Expected the reflected leave presence of " + conOne.getUser() + " of room " + mucAddress + " to include 'presence-to-self' (" + MUCUser.Status.PRESENCE_TO_SELF_110 + ") but it did not.");
|
|
||||||
assertEquals(mucAddress + "/nick-one", reflectedLeavePresence.getFrom().toString(), "Unexpected 'from' attribute value in the reflected leave presence of " + conOne.getUser() + " of room " + mucAddress);
|
|
||||||
assertEquals(conOne.getUser().asEntityFullJidIfPossible().toString(), reflectedLeavePresence.getTo().toString(), "Unexpected 'to' attribute value in the reflected leave presence of " + conOne.getUser() + " of room " + mucAddress);
|
|
||||||
} finally {
|
|
||||||
muc.join(Resourcepart.from("nick-one")); // We need to be in the room to destroy the room
|
|
||||||
tryDestroy(muc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SmackIntegrationTest
|
@SmackIntegrationTest
|
||||||
public void mucTest() throws Exception {
|
public void mucTest() throws Exception {
|
||||||
EntityBareJid mucAddress = getRandomRoom("smack-inttest-message");
|
EntityBareJid mucAddress = getRandomRoom("smack-inttest-message");
|
||||||
|
@ -150,7 +89,7 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati
|
||||||
EntityBareJid mucAddress = getRandomRoom("smack-inttest-destroy");
|
EntityBareJid mucAddress = getRandomRoom("smack-inttest-destroy");
|
||||||
|
|
||||||
MultiUserChat muc = mucManagerOne.getMultiUserChat(mucAddress);
|
MultiUserChat muc = mucManagerOne.getMultiUserChat(mucAddress);
|
||||||
muc.join(Resourcepart.from("nick-one"));
|
createMuc(muc, Resourcepart.from("one-" + randomString));
|
||||||
|
|
||||||
final SimpleResultSyncPoint mucDestroyed = new SimpleResultSyncPoint();
|
final SimpleResultSyncPoint mucDestroyed = new SimpleResultSyncPoint();
|
||||||
|
|
||||||
|
@ -165,8 +104,8 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati
|
||||||
muc.addUserStatusListener(userStatusListener);
|
muc.addUserStatusListener(userStatusListener);
|
||||||
|
|
||||||
// These would be a test implementation bug, not assertion failure.
|
// These would be a test implementation bug, not assertion failure.
|
||||||
if (mucManagerOne.getJoinedRooms().size() != 1) {
|
if (mucManagerOne.getJoinedRooms().stream().noneMatch(room -> room.equals(mucAddress))) {
|
||||||
throw new IllegalStateException("Expected user to have joined a room.");
|
throw new IllegalStateException("Expected user to have joined a room '" + mucAddress + "' (but does not appear to have done so).");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,108 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2024 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.igniterealtime.smack.inttest.util;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.BrokenBarrierException;
|
||||||
|
import java.util.concurrent.CyclicBarrier;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.util.Async;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class MultiResultSyncPointTest {
|
||||||
|
@Test
|
||||||
|
public void testResultSyncPoint() throws Exception {
|
||||||
|
final String result1 = "r1";
|
||||||
|
final String result2 = "r2";
|
||||||
|
final CyclicBarrier barrier = new CyclicBarrier(2);
|
||||||
|
final MultiResultSyncPoint<String, Exception> rsp = new MultiResultSyncPoint<>(2);
|
||||||
|
Async.go(new Async.ThrowingRunnable() {
|
||||||
|
@Override
|
||||||
|
public void runOrThrow() throws InterruptedException, BrokenBarrierException {
|
||||||
|
barrier.await();
|
||||||
|
rsp.signal(result1);
|
||||||
|
rsp.signal(result2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
barrier.await();
|
||||||
|
List<String> receivedResult = rsp.waitForResults(60 * 1000);
|
||||||
|
assertTrue(receivedResult.contains(result1));
|
||||||
|
assertTrue(receivedResult.contains(result2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exceptionTestResultSyncPoint() throws Exception {
|
||||||
|
final CyclicBarrier barrier = new CyclicBarrier(2);
|
||||||
|
final ResultSyncPoint<String, MultiResultSyncPointTest.TestException> rsp = new ResultSyncPoint<>();
|
||||||
|
Async.go(new Async.ThrowingRunnable() {
|
||||||
|
@Override
|
||||||
|
public void runOrThrow() throws InterruptedException, BrokenBarrierException {
|
||||||
|
barrier.await();
|
||||||
|
rsp.signal(new MultiResultSyncPointTest.TestException());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
barrier.await();
|
||||||
|
assertThrows(MultiResultSyncPointTest.TestException.class, () -> rsp.waitForResult(60 * 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTimeout() throws Exception {
|
||||||
|
final MultiResultSyncPoint<String, Exception> rsp = new MultiResultSyncPoint<>(2);
|
||||||
|
try {
|
||||||
|
rsp.waitForResults(100);
|
||||||
|
fail("A timeout exception should have been thrown.");
|
||||||
|
} catch (TimeoutException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTimeoutWithOneResult() throws Exception {
|
||||||
|
final String result1 = "partial";
|
||||||
|
final CyclicBarrier barrier = new CyclicBarrier(2);
|
||||||
|
final MultiResultSyncPoint<String, Exception> rsp = new MultiResultSyncPoint<>(2);
|
||||||
|
Async.go(new Async.ThrowingRunnable() {
|
||||||
|
@Override
|
||||||
|
public void runOrThrow() throws InterruptedException, BrokenBarrierException {
|
||||||
|
barrier.await();
|
||||||
|
rsp.signal(result1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
barrier.await();
|
||||||
|
try {
|
||||||
|
rsp.waitForResults(100);
|
||||||
|
fail("A timeout exception should have been thrown.");
|
||||||
|
} catch (TimeoutException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestException extends Exception {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,9 +18,11 @@ package org.igniterealtime.smack.inttest.util;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
import java.util.concurrent.BrokenBarrierException;
|
import java.util.concurrent.BrokenBarrierException;
|
||||||
import java.util.concurrent.CyclicBarrier;
|
import java.util.concurrent.CyclicBarrier;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.jivesoftware.smack.util.Async;
|
import org.jivesoftware.smack.util.Async;
|
||||||
|
|
||||||
|
@ -60,6 +62,17 @@ public class ResultSyncPointTest {
|
||||||
assertThrows(TestException.class, () -> rsp.waitForResult(60 * 1000));
|
assertThrows(TestException.class, () -> rsp.waitForResult(60 * 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTimeout() throws Exception {
|
||||||
|
final MultiResultSyncPoint<String, Exception> rsp = new MultiResultSyncPoint<>(2);
|
||||||
|
try {
|
||||||
|
rsp.waitForResults(100);
|
||||||
|
fail("A timeout exception should have been thrown.");
|
||||||
|
} catch (TimeoutException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class TestException extends Exception {
|
private static class TestException extends Exception {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue