/** * * 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 XEP-0422 §3.1 Wrapped Payloads */ @Test public void fasteningElementSerializationTest() { String xml = "" + " " + ""; 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 = "" + " " + " " + " " + ""; 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 = "" + " " + ""; FasteningElement parsed = FasteningElementProvider.TEST_INSTANCE.parse(TestUtils.getParser(xml)); assertTrue(parsed.isRemovingElement()); } @Test public void fasteningElementWithExternalElementsTest() { String xml = "" + " " + " " + " " + ""; 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 = "" + " Very much" + ""; 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 XEP-0422: §4. Business Rules */ @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)); } }