Fix bug w/ filter in URL not having any values not being respected. Add selenium test for it!!

This commit is contained in:
2023-07-26 12:39:58 -05:00
parent cd7e6b8db1
commit f189083a5a
3 changed files with 204 additions and 4 deletions

View File

@ -449,12 +449,15 @@ class FilterUtils
//////////////////////////////////////////////////////////////////////////
// replace objects that look like expressions with expression instances //
//////////////////////////////////////////////////////////////////////////
for(let i = 0; i < values.length; i++)
if(values && values.length)
{
const expression = this.gridCriteriaValueToExpression(values[i])
if(expression)
for (let i = 0; i < values.length; i++)
{
values[i] = expression;
const expression = this.gridCriteriaValueToExpression(values[i])
if (expression)
{
values[i] = expression;
}
}
}

View File

@ -0,0 +1,185 @@
/*
* QQQ - Low-code Application Framework for Engineers.
* Copyright (C) 2021-2022. Kingsrook, LLC
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
* contact@kingsrook.com
* https://github.com/Kingsrook/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.kingsrook.qqq.materialdashboard.tests;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.temporal.ChronoUnit;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.expressions.NowWithOffset;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.expressions.ThisOrLastPeriod;
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
import com.kingsrook.qqq.materialdashboard.lib.QBaseSeleniumTest;
import com.kingsrook.qqq.materialdashboard.lib.QQQMaterialDashboardSelectors;
import com.kingsrook.qqq.materialdashboard.lib.javalin.QSeleniumJavalin;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebElement;
/*******************************************************************************
** Test for the record query screen when a filter is given in the URL
*******************************************************************************/
public class QueryScreenFilterInUrlTest extends QBaseSeleniumTest
{
/*******************************************************************************
**
*******************************************************************************/
@Override
protected void addJavalinRoutes(QSeleniumJavalin qSeleniumJavalin)
{
super.addJavalinRoutes(qSeleniumJavalin);
qSeleniumJavalin
.withRouteToFile("/data/person/count", "data/person/count.json")
.withRouteToFile("/data/person/query", "data/person/index.json")
.withRouteToFile("/data/person/possibleValues/homeCityId", "data/person/possibleValues/homeCityId.json")
.withRouteToFile("/data/person/variants", "data/person/variants.json")
.withRouteToFile("/processes/querySavedFilter/init", "processes/querySavedFilter/init.json");
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testUrlWithFilter()
{
////////////////////////////////////////
// not-blank -- criteria w/ no values //
////////////////////////////////////////
String filterJSON = JsonUtils.toJson(new QQueryFilter()
.withCriteria(new QFilterCriteria("annualSalary", QCriteriaOperator.IS_NOT_BLANK)));
qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/peopleApp/greetingsApp/person?filter=" + URLEncoder.encode(filterJSON, StandardCharsets.UTF_8), "Person");
waitForQueryToHaveRan();
assertFilterButtonBadge(1);
clickFilterButton();
qSeleniumLib.waitForSelector("input[value=\"is not empty\"]");
///////////////////////////////
// between on a number field //
///////////////////////////////
filterJSON = JsonUtils.toJson(new QQueryFilter()
.withCriteria(new QFilterCriteria("annualSalary", QCriteriaOperator.BETWEEN, 1701, 74656)));
qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/peopleApp/greetingsApp/person?filter=" + URLEncoder.encode(filterJSON, StandardCharsets.UTF_8), "Person");
waitForQueryToHaveRan();
assertFilterButtonBadge(1);
clickFilterButton();
qSeleniumLib.waitForSelector("input[value=\"is between\"]");
qSeleniumLib.waitForSelector("input[value=\"1701\"]");
qSeleniumLib.waitForSelector("input[value=\"74656\"]");
//////////////////////////////////////////
// not-equals on a possible-value field //
//////////////////////////////////////////
filterJSON = JsonUtils.toJson(new QQueryFilter()
.withCriteria(new QFilterCriteria("homeCityId", QCriteriaOperator.NOT_EQUALS, 1)));
qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/peopleApp/greetingsApp/person?filter=" + URLEncoder.encode(filterJSON, StandardCharsets.UTF_8), "Person");
waitForQueryToHaveRan();
assertFilterButtonBadge(1);
clickFilterButton();
qSeleniumLib.waitForSelector("input[value=\"does not equal\"]");
qSeleniumLib.waitForSelector("input[value=\"St. Louis\"]");
//////////////////////////////////////
// an IN for a possible-value field //
//////////////////////////////////////
filterJSON = JsonUtils.toJson(new QQueryFilter()
.withCriteria(new QFilterCriteria("homeCityId", QCriteriaOperator.IN, 1, 2)));
qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/peopleApp/greetingsApp/person?filter=" + URLEncoder.encode(filterJSON, StandardCharsets.UTF_8), "Person");
waitForQueryToHaveRan();
assertFilterButtonBadge(1);
clickFilterButton();
qSeleniumLib.waitForSelector("input[value=\"is any of\"]");
qSeleniumLib.waitForSelectorContaining(".MuiChip-label", "St. Louis");
qSeleniumLib.waitForSelectorContaining(".MuiChip-label", "Chesterfield");
/////////////////////////////////////////
// greater than a date-time expression //
/////////////////////////////////////////
filterJSON = JsonUtils.toJson(new QQueryFilter()
.withCriteria(new QFilterCriteria("createDate", QCriteriaOperator.GREATER_THAN, NowWithOffset.minus(5, ChronoUnit.DAYS))));
qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/peopleApp/greetingsApp/person?filter=" + URLEncoder.encode(filterJSON, StandardCharsets.UTF_8), "Person");
waitForQueryToHaveRan();
assertFilterButtonBadge(1);
clickFilterButton();
qSeleniumLib.waitForSelector("input[value=\"is after\"]");
qSeleniumLib.waitForSelector("input[value=\"5 days ago\"]");
///////////////////////
// multiple criteria //
///////////////////////
filterJSON = JsonUtils.toJson(new QQueryFilter()
.withCriteria(new QFilterCriteria("firstName", QCriteriaOperator.STARTS_WITH, "Dar"))
.withCriteria(new QFilterCriteria("createDate", QCriteriaOperator.LESS_THAN_OR_EQUALS, ThisOrLastPeriod.this_(ChronoUnit.YEARS))));
qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/peopleApp/greetingsApp/person?filter=" + URLEncoder.encode(filterJSON, StandardCharsets.UTF_8), "Person");
waitForQueryToHaveRan();
assertFilterButtonBadge(2);
clickFilterButton();
qSeleniumLib.waitForSelector("input[value=\"is at or before\"]");
qSeleniumLib.waitForSelector("input[value=\"start of this year\"]");
qSeleniumLib.waitForSelector("input[value=\"starts with\"]");
qSeleniumLib.waitForSelector("input[value=\"Dar\"]");
////////////////
// remove one //
////////////////
qSeleniumLib.waitForSelectorContaining(".MuiIcon-root", "close").click();
assertFilterButtonBadge(1);
qSeleniumLib.waitForever();
}
/*******************************************************************************
**
*******************************************************************************/
private WebElement assertFilterButtonBadge(int valueInBadge)
{
return qSeleniumLib.waitForSelectorContaining(".MuiBadge-root", String.valueOf(valueInBadge));
}
/*******************************************************************************
**
*******************************************************************************/
private WebElement waitForQueryToHaveRan()
{
return qSeleniumLib.waitForSelector(QQQMaterialDashboardSelectors.QUERY_GRID_CELL);
}
/*******************************************************************************
**
*******************************************************************************/
private void clickFilterButton()
{
qSeleniumLib.waitForSelectorContaining(".MuiDataGrid-toolbarContainer BUTTON", "Filter").click();
}
}

View File

@ -0,0 +1,12 @@
{
"options": [
{
"id": 1,
"label": "St. Louis"
},
{
"id": 2,
"label": "Chesterfield"
}
]
}