Smack/smack-experimental/src/test/java/org/jivesoftware/smackx/message_fastening/MessageFasteningElementsTes...

232 lines
9.7 KiB
Java

/**
*
* Copyright 2019 Paul Schaub
*
* 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.smackx.message_fastening;
import static org.jivesoftware.smack.test.util.XmlAssertUtil.assertXmlSimilar;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.util.Arrays;
import org.jivesoftware.smack.packet.MessageBuilder;
import org.jivesoftware.smack.packet.StandardExtensionElement;
import org.jivesoftware.smack.packet.StanzaBuilder;
import org.jivesoftware.smack.packet.StanzaFactory;
import org.jivesoftware.smack.packet.id.StandardStanzaIdSource;
import org.jivesoftware.smack.parsing.SmackParsingException;
import org.jivesoftware.smack.test.util.SmackTestUtil;
import org.jivesoftware.smack.test.util.TestUtils;
import org.jivesoftware.smack.xml.XmlPullParserException;
import org.jivesoftware.smackx.message_fastening.element.ExternalElement;
import org.jivesoftware.smackx.message_fastening.element.FasteningElement;
import org.jivesoftware.smackx.message_fastening.provider.FasteningElementProvider;
import org.jivesoftware.smackx.sid.element.OriginIdElement;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
public class MessageFasteningElementsTest {
private final StanzaFactory stanzaFactory = new StanzaFactory(new StandardStanzaIdSource());
/**
* Test XML serialization of the {@link FasteningElement} using the example provided by
* the XEP.
*
* @see <a href="https://xmpp.org/extensions/xep-0422.html#wrapped-payloads">XEP-0422 §3.1 Wrapped Payloads</a>
*/
@Test
public void fasteningElementSerializationTest() {
String xml =
"<apply-to xmlns='urn:xmpp:fasten:0' id='origin-id-1'>" +
" <i-like-this xmlns='urn:example:like'/>" +
"</apply-to>";
FasteningElement applyTo = FasteningElement.builder()
.setOriginId("origin-id-1")
.addWrappedPayload(new StandardExtensionElement("i-like-this", "urn:example:like"))
.build();
assertXmlSimilar(xml, applyTo.toXML().toString());
}
@ParameterizedTest
@EnumSource(SmackTestUtil.XmlPullParserKind.class)
public void fasteningDeserializationTest(SmackTestUtil.XmlPullParserKind parserKind) throws XmlPullParserException, IOException, SmackParsingException {
String xml =
"<apply-to xmlns='urn:xmpp:fasten:0' id='origin-id-1'>" +
" <i-like-this xmlns='urn:example:like'/>" +
" <external name='custom' element-namespace='urn:example:custom'/>" +
" <external name='body'/>" +
"</apply-to>";
FasteningElement parsed = SmackTestUtil.parse(xml, FasteningElementProvider.class, parserKind);
assertNotNull(parsed);
assertEquals(new OriginIdElement("origin-id-1"), parsed.getReferencedStanzasOriginId());
assertFalse(parsed.isRemovingElement());
assertFalse(parsed.isShellElement());
assertEquals(1, parsed.getWrappedPayloads().size());
assertEquals("i-like-this", parsed.getWrappedPayloads().get(0).getElementName());
assertEquals("urn:example:like", parsed.getWrappedPayloads().get(0).getNamespace());
assertEquals(2, parsed.getExternalPayloads().size());
ExternalElement custom = parsed.getExternalPayloads().get(0);
assertEquals("custom", custom.getName());
assertEquals("urn:example:custom", custom.getElementNamespace());
ExternalElement body = parsed.getExternalPayloads().get(1);
assertEquals("body", body.getName());
assertNull(body.getElementNamespace());
}
@Test
public void fasteningDeserializationClearTest() throws XmlPullParserException, IOException, SmackParsingException {
String xml =
"<apply-to xmlns='urn:xmpp:fasten:0' id='origin-id-1' clear='true'>" +
" <i-like-this xmlns='urn:example:like'/>" +
"</apply-to>";
FasteningElement parsed = FasteningElementProvider.TEST_INSTANCE.parse(TestUtils.getParser(xml));
assertTrue(parsed.isRemovingElement());
}
@Test
public void fasteningElementWithExternalElementsTest() {
String xml =
"<apply-to xmlns='urn:xmpp:fasten:0' id='origin-id-2'>" +
" <external name='body'/>" +
" <external name='custom' element-namespace='urn:example:custom'/>" +
" <edit xmlns='urn:example.edit'/>" +
"</apply-to>";
FasteningElement element = FasteningElement.builder()
.setOriginId("origin-id-2")
.addExternalPayloads(Arrays.asList(
new ExternalElement("body"),
new ExternalElement("custom", "urn:example:custom")
))
.addWrappedPayload(
new StandardExtensionElement("edit", "urn:example.edit"))
.build();
assertXmlSimilar(xml, element.toXML().toString());
}
@Test
public void createShellElementSharesOriginIdTest() {
OriginIdElement originIdElement = new OriginIdElement("sensitive-stanza-1");
FasteningElement sensitiveFastening = FasteningElement.builder()
.setOriginId(originIdElement)
.build();
FasteningElement shellElement = FasteningElement.createShellElementForSensitiveElement(sensitiveFastening);
assertEquals(originIdElement, shellElement.getReferencedStanzasOriginId());
}
@Test
public void fasteningRemoveSerializationTest() {
String xml =
"<apply-to xmlns='urn:xmpp:fasten:0' id='origin-id-1' clear='true'>" +
" <i-like-this xmlns='urn:example:like'>Very much</i-like-this>" +
"</apply-to>";
FasteningElement element = FasteningElement.builder()
.setOriginId("origin-id-1")
.setClear()
.addWrappedPayload(StandardExtensionElement.builder("i-like-this", "urn:example:like")
.setText("Very much")
.build())
.build();
assertXmlSimilar(xml, element.toXML().toString());
}
@Test
public void hasFasteningElementTest() {
MessageBuilder messageBuilderWithFasteningElement = StanzaBuilder.buildMessage()
.setBody("Hi!")
.addExtension(FasteningElement.builder().setOriginId("origin-id-1").build());
MessageBuilder messageBuilderWithoutFasteningElement = StanzaBuilder.buildMessage()
.setBody("Ho!");
assertTrue(FasteningElement.hasFasteningElement(messageBuilderWithFasteningElement));
assertFalse(FasteningElement.hasFasteningElement(messageBuilderWithoutFasteningElement));
}
@Test
public void shellElementMustNotHaveClearAttributeTest() {
assertThrows(IllegalArgumentException.class, () ->
FasteningElement.builder()
.setShell()
.setClear()
.build());
}
@Test
public void shellElementMustNotContainAnyPayloads() {
assertThrows(IllegalArgumentException.class, () ->
FasteningElement.builder()
.setShell()
.addWrappedPayload(new StandardExtensionElement("edit", "urn:example.edit"))
.build());
assertThrows(IllegalArgumentException.class, () ->
FasteningElement.builder()
.setShell()
.addExternalPayload(new ExternalElement("body"))
.build());
}
@Test
public void ensureAddFasteningElementToStanzaWorks() {
MessageBuilder message = stanzaFactory.buildMessageStanza();
FasteningElement fasteningElement = FasteningElement.builder().setOriginId("another-apply-to").build();
// Adding only one element is allowed
fasteningElement.applyTo(message);
}
/**
* Ensure, that {@link FasteningElement#applyTo(MessageBuilder)}
* throws when trying to add an {@link FasteningElement} to a {@link MessageBuilder} that already contains one
* such element.
*
* @see <a href="https://xmpp.org/extensions/xep-0422.html#rules">XEP-0422: §4. Business Rules</a>
*/
@Test
public void ensureStanzaCanOnlyContainOneFasteningElement() {
MessageBuilder messageWithFastening = stanzaFactory.buildMessageStanza();
FasteningElement.builder().setOriginId("origin-id").build().applyTo(messageWithFastening);
// Adding a second fastening MUST result in exception
Assertions.assertThrows(IllegalArgumentException.class, () ->
FasteningElement.builder().setOriginId("another-apply-to").build()
.applyTo(messageWithFastening));
}
}