From 78f0a96fbe41e7f5c6242b1386bf1e7255dd1e1e Mon Sep 17 00:00:00 2001 From: Marius Dumitru Florea <marius@xwiki.com> Date: Thu, 11 Nov 2021 17:28:01 +0200 Subject: [PATCH] XWIKI-19113: Can't edit in place the Title and Content fields --- .../appwithinminutes/test/ui/AllITs.java | 6 ++ .../test/ui/DocumentFieldsIT.java | 79 +++++++++++------- .../AppWithinMinutes/ClassSheetGenerator.xml | 4 +- .../model/script/ModelScriptService.java | 16 ++++ .../model/script/ModelScriptServiceTest.java | 11 +++ .../main/java/com/xpn/xwiki/api/Object.java | 21 +++++ .../java/com/xpn/xwiki/api/ObjectTest.java | 81 +++++++++++++++++++ .../ui/po/DocumentSyntaxPropertyPane.java | 2 +- .../test/ui/po/EditablePropertyPane.java | 60 ++++++++++++-- .../xwiki/xclass/test/ui/ClassSheetIT.java | 26 +++++- .../src/test/resources/contentDisplayer.wiki | 11 +++ .../src/main/resources/XWiki/ObjectSheet.xml | 2 +- 12 files changed, 280 insertions(+), 39 deletions(-) rename xwiki-platform-distribution/xwiki-platform-distribution-flavor/xwiki-platform-distribution-flavor-test/xwiki-platform-distribution-flavor-test-ui/src/test/it/org/xwiki/test/ui/appwithinminutes/DocumentFieldsTest.java => xwiki-platform-core/xwiki-platform-appwithinminutes/xwiki-platform-appwithinminutes-test/xwiki-platform-appwithinminutes-test-docker/src/test/it/org/xwiki/appwithinminutes/test/ui/DocumentFieldsIT.java (62%) create mode 100644 xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/api/ObjectTest.java create mode 100644 xwiki-platform-core/xwiki-platform-xclass/xwiki-platform-xclass-test/xwiki-platform-xclass-test-docker/src/test/resources/contentDisplayer.wiki diff --git a/xwiki-platform-core/xwiki-platform-appwithinminutes/xwiki-platform-appwithinminutes-test/xwiki-platform-appwithinminutes-test-docker/src/test/it/org/xwiki/appwithinminutes/test/ui/AllITs.java b/xwiki-platform-core/xwiki-platform-appwithinminutes/xwiki-platform-appwithinminutes-test/xwiki-platform-appwithinminutes-test-docker/src/test/it/org/xwiki/appwithinminutes/test/ui/AllITs.java index da8ff799f28..9c06dea8937 100644 --- a/xwiki-platform-core/xwiki-platform-appwithinminutes/xwiki-platform-appwithinminutes-test/xwiki-platform-appwithinminutes-test-docker/src/test/it/org/xwiki/appwithinminutes/test/ui/AllITs.java +++ b/xwiki-platform-core/xwiki-platform-appwithinminutes/xwiki-platform-appwithinminutes-test/xwiki-platform-appwithinminutes-test-docker/src/test/it/org/xwiki/appwithinminutes/test/ui/AllITs.java @@ -61,4 +61,10 @@ class NestedLiveTableGeneratorIT extends LiveTableGeneratorIT class NestedAddEntryIT extends AddEntryIT { } + + @Nested + @DisplayName("Document fields test") + class NestedDocumentFieldsIT extends DocumentFieldsIT + { + } } diff --git a/xwiki-platform-distribution/xwiki-platform-distribution-flavor/xwiki-platform-distribution-flavor-test/xwiki-platform-distribution-flavor-test-ui/src/test/it/org/xwiki/test/ui/appwithinminutes/DocumentFieldsTest.java b/xwiki-platform-core/xwiki-platform-appwithinminutes/xwiki-platform-appwithinminutes-test/xwiki-platform-appwithinminutes-test-docker/src/test/it/org/xwiki/appwithinminutes/test/ui/DocumentFieldsIT.java similarity index 62% rename from xwiki-platform-distribution/xwiki-platform-distribution-flavor/xwiki-platform-distribution-flavor-test/xwiki-platform-distribution-flavor-test-ui/src/test/it/org/xwiki/test/ui/appwithinminutes/DocumentFieldsTest.java rename to xwiki-platform-core/xwiki-platform-appwithinminutes/xwiki-platform-appwithinminutes-test/xwiki-platform-appwithinminutes-test-docker/src/test/it/org/xwiki/appwithinminutes/test/ui/DocumentFieldsIT.java index 8fa1008c329..6f720f895f4 100644 --- a/xwiki-platform-distribution/xwiki-platform-distribution-flavor/xwiki-platform-distribution-flavor-test/xwiki-platform-distribution-flavor-test-ui/src/test/it/org/xwiki/test/ui/appwithinminutes/DocumentFieldsTest.java +++ b/xwiki-platform-core/xwiki-platform-appwithinminutes/xwiki-platform-appwithinminutes-test/xwiki-platform-appwithinminutes-test-docker/src/test/it/org/xwiki/appwithinminutes/test/ui/DocumentFieldsIT.java @@ -17,14 +17,13 @@ * 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.test.ui.appwithinminutes; +package org.xwiki.appwithinminutes.test.ui; import java.util.Arrays; import org.apache.commons.lang3.RandomStringUtils; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.xwiki.appwithinminutes.test.po.ApplicationClassEditPage; import org.xwiki.appwithinminutes.test.po.ApplicationCreatePage; import org.xwiki.appwithinminutes.test.po.ApplicationHomeEditPage; @@ -33,26 +32,45 @@ import org.xwiki.appwithinminutes.test.po.EntryEditPage; import org.xwiki.appwithinminutes.test.po.EntryNamePane; import org.xwiki.model.reference.LocalDocumentReference; -import org.xwiki.test.ui.AbstractTest; -import org.xwiki.test.ui.AdminAuthenticationRule; +import org.xwiki.test.docker.junit5.UITest; +import org.xwiki.test.ui.TestUtils; +import org.xwiki.test.ui.po.EditablePropertyPane; import org.xwiki.test.ui.po.LiveTableElement; import org.xwiki.test.ui.po.ViewPage; import org.xwiki.test.ui.po.editor.WikiEditPage; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** * Tests the special document fields available in the class editor, such as Title and Content. * * @version $Id$ - * @since 4.5RC1 + * @since 12.10.11 + * @since 13.4.6 + * @since 13.10RC1 */ -public class DocumentFieldsTest extends AbstractTest +@UITest +class DocumentFieldsIT { - @Rule - public AdminAuthenticationRule adminAuthenticationRule = new AdminAuthenticationRule(true, getUtil()); + @BeforeAll + static void beforeAll(TestUtils setup) + { + // By default the minimal distribution used for the tests doesn't have any rights setup. Let's create an Admin + // user part of the Admin Group and make sure that this Admin Group has admin rights in the wiki. We could also + // have given that Admin user the admin right directly but the solution we chose is closer to the XS + // distribution. + setup.loginAsSuperAdmin(); + setup.setGlobalRights("XWiki.XWikiAdminGroup", "", "admin", true); + setup.createAdminUser(); + setup.loginAsAdmin(); + } @Test - public void titleAndContent() + void titleAndContent(TestUtils setup) { + setup.loginAsAdmin(); + // Create a new application. String appName = RandomStringUtils.randomAlphabetic(6); ApplicationCreatePage appCreatePage = ApplicationCreatePage.gotoPage(); @@ -88,37 +106,44 @@ public void titleAndContent() EntryNamePane entryNamePane = homeEditPage.clickFinish().clickAddNewEntry(); entryNamePane.setName("Test"); EntryEditPage entryEditPage = entryNamePane.clickAdd(); - Assert.assertEquals("13", entryEditPage.getValue("number1")); + assertEquals("13", entryEditPage.getValue("number1")); // The page name is used as the default value for the title field. - Assert.assertEquals("Test", entryEditPage.getDocumentTitle()); - Assert.assertEquals("Test", entryEditPage.getTitle()); + assertEquals("Test", entryEditPage.getDocumentTitle()); + assertEquals("Test", entryEditPage.getTitle()); entryEditPage.setTitle("Foo"); - Assert.assertEquals(defaultContent, entryEditPage.getContent()); + assertEquals(defaultContent, entryEditPage.getContent()); entryEditPage.setContent("Bar"); // Check that the title and the content of the entry have been updated. ViewPage entryViewPage = entryEditPage.clickSaveAndView(); - Assert.assertEquals("Foo", entryViewPage.getDocumentTitle()); - Assert.assertTrue(entryViewPage.getContent().contains("Bar")); - entryViewPage.clickBreadcrumbLink(appName); + assertEquals("Foo", entryViewPage.getDocumentTitle()); + assertTrue(entryViewPage.getContent().contains("Bar")); + + // Verify that we can edit the document fields in-place. + String propertyReference = String.format("%s.Code.%1$sClass[0].title1", appName); + EditablePropertyPane<String> titleProperty = new EditablePropertyPane<>(propertyReference); + assertEquals("Foo", titleProperty.clickEdit().getValue()); + titleProperty.setValue("Book").clickSave(); + assertEquals("Book", titleProperty.getDisplayValue()); // Check the entries live table. + entryViewPage.clickBreadcrumbLink(appName); LiveTableElement liveTable = new ApplicationHomePage().getEntriesLiveTable(); liveTable.waitUntilReady(); - Assert.assertEquals(1, liveTable.getRowCount()); - Assert.assertTrue(liveTable.hasRow("My Title", "Foo")); - Assert.assertTrue(liveTable.hasRow("My Content", "Bar")); + assertEquals(1, liveTable.getRowCount()); + assertTrue(liveTable.hasRow("My Title", "Book")); + assertTrue(liveTable.hasRow("My Content", "Bar")); // Check that the title and the content of the class have not been changed. - getUtil().gotoPage(new LocalDocumentReference(Arrays.asList(appName, "Code"), appName + "Class"), "edit", + setup.gotoPage(new LocalDocumentReference(Arrays.asList(appName, "Code"), appName + "Class"), "edit", "editor=wiki"); WikiEditPage editPage = new WikiEditPage(); - Assert.assertEquals(appName + " Class", editPage.getTitle()); - Assert.assertEquals("", editPage.getContent()); + assertEquals(appName + " Class", editPage.getTitle()); + assertEquals("", editPage.getContent()); // Now edit the class and check if the default values for title and content are taken from the template. - editPage.editInline(); - Assert.assertEquals(defaultTitle, new ClassFieldEditPane("title1").getDefaultValue()); - Assert.assertEquals(defaultContent, new ClassFieldEditPane("content1").getDefaultValue()); + editPage.edit(); + assertEquals(defaultTitle, new ClassFieldEditPane("title1").getDefaultValue()); + assertEquals(defaultContent, new ClassFieldEditPane("content1").getDefaultValue()); } } diff --git a/xwiki-platform-core/xwiki-platform-appwithinminutes/xwiki-platform-appwithinminutes-ui/src/main/resources/AppWithinMinutes/ClassSheetGenerator.xml b/xwiki-platform-core/xwiki-platform-appwithinminutes/xwiki-platform-appwithinminutes-ui/src/main/resources/AppWithinMinutes/ClassSheetGenerator.xml index babeff1b72e..832bd0acc61 100644 --- a/xwiki-platform-core/xwiki-platform-appwithinminutes/xwiki-platform-appwithinminutes-ui/src/main/resources/AppWithinMinutes/ClassSheetGenerator.xml +++ b/xwiki-platform-core/xwiki-platform-appwithinminutes/xwiki-platform-appwithinminutes-ui/src/main/resources/AppWithinMinutes/ClassSheetGenerator.xml @@ -20,7 +20,7 @@ * 02110-1301 USA, or see the FSF site: http://www.fsf.org. --> -<xwikidoc version="1.3" reference="AppWithinMinutes.ClassSheetGenerator" locale=""> +<xwikidoc version="1.4" reference="AppWithinMinutes.ClassSheetGenerator" locale=""> <web>AppWithinMinutes</web> <name>ClassSheetGenerator</name> <language/> @@ -47,7 +47,7 @@ #macro(displayProperty $property $indentation) ${indentation}<dt ${escapetool.h}if (!${escapetool.d}editing && ${escapetool.d}hasEdit) ${indentation} class="editableProperty" -${indentation} data-property="${escapetool.d}escapetool.xml(${escapetool.d}services.model.serialize(${escapetool.d}object.getProperty('#escapeSingleQuotes($property.name)').reference))" +${indentation} data-property="${escapetool.d}escapetool.xml(${escapetool.d}services.model.serialize(${escapetool.d}object.getPropertyReference('#escapeSingleQuotes($property.name)')))" ${indentation} data-property-type="object"${escapetool.h}end> ${indentation} <label${escapetool.h}if (${escapetool.d}editing) for="$escapetool.xml("${doc.fullName}_0_$property.name")"${escapetool.h}end> ${indentation} ${escapetool.d}escapetool.xml(${escapetool.d}doc.displayPrettyName('#escapeSingleQuotes($property.name)', false, false)) diff --git a/xwiki-platform-core/xwiki-platform-model/xwiki-platform-model-api/src/main/java/org/xwiki/model/script/ModelScriptService.java b/xwiki-platform-core/xwiki-platform-model/xwiki-platform-model-api/src/main/java/org/xwiki/model/script/ModelScriptService.java index 6686844e8d9..2484c8fa1c4 100644 --- a/xwiki-platform-core/xwiki-platform-model/xwiki-platform-model-api/src/main/java/org/xwiki/model/script/ModelScriptService.java +++ b/xwiki-platform-core/xwiki-platform-model/xwiki-platform-model-api/src/main/java/org/xwiki/model/script/ModelScriptService.java @@ -309,6 +309,22 @@ public PageAttachmentReference createPageAttachmentReference(PageReference pageR return new PageAttachmentReference(fileName, pageReference); } + /** + * Creates an {@link ObjectPropertyReference} from a property name and the reference of the object having that + * property. + * + * @param propertyName the property name + * @param objectReference the object reference + * @return the reference of the specified object property + * @since 12.10.11 + * @since 13.4.6 + * @since 13.10RC1 + */ + public ObjectPropertyReference createObjectPropertyReference(String propertyName, ObjectReference objectReference) + { + return new ObjectPropertyReference(propertyName, objectReference); + } + /** * Creates a {@link WikiReference} from a string representing the wiki name. * diff --git a/xwiki-platform-core/xwiki-platform-model/xwiki-platform-model-api/src/test/java/org/xwiki/model/script/ModelScriptServiceTest.java b/xwiki-platform-core/xwiki-platform-model/xwiki-platform-model-api/src/test/java/org/xwiki/model/script/ModelScriptServiceTest.java index 1ceb94697a9..9fc8b17d0e6 100644 --- a/xwiki-platform-core/xwiki-platform-model/xwiki-platform-model-api/src/test/java/org/xwiki/model/script/ModelScriptServiceTest.java +++ b/xwiki-platform-core/xwiki-platform-model/xwiki-platform-model-api/src/test/java/org/xwiki/model/script/ModelScriptServiceTest.java @@ -35,6 +35,8 @@ import org.xwiki.model.reference.EntityReference; import org.xwiki.model.reference.EntityReferenceResolver; import org.xwiki.model.reference.EntityReferenceValueProvider; +import org.xwiki.model.reference.ObjectPropertyReference; +import org.xwiki.model.reference.ObjectReference; import org.xwiki.model.reference.PageReference; import org.xwiki.model.reference.PageReferenceResolver; import org.xwiki.model.reference.SpaceReference; @@ -329,4 +331,13 @@ public void resolveClassPropertyWithHintAndParameters() throws Exception assertEquals(reference, this.service.resolveClassProperty("Class^property", "custom", parameters[0], parameters[1])); } + + @Test + void createObjectPropertyReference() + { + ObjectReference objectReference = + new ObjectReference("objectName", new DocumentReference("test", "Some", "Page")); + assertEquals(new ObjectPropertyReference("test", objectReference), + this.service.createObjectPropertyReference("test", objectReference)); + } } diff --git a/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/Object.java b/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/Object.java index 546a554b404..bb50d7fd3c2 100644 --- a/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/Object.java +++ b/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/Object.java @@ -19,6 +19,8 @@ */ package com.xpn.xwiki.api; +import org.xwiki.model.reference.ObjectPropertyReference; + import com.xpn.xwiki.XWikiContext; import com.xpn.xwiki.XWikiException; import com.xpn.xwiki.doc.XWikiDocument; @@ -126,4 +128,23 @@ public BaseObjectReference getReference() { return getBaseObject().getReference(); } + + /** + * Helper method used to obtain the reference of an object property even when the object might not have the property + * (e.g. because it's a computed property which doesn't have a stored value so it's not saved on the object). This + * is a safe alternative to {@code getProperty(propertyName).getReference()} when you're not sure whether the object + * has the specified property or not. + * + * @param propertyName the property name + * @return the object property reference + * @see <a href="https://jira.xwiki.org/browse/XWIKI-19031">XWIKI-19031: Computed fields are stored as empty string + * properties in the database</a> + * @since 12.10.11 + * @since 13.4.6 + * @since 13.10RC1 + */ + public ObjectPropertyReference getPropertyReference(String propertyName) + { + return new ObjectPropertyReference(propertyName, getReference()); + } } diff --git a/xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/api/ObjectTest.java b/xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/api/ObjectTest.java new file mode 100644 index 00000000000..48540f716ce --- /dev/null +++ b/xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/api/ObjectTest.java @@ -0,0 +1,81 @@ +/* + * 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 com.xpn.xwiki.api; + +import javax.inject.Named; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.xwiki.model.reference.DocumentReference; +import org.xwiki.model.reference.EntityReferenceSerializer; +import org.xwiki.model.reference.ObjectPropertyReference; +import org.xwiki.test.junit5.mockito.MockComponent; + +import com.xpn.xwiki.XWikiContext; +import com.xpn.xwiki.objects.BaseObject; +import com.xpn.xwiki.objects.BaseObjectReference; +import com.xpn.xwiki.test.junit5.mockito.OldcoreTest; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; + +/** + * Unit tests for {@link Object}. + * + * @version $Id$ + * @since 12.10.11 + * @since 13.4.6 + * @since 13.10RC1 + */ +@OldcoreTest +class ObjectTest +{ + private Object object; + + @Mock + private BaseObject baseObject; + + @Mock + private XWikiContext xcontext; + + @MockComponent + @Named("compactwiki") + private EntityReferenceSerializer<String> compactWikiSerializer; + + @BeforeEach + void setUp() + { + DocumentReference classReference = new DocumentReference("test", "Some", "Class"); + DocumentReference documentReference = new DocumentReference("test", "Some", "Page"); + when(this.compactWikiSerializer.serialize(classReference, documentReference)).thenReturn("Some.Class"); + BaseObjectReference objectReference = new BaseObjectReference(classReference, 0, documentReference); + when(this.baseObject.getReference()).thenReturn(objectReference); + + this.object = new Object(this.baseObject, this.xcontext); + } + + @Test + void getPropertyReference() + { + assertEquals(new ObjectPropertyReference("age", this.baseObject.getReference()), + object.getPropertyReference("age")); + } +} diff --git a/xwiki-platform-core/xwiki-platform-test/xwiki-platform-test-ui/src/main/java/org/xwiki/test/ui/po/DocumentSyntaxPropertyPane.java b/xwiki-platform-core/xwiki-platform-test/xwiki-platform-test-ui/src/main/java/org/xwiki/test/ui/po/DocumentSyntaxPropertyPane.java index 11362199110..5090e5e964b 100644 --- a/xwiki-platform-core/xwiki-platform-test/xwiki-platform-test-ui/src/main/java/org/xwiki/test/ui/po/DocumentSyntaxPropertyPane.java +++ b/xwiki-platform-core/xwiki-platform-test/xwiki-platform-test-ui/src/main/java/org/xwiki/test/ui/po/DocumentSyntaxPropertyPane.java @@ -26,7 +26,7 @@ * @since 12.6.3 * @since 12.9RC1 */ -public class DocumentSyntaxPropertyPane extends EditablePropertyPane +public class DocumentSyntaxPropertyPane extends EditablePropertyPane<String> { public DocumentSyntaxPropertyPane() { diff --git a/xwiki-platform-core/xwiki-platform-test/xwiki-platform-test-ui/src/main/java/org/xwiki/test/ui/po/EditablePropertyPane.java b/xwiki-platform-core/xwiki-platform-test/xwiki-platform-test-ui/src/main/java/org/xwiki/test/ui/po/EditablePropertyPane.java index 889bee7c480..e0dc616ca4a 100644 --- a/xwiki-platform-core/xwiki-platform-test/xwiki-platform-test-ui/src/main/java/org/xwiki/test/ui/po/EditablePropertyPane.java +++ b/xwiki-platform-core/xwiki-platform-test/xwiki-platform-test-ui/src/main/java/org/xwiki/test/ui/po/EditablePropertyPane.java @@ -27,11 +27,12 @@ /** * The page object used to edit a document or object property in-place. * + * @param <T> the property value type * @version $Id$ * @since 12.6.3 * @since 12.9RC1 */ -public class EditablePropertyPane extends BaseElement +public class EditablePropertyPane<T> extends BaseElement { protected final WebElement element; @@ -47,8 +48,8 @@ public class EditablePropertyPane extends BaseElement public EditablePropertyPane(String property) { - this.element = getDriver().findElement( - By.cssSelector("dt.editableProperty[data-property=\"" + property + "\"]")); + this.element = + getDriver().findElement(By.cssSelector("dt.editableProperty[data-property=\"" + property + "\"]")); this.viewer = this.element.findElement(By.xpath("./following-sibling::dd[contains(@class, 'editableProperty-viewer')]")); this.editor = @@ -58,21 +59,21 @@ public EditablePropertyPane(String property) this.saveButton = this.element.findElement(By.className("editableProperty-save")); } - public EditablePropertyPane clickEdit() + public EditablePropertyPane<T> clickEdit() { this.editButton.click(); getDriver().waitUntilCondition(visibilityOf(this.editor)); return this; } - public EditablePropertyPane clickCancel() + public EditablePropertyPane<T> clickCancel() { this.cancelButton.click(); getDriver().waitUntilCondition(visibilityOf(this.editButton)); return this; } - public EditablePropertyPane clickSave() + public EditablePropertyPane<T> clickSave() { this.saveButton.click(); getDriver().waitUntilCondition(visibilityOf(this.editButton)); @@ -88,4 +89,51 @@ public String getDisplayValue() { return this.viewer.getText(); } + + /** + * @return the property value while the property is being edited + * @since 12.10.11 + * @since 13.4.6 + * @since 13.10RC1 + */ + @SuppressWarnings("unchecked") + public T getValue() + { + WebElement inputField = getInputField(); + if ("checkbox".equals(inputField.getAttribute("type"))) { + return (T) Boolean.valueOf(inputField.isSelected()); + } else { + return (T) inputField.getAttribute("value"); + } + } + + /** + * Sets the property value while the property is being edited. + * + * @param value the new property value + * @return this property pane + * @since 12.10.11 + * @since 13.4.6 + * @since 13.10RC1 + */ + public EditablePropertyPane<T> setValue(T value) + { + WebElement inputField = getInputField(); + if (value instanceof Boolean) { + // If the value is boolean then we assume the input field is a checkbox. + if (inputField.isSelected() != (Boolean) value) { + inputField.click(); + } + } else { + // Assume the input field is a text field (text input or text area). + inputField.clear(); + inputField.sendKeys(String.valueOf(value)); + } + return this; + } + + private WebElement getInputField() + { + return getDriver().findElementWithoutWaiting(this.editor, By.cssSelector("[name]")); + } } diff --git a/xwiki-platform-core/xwiki-platform-xclass/xwiki-platform-xclass-test/xwiki-platform-xclass-test-docker/src/test/it/org/xwiki/xclass/test/ui/ClassSheetIT.java b/xwiki-platform-core/xwiki-platform-xclass/xwiki-platform-xclass-test/xwiki-platform-xclass-test-docker/src/test/it/org/xwiki/xclass/test/ui/ClassSheetIT.java index 491e1f73618..67efa0d10c3 100644 --- a/xwiki-platform-core/xwiki-platform-xclass/xwiki-platform-xclass-test/xwiki-platform-xclass-test-docker/src/test/it/org/xwiki/xclass/test/ui/ClassSheetIT.java +++ b/xwiki-platform-core/xwiki-platform-xclass/xwiki-platform-xclass-test/xwiki-platform-xclass-test-docker/src/test/it/org/xwiki/xclass/test/ui/ClassSheetIT.java @@ -19,12 +19,14 @@ */ package org.xwiki.xclass.test.ui; +import org.apache.commons.io.IOUtils; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.xwiki.test.docker.junit5.TestReference; import org.xwiki.test.docker.junit5.UITest; import org.xwiki.test.ui.TestUtils; +import org.xwiki.test.ui.po.EditablePropertyPane; import org.xwiki.test.ui.po.InlinePage; import org.xwiki.test.ui.po.ViewPage; import org.xwiki.test.ui.po.editor.ClassEditPage; @@ -55,7 +57,7 @@ void setup(TestUtils setup) */ @Test @Order(1) - void createClass(TestUtils setup, TestReference reference) + void createClass(TestUtils setup, TestReference reference) throws Exception { //TODO: rewrite the test to not rely on the breadcrumb based on parent/child mechanism. setup.setHierarchyMode("parentchild"); @@ -89,6 +91,12 @@ void createClass(TestUtils setup, TestReference reference) // Add a new property. classEditor = classSheetPage.waitUntilPageIsLoaded().clickEditClassLink(); classEditor.addProperty("age", "Number").setPrettyName("Your current age"); + + // Add a computed property. + String titleDisplayer = + IOUtils.toString(this.getClass().getResourceAsStream("/contentDisplayer.wiki"), "UTF-8"); + classEditor.addProperty("description", "ComputedField").setPrettyName("Description") + .setMetaProperty("customDisplay", titleDisplayer); classEditor.clickSaveAndView(); // We have to wait for the page to load because Selenium doesn't do it all the time when we click on Save & View @@ -99,6 +107,7 @@ void createClass(TestUtils setup, TestReference reference) // Assert that the properties are listed. assertTrue(classSheetPage.hasProperty("color", "Your favorite color", "String")); assertTrue(classSheetPage.hasProperty("age", "Your current age", "Number")); + assertTrue(classSheetPage.hasProperty("description", "Description", "Computed Field")); // Create and bind a sheet. classSheetPage = classSheetPage.clickCreateSheetButton().waitUntilPageIsLoaded() @@ -134,8 +143,21 @@ void createClass(TestUtils setup, TestReference reference) editPage.setValue("age", "27"); ViewPage viewPage = editPage.clickSaveAndView(); + // Verify that the properties can be edited in-place. + EditablePropertyPane<String> colorProperty = + new EditablePropertyPane<>(String.format("%s.%s[0].color", spaceName, classDocName)); + assertEquals("blue", colorProperty.clickEdit().getValue()); + colorProperty.setValue("pink").clickSave(); + assertEquals("pink", colorProperty.getDisplayValue()); + + EditablePropertyPane<String> descriptionProperty = + new EditablePropertyPane<>(String.format("%s.%s[0].description", spaceName, classDocName)); + assertEquals("", descriptionProperty.clickEdit().getValue()); + descriptionProperty.setValue("Tester").clickSave(); + assertEquals("Tester", descriptionProperty.getDisplayValue()); + assertEquals(pageName, viewPage.getDocumentTitle()); - assertEquals("YOUR FAVORITE COLOR\nblue\nYOUR CURRENT AGE\n27", viewPage.getContent()); + assertEquals("YOUR FAVORITE COLOR\npink\nYOUR CURRENT AGE\n27\nDESCRIPTION\nTester", viewPage.getContent()); viewPage.clickBreadcrumbLink(classTitle); classSheetPage.waitUntilPageIsLoaded(); diff --git a/xwiki-platform-core/xwiki-platform-xclass/xwiki-platform-xclass-test/xwiki-platform-xclass-test-docker/src/test/resources/contentDisplayer.wiki b/xwiki-platform-core/xwiki-platform-xclass/xwiki-platform-xclass-test/xwiki-platform-xclass-test-docker/src/test/resources/contentDisplayer.wiki new file mode 100644 index 00000000000..d8d27b9d727 --- /dev/null +++ b/xwiki-platform-core/xwiki-platform-xclass/xwiki-platform-xclass-test/xwiki-platform-xclass-test-docker/src/test/resources/contentDisplayer.wiki @@ -0,0 +1,11 @@ +{{velocity}} +#if ($type == 'edit') + {{html clean="false"}} + <textarea name="content">$!escapetool.xml($tdoc.content)</textarea> + {{/html}} +#elseif ("$!type" != '') + {{include reference="" /}} +#else + The display mode is not specified! +#end +{{/velocity}} \ No newline at end of file diff --git a/xwiki-platform-core/xwiki-platform-xclass/xwiki-platform-xclass-ui/src/main/resources/XWiki/ObjectSheet.xml b/xwiki-platform-core/xwiki-platform-xclass/xwiki-platform-xclass-ui/src/main/resources/XWiki/ObjectSheet.xml index 528321ccf33..18eed82bfe2 100644 --- a/xwiki-platform-core/xwiki-platform-xclass/xwiki-platform-xclass-ui/src/main/resources/XWiki/ObjectSheet.xml +++ b/xwiki-platform-core/xwiki-platform-xclass/xwiki-platform-xclass-ui/src/main/resources/XWiki/ObjectSheet.xml @@ -60,7 +60,7 @@ #foreach ($property in $xclass.properties) <dt #if (!$editing && $hasEdit) class="editableProperty" - #set ($xobjectPropertyReference = $xobject.getProperty($property.name).reference) + #set ($xobjectPropertyReference = $xobject.getPropertyReference($property.name)) data-property="$escapetool.xml($services.model.serialize($xobjectPropertyReference))" data-property-type="object"#end> ## This must match the id generated by the $doc.display() method below. -- GitLab