From 188efcdde7a2822bc12f1eae8cbeffd1ae220e18 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Thu, 29 Feb 2024 13:01:23 +0100 Subject: [PATCH 1/3] XWIKI-20632: Page searched by its exact name is not found in a page picker for a macro parameter when its subtree is larger than 10 pages * Search only in the actual page name, not in the space hierarchy. --- .../rest/internal/resources/BaseSearchResult.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/xwiki-platform-core/xwiki-platform-rest/xwiki-platform-rest-server/src/main/java/org/xwiki/rest/internal/resources/BaseSearchResult.java b/xwiki-platform-core/xwiki-platform-rest/xwiki-platform-rest-server/src/main/java/org/xwiki/rest/internal/resources/BaseSearchResult.java index b5436c462faa..beccb7f860a1 100644 --- a/xwiki-platform-core/xwiki-platform-rest/xwiki-platform-rest-server/src/main/java/org/xwiki/rest/internal/resources/BaseSearchResult.java +++ b/xwiki-platform-core/xwiki-platform-rest/xwiki-platform-rest-server/src/main/java/org/xwiki/rest/internal/resources/BaseSearchResult.java @@ -175,14 +175,20 @@ protected List searchPages(List searchScopes, String .equals("space")) ? "" : ", doc." + orderField; } + String addSpace = ""; + if (searchScopes.contains(SearchScope.NAME)) { + // Join the space to get the last space name. + addSpace = "left join XWikiSpace as space on doc.space = space.reference"; + } + if (space != null) { f.format("select distinct doc.fullName, doc.space, doc.name, doc.language"); f.format(addColumn); - f.format(" from XWikiDocument as doc where doc.space = :space and ( "); + f.format(" from XWikiDocument as doc %s where doc.space = :space and ( ", addSpace); } else { f.format("select distinct doc.fullName, doc.space, doc.name, doc.language"); f.format(addColumn); - f.format(" from XWikiDocument as doc where ( "); + f.format(" from XWikiDocument as doc %s where ( ", addSpace); } /* Look for scopes related to pages */ @@ -196,8 +202,8 @@ protected List searchPages(List searchScopes, String acceptedScopes++; break; case NAME: - String matchTerminalPage = "doc.name <> :defaultDocName and upper(doc.fullName) like :keywords"; - String matchNestedPage = "doc.name = :defaultDocName and upper(doc.space) like :keywords"; + String matchTerminalPage = "doc.name <> :defaultDocName and upper(doc.name) like :keywords"; + String matchNestedPage = "doc.name = :defaultDocName and upper(space.name) like :keywords"; f.format("((%s) or (%s)) ", matchTerminalPage, matchNestedPage); acceptedScopes++; break; From ea97599cde03cf3c2bd3e52f28c19dfb57f67889 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Fri, 1 Mar 2024 14:59:24 +0100 Subject: [PATCH 2/3] XWIKI-20632: Page searched by its exact name is not found in a page picker for a macro parameter when its subtree is larger than 10 pages * Add tests. --- .../flamingo/test/docker/PagePickerIT.java | 47 +++++++++++++++++-- .../org/xwiki/rest/test/WikisResourceIT.java | 44 +++++++++++++++++ 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/it/org/xwiki/flamingo/test/docker/PagePickerIT.java b/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/it/org/xwiki/flamingo/test/docker/PagePickerIT.java index 0421f477acfc..e0da0e4f89c4 100644 --- a/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/it/org/xwiki/flamingo/test/docker/PagePickerIT.java +++ b/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/it/org/xwiki/flamingo/test/docker/PagePickerIT.java @@ -19,14 +19,19 @@ */ package org.xwiki.flamingo.test.docker; +import java.util.List; + import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; +import org.xwiki.model.reference.DocumentReference; 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.SuggestInputElement; +import static org.junit.jupiter.api.Assertions.assertEquals; + /** * Functional tests for the Page Picker. * @@ -35,6 +40,8 @@ @UITest class PagePickerIT { + private static final String PICKER_ID = "pagePickerTest"; + /** * See XWIKI-16078: Selected (and deleted) users/subgroups are not displayed properly in drop-down when editing a * group @@ -45,12 +52,12 @@ void unselectingAPageDoesNotRemoveItFromSuggestions(TestUtils setup, TestReferen { setup.loginAsSuperAdmin(); String pageName = reference.getLastSpaceReference().getName(); - setup.createPage(reference, - "{{velocity}}{{html}}#pagePicker({'id': 'pagePickerTest', 'multiple': true}){{/html}}{{/velocity}}", + setup.createPage(reference, String.format( + "{{velocity}}{{html}}#pagePicker({'id': '%s', 'multiple': true}){{/html}}{{/velocity}}", PICKER_ID), pageName); SuggestInputElement pagePicker = - new SuggestInputElement(setup.getDriver().findElementWithoutWaiting(By.id("pagePickerTest"))); + new SuggestInputElement(setup.getDriver().findElementWithoutWaiting(By.id(PICKER_ID))); // Make sure the picker is ready. TODO: remove once XWIKI-19056 is closed. pagePicker.click().waitForSuggestions(); @@ -59,4 +66,38 @@ void unselectingAPageDoesNotRemoveItFromSuggestions(TestUtils setup, TestReferen pagePicker.clearSelectedSuggestions().sendKeys(pageName.substring(0, 3)).waitForSuggestions() .selectByVisibleText(pageName); } + + /** + * Verify that spaces can be selected even if they contain many children. + */ + @Test + @Order(2) + void selectSpaceWithManyChildren(TestUtils setup, TestReference reference) throws Exception + { + setup.loginAsSuperAdmin(); + + String childName = "Child"; + for (int i = 0; i < 20; i++) { + DocumentReference childReference = new DocumentReference(childName + i, + reference.getLastSpaceReference()); + setup.createPage(childReference, "Test page " + i, "Child page " + i); + } + + String pageName = reference.getLastSpaceReference().getName(); + setup.createPage(reference, + String.format("{{velocity}}{{html}}#pagePicker({'id': '%s'}){{/html}}{{/velocity}}", PICKER_ID), + pageName); + + SuggestInputElement pagePicker = + new SuggestInputElement(setup.getDriver().findElementWithoutWaiting(By.id(PICKER_ID))); + + // Search for the space and ensure that we get it (and just that space, not any of the children). + List suggestions = + pagePicker.sendKeys(pageName).waitForSuggestions().getSuggestions(); + assertEquals(1, suggestions.size()); + assertEquals(pageName, suggestions.get(0).getLabel()); + // Just to be sure that searching for the children also works, search and select the first child. + pagePicker.clear().sendKeys(childName).waitForSuggestions() + .selectByVisibleText("Child page 0"); + } } diff --git a/xwiki-platform-core/xwiki-platform-rest/xwiki-platform-rest-test/xwiki-platform-rest-test-tests/src/test/it/org/xwiki/rest/test/WikisResourceIT.java b/xwiki-platform-core/xwiki-platform-rest/xwiki-platform-rest-test/xwiki-platform-rest-test-tests/src/test/it/org/xwiki/rest/test/WikisResourceIT.java index 6225dee18dc9..a0fbe065dbfd 100644 --- a/xwiki-platform-core/xwiki-platform-rest/xwiki-platform-rest-test/xwiki-platform-rest-test-tests/src/test/it/org/xwiki/rest/test/WikisResourceIT.java +++ b/xwiki-platform-core/xwiki-platform-rest/xwiki-platform-rest-test/xwiki-platform-rest-test-tests/src/test/it/org/xwiki/rest/test/WikisResourceIT.java @@ -24,6 +24,7 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.GetMethod; @@ -60,6 +61,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; public class WikisResourceIT extends AbstractHttpIT { @@ -117,6 +119,48 @@ public void testRepresentation() throws Exception } } + @Test + public void testSearchWikisName() throws Exception + { + this.testUtils.rest().delete(reference); + this.testUtils.rest().savePage(reference, "Name Content", "Name Title " + this.pageName); + + GetMethod getMethod = executeGet( + String.format("%s?scope=name&q=" + this.pageName, buildURI(WikiSearchResource.class, getWiki()))); + SearchResults searchResults = (SearchResults) unmarshaller.unmarshal(getMethod.getResponseBodyAsStream()); + + // Ensure that the terminal page is found by its name. + int resultSize = searchResults.getSearchResults().size(); + assertEquals(1, resultSize); + assertEquals(this.fullName, searchResults.getSearchResults().get(0).getPageFullName()); + + // Create a non-terminal page with the same "name" but this time as last space. + List nonTerminalSpaces = List.of(this.spaces.get(0), this.pageName); + DocumentReference nonTerminalReference = new DocumentReference(this.wikiName, nonTerminalSpaces, "WebHome"); + String nonTerminalFullName = String.join(".", nonTerminalSpaces) + "." + "WebHome"; + this.testUtils.rest().savePage(nonTerminalReference, "content2" + this.pageName, "title2" + this.pageName); + + getMethod = executeGet( + String.format("%s?scope=name&q=" + this.pageName, buildURI(WikiSearchResource.class, getWiki()))); + searchResults = (SearchResults) unmarshaller.unmarshal(getMethod.getResponseBodyAsStream()); + + // Ensure that searching by name finds both terminal and non-terminal page. + resultSize = searchResults.getSearchResults().size(); + assertEquals(2, resultSize); + List foundPages = searchResults.getSearchResults().stream() + .map(SearchResult::getPageFullName) + .collect(Collectors.toList()); + assertTrue(foundPages.contains(this.fullName)); + assertTrue(foundPages.contains(nonTerminalFullName)); + + // Ensure that searching by space finds neither the terminal nor the non-terminal page. + getMethod = + executeGet(String.format("%s?scope=name&q=" + this.spaces.get(0), + buildURI(WikiSearchResource.class, getWiki()))); + searchResults = (SearchResults) unmarshaller.unmarshal(getMethod.getResponseBodyAsStream()); + assertEquals(0, searchResults.getSearchResults().size()); + } + @Test public void testSearchWikis() throws Exception { From 973f7b83a7f731d89a10cac4080fef71cbc4817d Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Fri, 1 Mar 2024 15:13:11 +0100 Subject: [PATCH 3/3] XWIKI-20632: Page searched by its exact name is not found in a page picker for a macro parameter when its subtree is larger than 10 pages * Reduce the number of pages created in the test. --- .../test/it/org/xwiki/flamingo/test/docker/PagePickerIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/it/org/xwiki/flamingo/test/docker/PagePickerIT.java b/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/it/org/xwiki/flamingo/test/docker/PagePickerIT.java index e0da0e4f89c4..5f6b7a19ac48 100644 --- a/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/it/org/xwiki/flamingo/test/docker/PagePickerIT.java +++ b/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/it/org/xwiki/flamingo/test/docker/PagePickerIT.java @@ -77,7 +77,7 @@ void selectSpaceWithManyChildren(TestUtils setup, TestReference reference) throw setup.loginAsSuperAdmin(); String childName = "Child"; - for (int i = 0; i < 20; i++) { + for (int i = 0; i < 11; i++) { DocumentReference childReference = new DocumentReference(childName + i, reference.getLastSpaceReference()); setup.createPage(childReference, "Test page " + i, "Child page " + i);