From 5fcb0aa4b58566067a53cf7f40c6baecdf2b5f71 Mon Sep 17 00:00:00 2001
From: Simon Urli <simon.urli@xwiki.com>
Date: Mon, 3 Jun 2024 14:49:55 +0200
Subject: [PATCH] XWIKI-22208: Boolean filters are not properly removed in
 LiveData

  * Ensure to remove the boolean filter properly like we do for list
    filters
  * Improve Page Object to select all kind of filters (input or select)
  * Ensure to cover manipulating boolean filters in integration test

(cherry picked from commit 0487a5962b4735ac3544ee1fb8885a130c5f284e)
---
 .../xwiki/livedata/test/ui/LiveDataIT.java    | 49 ++++++++++++++++---
 .../livedata/test/po/TableLayoutElement.java  |  6 ++-
 .../src/main/vue/filters/FilterBoolean.vue    |  5 +-
 3 files changed, 50 insertions(+), 10 deletions(-)

diff --git a/xwiki-platform-core/xwiki-platform-livedata/xwiki-platform-livedata-test/xwiki-platform-livedata-test-docker/src/test/it/org/xwiki/livedata/test/ui/LiveDataIT.java b/xwiki-platform-core/xwiki-platform-livedata/xwiki-platform-livedata-test/xwiki-platform-livedata-test-docker/src/test/it/org/xwiki/livedata/test/ui/LiveDataIT.java
index 17a444950df..42ab7b4d8e7 100644
--- a/xwiki-platform-core/xwiki-platform-livedata/xwiki-platform-livedata-test/xwiki-platform-livedata-test-docker/src/test/it/org/xwiki/livedata/test/ui/LiveDataIT.java
+++ b/xwiki-platform-core/xwiki-platform-livedata/xwiki-platform-livedata-test/xwiki-platform-livedata-test-docker/src/test/it/org/xwiki/livedata/test/ui/LiveDataIT.java
@@ -102,6 +102,11 @@ class LiveDataIT
 
     private static final String CANCELED_BIRTHDAY_DATETIME = "11/05/2021 16:00:10";
 
+    private static final String IS_ACTIVE_COLUMN = "isActive";
+
+    private static final String YES = "Yes";
+    private static final String NO = "No";
+
     private static final String DOC_TITLE_COLUMN = "doc.title";
 
     private static final String FOOTNOTE_COMPUTED_TITLE =
@@ -131,7 +136,8 @@ void livedataLivetableTableLayout(TestUtils testUtils, TestReference testReferen
         initLocalization(testUtils, testReference);
 
         // Initializes the page content.
-        List<String> properties = List.of(NAME_COLUMN, CHOICE_COLUMN, BIRTHDAY_COLUMN, USER_COLUMN, DOC_TITLE_COLUMN);
+        List<String> properties =
+            List.of(NAME_COLUMN, CHOICE_COLUMN, BIRTHDAY_COLUMN, USER_COLUMN, IS_ACTIVE_COLUMN, DOC_TITLE_COLUMN);
         createClassNameLiveDataPage(testUtils, testReference, properties, "");
 
         // Creates the XClass.
@@ -170,6 +176,8 @@ void livedataLivetableTableLayout(TestUtils testUtils, TestReference testReferen
         tableLayout.assertRow(CHOICE_COLUMN, CHOICE_B);
         tableLayout.assertRow(CHOICE_COLUMN, CHOICE_C);
         tableLayout.assertRow(BIRTHDAY_COLUMN, BIRTHDAY_DATETIME);
+        tableLayout.assertRow(IS_ACTIVE_COLUMN, YES);
+        tableLayout.assertRow(IS_ACTIVE_COLUMN, NO);
         // The canceled birthday date shouldn't appear on the table since it has been canceled. 
         tableLayout
             .assertRow(BIRTHDAY_COLUMN, not(hasItem(tableLayout.getWebElementTextMatcher(CANCELED_BIRTHDAY_DATETIME))));
@@ -234,6 +242,33 @@ void livedataLivetableTableLayout(TestUtils testUtils, TestReference testReferen
         assertEquals(1, suggestionElements.size());
         assertEquals(CHOICE_T, suggestionElements.get(0).getValue());
         assertEquals(CHOICE_T_TRANSLATION, suggestionElements.get(0).getLabel());
+
+        // Test filter on boolean values
+        suggestInputElement.clear().hideSuggestions();
+        assertEquals(2, tableLayout.countRows());
+
+        // Take the focus on the is active filter.
+        suggestInputElement = new SuggestInputElement(tableLayout.getFilter(IS_ACTIVE_COLUMN));
+        suggestInputElement.sendKeys(Boolean.TRUE.toString());
+        suggestInputElement.waitForSuggestions();
+        suggestionElements = suggestInputElement.getSuggestions();
+        assertEquals(1, suggestionElements.size());
+        suggestionElements.get(0).select();
+        assertEquals(1, tableLayout.countRows());
+        tableLayout.assertRow(NAME_COLUMN, NAME_LYNDA);
+
+        suggestInputElement.clear();
+        suggestInputElement.sendKeys(Boolean.FALSE.toString());
+        suggestInputElement.waitForSuggestions();
+        suggestionElements = suggestInputElement.getSuggestions();
+        assertEquals(1, suggestionElements.size());
+        suggestionElements.get(0).select();
+        assertEquals(1, tableLayout.countRows());
+        tableLayout.assertRow(NAME_COLUMN, NAME_NIKOLAY);
+
+        suggestInputElement.clear().hideSuggestions();
+        liveDataElement.waitUntilReady();
+        assertEquals(2, tableLayout.countRows());
     }
 
     private void createXObjects(TestUtils testUtils, TestReference testReference)
@@ -241,17 +276,15 @@ private void createXObjects(TestUtils testUtils, TestReference testReference)
         String className = testUtils.serializeReference(testReference);
         DocumentReference o1 = new DocumentReference("O1", (SpaceReference) testReference.getParent());
         testUtils.createPage(o1, "", "O1");
-        addXObject(testUtils, o1, className,
-            NAME_LYNDA, CHOICE_A, "U1");
+        addXObject(testUtils, o1, className, NAME_LYNDA, CHOICE_A, "U1", true);
         DocumentReference o2 = new DocumentReference("O2", (SpaceReference) testReference.getParent());
         // Make 02 not viewable by guests to test the footnotes.
         testUtils.setRights(o2, null, "XWiki.XWikiGuest", "view", false);
-        addXObject(testUtils, o2, className,
-            NAME_ESTHER, CHOICE_B, "U2");
+        addXObject(testUtils, o2, className, NAME_ESTHER, CHOICE_B, "U2", false);
         DocumentReference o3 = new DocumentReference("O3", (SpaceReference) testReference.getParent());
         // Set a localized title on O3 to test the footnotes.
         testUtils.createPage(o3, "", "$services.localization.render('computedTitle')");
-        addXObject(testUtils, o3, className, NAME_NIKOLAY, "", null);
+        addXObject(testUtils, o3, className, NAME_NIKOLAY, "", null, false);
     }
 
     /**
@@ -346,7 +379,7 @@ private void initLocalization(TestUtils testUtils, TestReference testReference)
      * @param username the username of the user field (e.g., {@code "U1"})
      */
     private void addXObject(TestUtils testUtils, DocumentReference documentReference, String className, String name,
-        String choice, String username)
+        String choice, String username, boolean isActive)
     {
         Map<String, Object> properties = new HashMap<>();
         properties.put(NAME_COLUMN, name);
@@ -354,6 +387,7 @@ private void addXObject(TestUtils testUtils, DocumentReference documentReference
         if (username != null) {
             properties.put(USER_COLUMN, "XWiki." + username);
         }
+        properties.put(IS_ACTIVE_COLUMN, isActive);
         testUtils.addObject(documentReference, className, properties);
     }
 
@@ -376,6 +410,7 @@ private void createXClass(TestUtils testUtils, TestReference testReference)
         classEditPage.clickSaveAndView();
         testUtils.addClassProperty(testReference, BIRTHDAY_COLUMN, "Date");
         testUtils.addClassProperty(testReference, USER_COLUMN, "Users");
+        testUtils.addClassProperty(testReference, IS_ACTIVE_COLUMN, "Boolean");
     }
 
     private static void createClassNameLiveDataPage(TestUtils testUtils, TestReference testReference,
diff --git a/xwiki-platform-core/xwiki-platform-livedata/xwiki-platform-livedata-test/xwiki-platform-livedata-test-pageobjects/src/main/java/org/xwiki/livedata/test/po/TableLayoutElement.java b/xwiki-platform-core/xwiki-platform-livedata/xwiki-platform-livedata-test/xwiki-platform-livedata-test-pageobjects/src/main/java/org/xwiki/livedata/test/po/TableLayoutElement.java
index f8913aa42a0..f33d9fd7f74 100644
--- a/xwiki-platform-core/xwiki-platform-livedata/xwiki-platform-livedata-test/xwiki-platform-livedata-test-pageobjects/src/main/java/org/xwiki/livedata/test/po/TableLayoutElement.java
+++ b/xwiki-platform-core/xwiki-platform-livedata/xwiki-platform-livedata-test/xwiki-platform-livedata-test-pageobjects/src/main/java/org/xwiki/livedata/test/po/TableLayoutElement.java
@@ -678,8 +678,10 @@ public int getRowIndexForElement(By by)
     public WebElement getFilter(String columnLabel)
     {
         int columnIndex = findColumnIndex(columnLabel);
-        return getRoot()
-            .findElement(By.cssSelector(String.format(".column-filters > th:nth-child(%d) input", columnIndex)));
+        By cssSelector = By.cssSelector(String.format(
+            ".column-filters > th:nth-child(%1$d) input.livedata-filter, "
+            + ".column-filters > th:nth-child(%1$d) select.livedata-filter", columnIndex));
+        return getRoot().findElement(cssSelector);
     }
 
     /**
diff --git a/xwiki-platform-core/xwiki-platform-livedata/xwiki-platform-livedata-webjar/src/main/vue/filters/FilterBoolean.vue b/xwiki-platform-core/xwiki-platform-livedata/xwiki-platform-livedata-webjar/src/main/vue/filters/FilterBoolean.vue
index 678de0c739a..33217cf60e8 100644
--- a/xwiki-platform-core/xwiki-platform-livedata/xwiki-platform-livedata-webjar/src/main/vue/filters/FilterBoolean.vue
+++ b/xwiki-platform-core/xwiki-platform-livedata/xwiki-platform-livedata-webjar/src/main/vue/filters/FilterBoolean.vue
@@ -57,7 +57,10 @@ export default {
 
   watch: {
     filterValue(newValue, oldValue) {
-      if (newValue !== oldValue) {
+      if (this.$refs.input.selectize.items.length === 0) {
+        // When no values are selected, simply remove the filter.
+        this.removeFilter();
+      } else if (newValue !== oldValue) {
         $(this.$refs.input).val(newValue).trigger('change');
         this.applyFilter(newValue);
       }
-- 
GitLab