From bbfa70317a5dc20d956f0bf15cfc6cd53fdb8b5f Mon Sep 17 00:00:00 2001
From: Thomas Mortagne <thomas.mortagne@gmail.com>
Date: Mon, 19 Dec 2022 11:31:26 +0100
Subject: [PATCH] XWIKI-20462: Add support for content coming from a different
 source in the code macro * add component missing from previous commit * add
 more tests

---
 .../pom.xml                                   |   2 +-
 .../MacroCodeEntitySoureConfiguration.java    |  62 +++++++
 .../EntityCodeMacroSourceFactoryTest.java     | 154 +++++++++++++++---
 .../code/source/CodeMacroSourceTest.java      |  70 ++++++++
 4 files changed, 264 insertions(+), 24 deletions(-)
 create mode 100644 xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-macros/xwiki-platform-rendering-macro-code-oldcore/src/main/java/org/xwiki/rendering/internal/macro/code/source/MacroCodeEntitySoureConfiguration.java
 create mode 100644 xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-macros/xwiki-platform-rendering-macro-code/src/test/java/org/xwiki/rendering/internal/macro/code/source/CodeMacroSourceTest.java

diff --git a/xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-macros/xwiki-platform-rendering-macro-code-oldcore/pom.xml b/xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-macros/xwiki-platform-rendering-macro-code-oldcore/pom.xml
index b9b2503f5a4..5cb1ba09752 100644
--- a/xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-macros/xwiki-platform-rendering-macro-code-oldcore/pom.xml
+++ b/xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-macros/xwiki-platform-rendering-macro-code-oldcore/pom.xml
@@ -31,7 +31,7 @@
   <name>XWiki Platform - Rendering - Macro - Code Oldcore</name>
   <description>Extend the code macro with features requiring xwiki-platform-oldcore</description>
   <properties>
-    <xwiki.jacoco.instructionRatio>1.00</xwiki.jacoco.instructionRatio>
+    <xwiki.jacoco.instructionRatio>0.71</xwiki.jacoco.instructionRatio>
   </properties>
   <dependencies>
     <dependency>
diff --git a/xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-macros/xwiki-platform-rendering-macro-code-oldcore/src/main/java/org/xwiki/rendering/internal/macro/code/source/MacroCodeEntitySoureConfiguration.java b/xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-macros/xwiki-platform-rendering-macro-code-oldcore/src/main/java/org/xwiki/rendering/internal/macro/code/source/MacroCodeEntitySoureConfiguration.java
new file mode 100644
index 00000000000..e8eabd70147
--- /dev/null
+++ b/xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-macros/xwiki-platform-rendering-macro-code-oldcore/src/main/java/org/xwiki/rendering/internal/macro/code/source/MacroCodeEntitySoureConfiguration.java
@@ -0,0 +1,62 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.xwiki.rendering.internal.macro.code.source;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.xwiki.component.annotation.Component;
+import org.xwiki.configuration.ConfigurationSource;
+
+/**
+ * Configuration related to the various entity sources for the code macro.
+ * 
+ * @version $Id$
+ * @since 15.0RC1
+ * @since 14.10.2
+ */
+@Component(roles = MacroCodeEntitySoureConfiguration.class)
+@Singleton
+public class MacroCodeEntitySoureConfiguration
+{
+    /**
+     * Prefix for configuration keys for the Velocity Macro module.
+     */
+    private static final String PREFIX = "rendering.macro.code.source.";
+
+    /**
+     * Use 10MB as maximum attachment size by default.
+     */
+    private static final int DEFAULT_MAXIMUM_ATTACHMENTSIZE = 10000000;
+
+    /**
+     * Defines from where to read the Pygments configuration data.
+     */
+    @Inject
+    private ConfigurationSource configuration;
+
+    /**
+     * @return the maximum size of attachment to load
+     */
+    public int getMaximumAttachmentSize()
+    {
+        return this.configuration.getProperty(PREFIX + "attachmentMaximumSize", DEFAULT_MAXIMUM_ATTACHMENTSIZE);
+    }
+}
diff --git a/xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-macros/xwiki-platform-rendering-macro-code-oldcore/src/test/java/org/xwiki/rendering/internal/macro/code/source/EntityCodeMacroSourceFactoryTest.java b/xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-macros/xwiki-platform-rendering-macro-code-oldcore/src/test/java/org/xwiki/rendering/internal/macro/code/source/EntityCodeMacroSourceFactoryTest.java
index 67ffdcc79b7..7c3dfb15c50 100644
--- a/xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-macros/xwiki-platform-rendering-macro-code-oldcore/src/test/java/org/xwiki/rendering/internal/macro/code/source/EntityCodeMacroSourceFactoryTest.java
+++ b/xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-macros/xwiki-platform-rendering-macro-code-oldcore/src/test/java/org/xwiki/rendering/internal/macro/code/source/EntityCodeMacroSourceFactoryTest.java
@@ -28,7 +28,10 @@
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.xwiki.internal.model.reference.CurrentPageReferenceDocumentReferenceResolver;
+import org.xwiki.mail.GeneralMailConfiguration;
 import org.xwiki.model.reference.DocumentReference;
+import org.xwiki.model.reference.LocalDocumentReference;
+import org.xwiki.model.reference.WikiReference;
 import org.xwiki.rendering.block.MacroBlock;
 import org.xwiki.rendering.block.XDOM;
 import org.xwiki.rendering.internal.transformation.macro.CurrentMacroEntityReferenceResolver;
@@ -40,10 +43,14 @@
 import org.xwiki.rendering.transformation.MacroTransformationContext;
 import org.xwiki.test.annotation.ComponentList;
 import org.xwiki.test.junit5.mockito.InjectMockComponents;
+import org.xwiki.test.junit5.mockito.MockComponent;
 
 import com.xpn.xwiki.XWikiException;
 import com.xpn.xwiki.doc.XWikiAttachment;
 import com.xpn.xwiki.doc.XWikiDocument;
+import com.xpn.xwiki.objects.BaseObject;
+import com.xpn.xwiki.objects.classes.BaseClass;
+import com.xpn.xwiki.objects.classes.TextAreaClass.ContentType;
 import com.xpn.xwiki.test.MockitoOldcore;
 import com.xpn.xwiki.test.junit5.mockito.InjectMockitoOldcore;
 import com.xpn.xwiki.test.junit5.mockito.OldcoreTest;
@@ -51,6 +58,7 @@
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.when;
 
 /**
  * Validate the various entity macro source factories.
@@ -79,6 +87,15 @@ class EntityCodeMacroSourceFactoryTest
     @InjectMockComponents
     private PageAttachmentCodeMacroSourceFactory pageAttachmentFactory;
 
+    @InjectMockComponents
+    private DocumentObjectPropertyCodeMacroSourceFactory documentObjectPropertyFactory;
+
+    @InjectMockComponents
+    private PageObjectPropertyCodeMacroSourceFactory pageObjectPropertyFactory;
+
+    @MockComponent
+    private GeneralMailConfiguration mailConfiguration;
+
     private MacroTransformationContext macroContext;
 
     @BeforeEach
@@ -94,23 +111,23 @@ public void beforeEach()
     }
 
     private void assertCodeMacroSource(CodeMacroSourceFactory factory, CodeMacroSourceReference reference,
-        String expectedContent, String expectedLanguage, boolean fail) throws MacroExecutionException
+        String expectedContent, String expectedLanguage) throws MacroExecutionException
+    {
+        assertEquals(new CodeMacroSource(reference, expectedContent, expectedLanguage),
+            factory.getContent(reference, this.macroContext));
+    }
+
+    private void assertFailCodeMacroSource(CodeMacroSourceFactory factory, CodeMacroSourceReference reference)
     {
-        if (fail) {
-            assertThrows(MacroExecutionException.class, () -> factory.getContent(reference, this.macroContext));
-        } else {
-            assertEquals(new CodeMacroSource(reference, expectedContent, expectedLanguage),
-                factory.getContent(reference, this.macroContext));
-        }
+        assertThrows(MacroExecutionException.class, () -> factory.getContent(reference, this.macroContext));
     }
 
     @Test
     void getContentDocument() throws MacroExecutionException, XWikiException
     {
-        assertCodeMacroSource(this.documentFactory, new CodeMacroSourceReference("document", "wiki:Space.Document"), "",
-            null, true);
-        assertCodeMacroSource(this.pageFactory, new CodeMacroSourceReference("page", "wiki:Space/Document"), "", null,
-            true);
+        assertFailCodeMacroSource(this.documentFactory,
+            new CodeMacroSourceReference("document", "wiki:Space.Document"));
+        assertFailCodeMacroSource(this.pageFactory, new CodeMacroSourceReference("page", "wiki:Space/Document"));
 
         DocumentReference documentReference = new DocumentReference("wiki", "Space", "Document");
 
@@ -120,26 +137,26 @@ void getContentDocument() throws MacroExecutionException, XWikiException
         this.oldcore.getSpyXWiki().saveDocument(document, this.oldcore.getXWikiContext());
 
         assertCodeMacroSource(this.documentFactory, new CodeMacroSourceReference("document", "wiki:Space.Document"),
-            "document content", null, false);
+            "document content", null);
         assertCodeMacroSource(this.pageFactory, new CodeMacroSourceReference("page", "wiki:Space/Document"),
-            "document content", null, false);
+            "document content", null);
 
         document.setSyntax(Syntax.HTML_5_0);
         this.oldcore.getSpyXWiki().saveDocument(document, this.oldcore.getXWikiContext());
 
         assertCodeMacroSource(this.documentFactory, new CodeMacroSourceReference("document", "wiki:Space.Document"),
-            "document content", "html", false);
+            "document content", "html");
         assertCodeMacroSource(this.pageFactory, new CodeMacroSourceReference("page", "wiki:Space/Document"),
-            "document content", "html", false);
+            "document content", "html");
     }
 
     @Test
     void getContentAttachment() throws MacroExecutionException, XWikiException, IOException
     {
-        assertCodeMacroSource(this.documentAttachmentFactory,
-            new CodeMacroSourceReference("attachment", "wiki:Space.Document@attachment.ext"), "", null, true);
-        assertCodeMacroSource(this.pageAttachmentFactory,
-            new CodeMacroSourceReference("page_attachment", "wiki:Space/Document/attachment.ext"), "", null, true);
+        assertFailCodeMacroSource(this.documentAttachmentFactory,
+            new CodeMacroSourceReference("attachment", "wiki:Space.Document@attachment.ext"));
+        assertFailCodeMacroSource(this.pageAttachmentFactory,
+            new CodeMacroSourceReference("page_attachment", "wiki:Space/Document/attachment.ext"));
 
         DocumentReference documentReference = new DocumentReference("wiki", "Space", "Document");
 
@@ -152,19 +169,110 @@ void getContentAttachment() throws MacroExecutionException, XWikiException, IOEx
 
         assertCodeMacroSource(this.documentAttachmentFactory,
             new CodeMacroSourceReference("attachment", "wiki:Space.Document@attachment.ext"), "attachment content",
-            null, false);
+            null);
         assertCodeMacroSource(this.pageAttachmentFactory,
             new CodeMacroSourceReference("page_attachment", "wiki:Space/Document/attachment.ext"), "attachment content",
-            null, false);
+            null);
 
         attachment.setMimeType("text/html");
         this.oldcore.getSpyXWiki().saveDocument(document, this.oldcore.getXWikiContext());
 
         assertCodeMacroSource(this.documentAttachmentFactory,
             new CodeMacroSourceReference("attachment", "wiki:Space.Document@attachment.ext"), "attachment content",
-            "html", false);
+            "html");
         assertCodeMacroSource(this.pageAttachmentFactory,
             new CodeMacroSourceReference("page_attachment", "wiki:Space/Document/attachment.ext"), "attachment content",
-            "html", false);
+            "html");
+    }
+
+    @Test
+    void getContentObjectProperty() throws MacroExecutionException, XWikiException
+    {
+        assertFailCodeMacroSource(this.documentObjectPropertyFactory,
+            new CodeMacroSourceReference("object_property", "wiki:Space.Document^Space.Class.property"));
+
+        LocalDocumentReference classLocalReference = new LocalDocumentReference("Space", "Class");
+        DocumentReference classDocumentReference =
+            new DocumentReference(classLocalReference, new WikiReference("wiki"));
+        XWikiDocument classDocument =
+            this.oldcore.getSpyXWiki().getDocument(classDocumentReference, this.oldcore.getXWikiContext());
+        BaseClass xclass = classDocument.getXClass();
+        xclass.addPasswordField("password", "Password", 30);
+        xclass.addEmailField("email", "Email", 30);
+        xclass.addTextAreaField("textareasyntax", "Syntax", 5, 30);
+        xclass.addTextAreaField("textareaplain", "PURE_TEXT", 5, 30, ContentType.PURE_TEXT);
+        xclass.addTextAreaField("textareavelocitywiki", "VELOCITYWIKI", 5, 30, ContentType.VELOCITYWIKI);
+        xclass.addTextAreaField("textareavelocitycode", "VELOCITY_CODE", 5, 30, ContentType.VELOCITY_CODE);
+        xclass.addTextField("text", "Text", 30);
+        xclass.addNumberField("number", "Number", 30, "integer");
+        this.oldcore.getSpyXWiki().saveDocument(classDocument, this.oldcore.getXWikiContext());
+
+        DocumentReference documentReference = new DocumentReference("wiki", "Space", "Document");
+        XWikiDocument document =
+            this.oldcore.getSpyXWiki().getDocument(documentReference, this.oldcore.getXWikiContext());
+        BaseObject object = document.newXObject(classLocalReference, this.oldcore.getXWikiContext());
+        object.setStringValue("password", "password content");
+        object.setStringValue("email", "email content");
+        object.setStringValue("text", "text content");
+        object.setLargeStringValue("textareasyntax", "syntax content");
+        object.setLargeStringValue("textareaplain", "plain content");
+        object.setLargeStringValue("textareavelocitywiki", "velocity wiki content");
+        object.setLargeStringValue("textareavelocitycode", "velocity code content");
+        object.setIntValue("number", 42);
+        object.setStringValue("other", "other content");
+        this.oldcore.getSpyXWiki().saveDocument(document, this.oldcore.getXWikiContext());
+
+        // text
+        assertCodeMacroSource(this.documentObjectPropertyFactory,
+            new CodeMacroSourceReference("object_property", "wiki:Space.Document^Space.Class.text"), "text content",
+            null);
+        // number
+        assertCodeMacroSource(this.documentObjectPropertyFactory,
+            new CodeMacroSourceReference("object_property", "wiki:Space.Document^Space.Class.number"), "42", null);
+        // other
+        assertCodeMacroSource(this.documentObjectPropertyFactory,
+            new CodeMacroSourceReference("object_property", "wiki:Space.Document^Space.Class.other"), "other content",
+            null);
+        // email
+        assertCodeMacroSource(this.documentObjectPropertyFactory,
+            new CodeMacroSourceReference("object_property", "wiki:Space.Document^Space.Class.email"), "email content",
+            null);
+        // textareasyntax
+        assertCodeMacroSource(this.documentObjectPropertyFactory,
+            new CodeMacroSourceReference("object_property", "wiki:Space.Document^Space.Class.textareasyntax"),
+            "syntax content", null);
+        // textareaplain
+        assertCodeMacroSource(this.documentObjectPropertyFactory,
+            new CodeMacroSourceReference("object_property", "wiki:Space.Document^Space.Class.textareaplain"),
+            "plain content", null);
+        // textareavelocitywiki
+        assertCodeMacroSource(this.documentObjectPropertyFactory,
+            new CodeMacroSourceReference("object_property", "wiki:Space.Document^Space.Class.textareavelocitywiki"),
+            "velocity wiki content", "velocity");
+        // textareavelocitycode
+        assertCodeMacroSource(this.documentObjectPropertyFactory,
+            new CodeMacroSourceReference("object_property", "wiki:Space.Document^Space.Class.textareavelocitycode"),
+            "velocity code content", "velocity");
+        // password
+        assertFailCodeMacroSource(this.documentObjectPropertyFactory,
+            new CodeMacroSourceReference("object_property", "wiki:Space.Document^Space.Class.passwords"));
+
+        document.setSyntax(Syntax.HTML_5_0);
+        this.oldcore.getSpyXWiki().saveDocument(document, this.oldcore.getXWikiContext());
+
+        // textareasyntax
+        assertCodeMacroSource(this.documentObjectPropertyFactory,
+            new CodeMacroSourceReference("object_property", "wiki:Space.Document^Space.Class.textareasyntax"),
+            "syntax content", "html");
+        // textareaplain
+        assertCodeMacroSource(this.documentObjectPropertyFactory,
+            new CodeMacroSourceReference("object_property", "wiki:Space.Document^Space.Class.textareaplain"),
+            "plain content", null);
+
+        when(this.mailConfiguration.shouldObfuscate()).thenReturn(true);
+
+        // email
+        assertFailCodeMacroSource(this.documentObjectPropertyFactory,
+            new CodeMacroSourceReference("object_property", "wiki:Space.Document^Space.Class.email"));
     }
 }
diff --git a/xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-macros/xwiki-platform-rendering-macro-code/src/test/java/org/xwiki/rendering/internal/macro/code/source/CodeMacroSourceTest.java b/xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-macros/xwiki-platform-rendering-macro-code/src/test/java/org/xwiki/rendering/internal/macro/code/source/CodeMacroSourceTest.java
new file mode 100644
index 00000000000..70b43a872c5
--- /dev/null
+++ b/xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-macros/xwiki-platform-rendering-macro-code/src/test/java/org/xwiki/rendering/internal/macro/code/source/CodeMacroSourceTest.java
@@ -0,0 +1,70 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.xwiki.rendering.internal.macro.code.source;
+
+import org.junit.jupiter.api.Test;
+import org.xwiki.rendering.macro.code.source.CodeMacroSource;
+import org.xwiki.rendering.macro.code.source.CodeMacroSourceReference;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+
+/**
+ * Validate {@link CodeMacroSource}.
+ * 
+ * @version $Id$
+ */
+class CodeMacroSourceTest
+{
+    private static final CodeMacroSourceReference REFERENCE1 = new CodeMacroSourceReference("type1", "reference1");
+
+    private static final CodeMacroSourceReference REFERENCE2 = new CodeMacroSourceReference("type2", "reference2");
+
+    @Test
+    void equalshashcode()
+    {
+        CodeMacroSource source = new CodeMacroSource(null, null, null);
+        assertEquals(source, source);
+        assertEquals(new CodeMacroSource(null, null, null), new CodeMacroSource(null, null, null));
+        assertEquals(new CodeMacroSource(null, null, null).hashCode(),
+            new CodeMacroSource(null, null, null).hashCode());
+        assertEquals(new CodeMacroSource(REFERENCE1, "content", "language"),
+            new CodeMacroSource(REFERENCE1, "content", "language"));
+        assertEquals(new CodeMacroSource(REFERENCE1, "content", "language").hashCode(),
+            new CodeMacroSource(REFERENCE1, "content", "language").hashCode());
+
+        assertNotEquals(new CodeMacroSource(null, null, null), null);
+        assertNotEquals(new CodeMacroSource(REFERENCE1, "content", "language"),
+            new CodeMacroSource(REFERENCE2, "content", "language"));
+        assertNotEquals(new CodeMacroSource(REFERENCE1, "content", "language"),
+            new CodeMacroSource(REFERENCE1, "content1", "language"));
+        assertNotEquals(new CodeMacroSource(REFERENCE1, "content", "language"),
+            new CodeMacroSource(REFERENCE1, "content", "language1"));
+    }
+
+    @Test
+    void tostring()
+    {
+        assertEquals("reference = [<null>], language = [<null>], content = [<null>]",
+            new CodeMacroSource(null, null, null).toString());
+        assertEquals("reference = [type1:reference1], language = [language], content = [content]",
+            new CodeMacroSource(REFERENCE1, "content", "language").toString());
+    }
+}
-- 
GitLab