diff --git a/.circleci/config.yml b/.circleci/config.yml
index e8650d11..5bc5af0b 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -24,6 +24,11 @@ commands:
sudo apt install -y openjdk-17-jdk
sudo rm /etc/alternatives/java
sudo ln -s /usr/lib/jvm/java-17-openjdk-amd64/bin/java /etc/alternatives/java
+ - run:
+ name: Install html2text
+ command: |
+ sudo apt-get update
+ sudo apt-get install -y html2text
mvn_verify:
steps:
@@ -59,6 +64,10 @@ commands:
when: always
- store_test_results:
path: ~/test-results
+ - find_untested_classes:
+ name: Find Un-tested Classes
+ command: |
+ for i in */target/site/jacoco/*/index.html; do html2text -width 500 -nobs $i | sed '1,/^Total/d;' | grep -v Created | sed 's/ \+/ /g' | sed 's/ [[:digit:]]$//' | grep -v 0$ | cut -d' ' -f1; done
- save_cache:
paths:
- ~/.m2
diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/DefaultWidgetRendererTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/DefaultWidgetRendererTest.java
new file mode 100644
index 00000000..283c6c15
--- /dev/null
+++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/DefaultWidgetRendererTest.java
@@ -0,0 +1,52 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2023. 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 .
+ */
+
+package com.kingsrook.qqq.backend.core.actions.dashboard.widgets;
+
+
+import com.kingsrook.qqq.backend.core.exceptions.QException;
+import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetInput;
+import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetOutput;
+import com.kingsrook.qqq.backend.core.model.dashboard.widgets.WidgetType;
+import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaData;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+
+/*******************************************************************************
+ ** Unit test for DefaultWidgetRenderer
+ *******************************************************************************/
+class DefaultWidgetRendererTest
+{
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ @Test
+ void test() throws QException
+ {
+ RenderWidgetInput input = new RenderWidgetInput();
+ input.setWidgetMetaData(new QWidgetMetaData().withType(WidgetType.PIE_CHART.getType()));
+ RenderWidgetOutput output = new DefaultWidgetRenderer().render(input);
+ assertEquals(WidgetType.PIE_CHART.getType(), output.getWidgetData().getType());
+ }
+
+}
\ No newline at end of file
diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/DividerWidgetRendererTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/DividerWidgetRendererTest.java
new file mode 100644
index 00000000..3352f496
--- /dev/null
+++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/DividerWidgetRendererTest.java
@@ -0,0 +1,46 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2023. 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 .
+ */
+
+package com.kingsrook.qqq.backend.core.actions.dashboard.widgets;
+
+
+import com.kingsrook.qqq.backend.core.BaseTest;
+import com.kingsrook.qqq.backend.core.exceptions.QException;
+import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetInput;
+import org.junit.jupiter.api.Test;
+
+
+/*******************************************************************************
+ ** Unit test for com.kingsrook.qqq.backend.core.actions.dashboard.widgets.DividerWidgetRenderer
+ *******************************************************************************/
+class DividerWidgetRendererTest extends BaseTest
+{
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ @Test
+ void test() throws QException
+ {
+ new DividerWidgetRenderer().render(new RenderWidgetInput());
+ }
+
+}
\ No newline at end of file
diff --git a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinImplementation.java b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinImplementation.java
index 7bea3ccc..5bc7823f 100644
--- a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinImplementation.java
+++ b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinImplementation.java
@@ -57,6 +57,7 @@ import com.kingsrook.qqq.backend.core.actions.values.SearchPossibleValueSourceAc
import com.kingsrook.qqq.backend.core.adapters.QInstanceAdapter;
import com.kingsrook.qqq.backend.core.context.QContext;
import com.kingsrook.qqq.backend.core.exceptions.QAuthenticationException;
+import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.exceptions.QInstanceValidationException;
import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException;
import com.kingsrook.qqq.backend.core.exceptions.QNotFoundException;
@@ -333,6 +334,7 @@ public class QJavalinImplementation
get("/export/{filename}", QJavalinImplementation::dataExportWithFilename);
post("/export/{filename}", QJavalinImplementation::dataExportWithFilename);
get("/possibleValues/{fieldName}", QJavalinImplementation::possibleValues);
+ post("/possibleValues/{fieldName}", QJavalinImplementation::possibleValues);
// todo - add put and/or patch at this level (without a primaryKey) to do a bulk update based on primaryKeys in the records.
path("/{primaryKey}", () ->
@@ -1255,10 +1257,8 @@ public class QJavalinImplementation
{
try
{
- String tableName = context.pathParam("table");
- String fieldName = context.pathParam("fieldName");
- String searchTerm = context.queryParam("searchTerm");
- String ids = context.queryParam("ids");
+ String tableName = context.pathParam("table");
+ String fieldName = context.pathParam("fieldName");
QTableMetaData table = qInstance.getTable(tableName);
if(table == null)
@@ -1281,22 +1281,7 @@ public class QJavalinImplementation
throw (new QNotFoundException("Field " + fieldName + " in table " + tableName + " is not associated with a possible value source."));
}
- SearchPossibleValueSourceInput input = new SearchPossibleValueSourceInput();
- setupSession(context, input);
- input.setPossibleValueSourceName(field.getPossibleValueSourceName());
- input.setSearchTerm(searchTerm);
-
- if(StringUtils.hasContent(ids))
- {
- List idList = new ArrayList<>(Arrays.asList(ids.split(",")));
- input.setIdList(idList);
- }
-
- SearchPossibleValueSourceOutput output = new SearchPossibleValueSourceAction().execute(input);
-
- Map result = new HashMap<>();
- result.put("options", output.getResults());
- context.result(JsonUtils.toJson(result));
+ finishPossibleValuesRequest(context, field);
}
catch(Exception e)
{
@@ -1306,6 +1291,51 @@ public class QJavalinImplementation
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ static void finishPossibleValuesRequest(Context context, QFieldMetaData field) throws IOException, QException
+ {
+ String searchTerm = context.queryParam("searchTerm");
+ String ids = context.queryParam("ids");
+
+ Map values = new HashMap<>();
+ if(context.formParamMap().containsKey("values"))
+ {
+ List valuesParamList = context.formParamMap().get("values");
+ if(CollectionUtils.nullSafeHasContents(valuesParamList))
+ {
+ String valuesParam = valuesParamList.get(0);
+ values = JsonUtils.toObject(valuesParam, Map.class);
+ }
+ }
+
+ SearchPossibleValueSourceInput input = new SearchPossibleValueSourceInput();
+ setupSession(context, input);
+ input.setPossibleValueSourceName(field.getPossibleValueSourceName());
+ input.setSearchTerm(searchTerm);
+
+ if(field.getPossibleValueSourceFilter() != null)
+ {
+ field.getPossibleValueSourceFilter().interpretValues(values);
+ input.setDefaultQueryFilter(field.getPossibleValueSourceFilter());
+ }
+
+ if(StringUtils.hasContent(ids))
+ {
+ List idList = new ArrayList<>(Arrays.asList(ids.split(",")));
+ input.setIdList(idList);
+ }
+
+ SearchPossibleValueSourceOutput output = new SearchPossibleValueSourceAction().execute(input);
+
+ Map result = new HashMap<>();
+ result.put("options", output.getResults());
+ context.result(JsonUtils.toJson(result));
+ }
+
+
+
/*******************************************************************************
**
*******************************************************************************/
diff --git a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinProcessHandler.java b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinProcessHandler.java
index 08205cdf..84d97ffc 100644
--- a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinProcessHandler.java
+++ b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinProcessHandler.java
@@ -50,7 +50,6 @@ import com.kingsrook.qqq.backend.core.actions.processes.RunProcessAction;
import com.kingsrook.qqq.backend.core.actions.reporting.GenerateReportAction;
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
import com.kingsrook.qqq.backend.core.actions.values.QValueFormatter;
-import com.kingsrook.qqq.backend.core.actions.values.SearchPossibleValueSourceAction;
import com.kingsrook.qqq.backend.core.exceptions.QNotFoundException;
import com.kingsrook.qqq.backend.core.exceptions.QPermissionDeniedException;
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
@@ -66,8 +65,6 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
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.values.SearchPossibleValueSourceInput;
-import com.kingsrook.qqq.backend.core.model.actions.values.SearchPossibleValueSourceOutput;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
@@ -749,19 +746,6 @@ public class QJavalinProcessHandler
{
String processName = context.pathParam("processName");
String fieldName = context.pathParam("fieldName");
- String searchTerm = context.queryParam("searchTerm");
- String ids = context.queryParam("ids");
-
- Map values = new HashMap<>();
- if(context.formParamMap().containsKey("values"))
- {
- List valuesParamList = context.formParamMap().get("values");
- if(CollectionUtils.nullSafeHasContents(valuesParamList))
- {
- String valuesParam = valuesParamList.get(0);
- values = JsonUtils.toObject(valuesParam, Map.class);
- }
- }
QProcessMetaData process = QJavalinImplementation.qInstance.getProcess(processName);
if(process == null)
@@ -777,28 +761,7 @@ public class QJavalinProcessHandler
throw (new QNotFoundException("Field " + fieldName + " in process " + processName + " is not associated with a possible value source."));
}
- SearchPossibleValueSourceInput input = new SearchPossibleValueSourceInput();
- QJavalinImplementation.setupSession(context, input);
- input.setPossibleValueSourceName(field.getPossibleValueSourceName());
- input.setSearchTerm(searchTerm);
-
- if(field.getPossibleValueSourceFilter() != null)
- {
- field.getPossibleValueSourceFilter().interpretValues(values);
- input.setDefaultQueryFilter(field.getPossibleValueSourceFilter());
- }
-
- if(StringUtils.hasContent(ids))
- {
- List idList = new ArrayList<>(Arrays.asList(ids.split(",")));
- input.setIdList(idList);
- }
-
- SearchPossibleValueSourceOutput output = new SearchPossibleValueSourceAction().execute(input);
-
- Map result = new HashMap<>();
- result.put("options", output.getResults());
- context.result(JsonUtils.toJson(result));
+ QJavalinImplementation.finishPossibleValuesRequest(context, field);
}
catch(Exception e)
{