CE-881 - Formalize savedReport.columnsJSON as a ReportColumns class.

This commit is contained in:
2024-03-29 09:06:16 -05:00
parent 52b64ffbc0
commit 5384eb9927
6 changed files with 312 additions and 105 deletions

View File

@ -0,0 +1,98 @@
/*
* QQQ - Low-code Application Framework for Engineers.
* Copyright (C) 2021-2024. 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.backend.core.model.savedreports;
import java.io.Serializable;
/*******************************************************************************
** single entry in ReportColumns object - as part of SavedReport
*******************************************************************************/
public class ReportColumn implements Serializable
{
private String name;
private Boolean isVisible;
/*******************************************************************************
** Getter for name
*******************************************************************************/
public String getName()
{
return (this.name);
}
/*******************************************************************************
** Setter for name
*******************************************************************************/
public void setName(String name)
{
this.name = name;
}
/*******************************************************************************
** Fluent setter for name
*******************************************************************************/
public ReportColumn withName(String name)
{
this.name = name;
return (this);
}
/*******************************************************************************
** Getter for isVisible
*******************************************************************************/
public Boolean getIsVisible()
{
return (this.isVisible);
}
/*******************************************************************************
** Setter for isVisible
*******************************************************************************/
public void setIsVisible(Boolean isVisible)
{
this.isVisible = isVisible;
}
/*******************************************************************************
** Fluent setter for isVisible
*******************************************************************************/
public ReportColumn withIsVisible(Boolean isVisible)
{
this.isVisible = isVisible;
return (this);
}
}

View File

@ -0,0 +1,95 @@
/*
* QQQ - Low-code Application Framework for Engineers.
* Copyright (C) 2021-2024. 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.backend.core.model.savedreports;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/*******************************************************************************
** type of object expected to be in the SavedReport columnsJSON field
*******************************************************************************/
public class ReportColumns implements Serializable
{
private List<ReportColumn> columns;
/*******************************************************************************
** Getter for columns
*******************************************************************************/
public List<ReportColumn> getColumns()
{
return (this.columns);
}
/*******************************************************************************
** Setter for columns
*******************************************************************************/
public void setColumns(List<ReportColumn> columns)
{
this.columns = columns;
}
/*******************************************************************************
** Fluent setter for columns
*******************************************************************************/
public ReportColumns withColumns(List<ReportColumn> columns)
{
this.columns = columns;
return (this);
}
/*******************************************************************************
** Fluent setter to add 1 column
*******************************************************************************/
public ReportColumns withColumn(ReportColumn column)
{
if(this.columns == null)
{
this.columns = new ArrayList<>();
}
this.columns.add(column);
return (this);
}
/*******************************************************************************
** Fluent setter to add 1 column w/ just a name
*******************************************************************************/
public ReportColumns withColumn(String name)
{
if(this.columns == null)
{
this.columns = new ArrayList<>();
}
this.columns.add(new ReportColumn().withName(name));
return (this);
}
}

View File

@ -25,9 +25,8 @@ package com.kingsrook.qqq.backend.core.processes.implementations.savedreports;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature;
import com.kingsrook.qqq.backend.core.context.QContext; import com.kingsrook.qqq.backend.core.context.QContext;
import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.logging.QLogger; import com.kingsrook.qqq.backend.core.logging.QLogger;
@ -43,12 +42,15 @@ import com.kingsrook.qqq.backend.core.model.metadata.reporting.QReportView;
import com.kingsrook.qqq.backend.core.model.metadata.reporting.ReportType; import com.kingsrook.qqq.backend.core.model.metadata.reporting.ReportType;
import com.kingsrook.qqq.backend.core.model.metadata.tables.ExposedJoin; import com.kingsrook.qqq.backend.core.model.metadata.tables.ExposedJoin;
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
import com.kingsrook.qqq.backend.core.model.savedreports.ReportColumn;
import com.kingsrook.qqq.backend.core.model.savedreports.ReportColumns;
import com.kingsrook.qqq.backend.core.model.savedreports.SavedReport; import com.kingsrook.qqq.backend.core.model.savedreports.SavedReport;
import com.kingsrook.qqq.backend.core.utils.CollectionUtils; import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
import com.kingsrook.qqq.backend.core.utils.JsonUtils; import com.kingsrook.qqq.backend.core.utils.JsonUtils;
import com.kingsrook.qqq.backend.core.utils.StringUtils; import com.kingsrook.qqq.backend.core.utils.StringUtils;
import com.kingsrook.qqq.backend.core.utils.ValueUtils; import com.kingsrook.qqq.backend.core.utils.ValueUtils;
import com.kingsrook.qqq.backend.core.utils.collections.ListBuilder; import com.kingsrook.qqq.backend.core.utils.collections.ListBuilder;
import org.apache.commons.lang.BooleanUtils;
import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair; import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
@ -73,16 +75,15 @@ public class SavedReportToReportMetaDataAdapter
QReportMetaData reportMetaData = new QReportMetaData(); QReportMetaData reportMetaData = new QReportMetaData();
reportMetaData.setLabel(savedReport.getLabel()); reportMetaData.setLabel(savedReport.getLabel());
//////////////////////////// /////////////////////////////////////////////////////
// set up the data-source // // set up the data-source - e.g., table and filter //
//////////////////////////// /////////////////////////////////////////////////////
QReportDataSource dataSource = new QReportDataSource(); QReportDataSource dataSource = new QReportDataSource();
reportMetaData.setDataSources(List.of(dataSource)); reportMetaData.setDataSources(List.of(dataSource));
dataSource.setName("main"); dataSource.setName("main");
QTableMetaData table = qInstance.getTable(savedReport.getTableName()); QTableMetaData table = qInstance.getTable(savedReport.getTableName());
dataSource.setSourceTable(savedReport.getTableName()); dataSource.setSourceTable(savedReport.getTableName());
dataSource.setQueryFilter(JsonUtils.toObject(savedReport.getQueryFilterJson(), QQueryFilter.class)); dataSource.setQueryFilter(JsonUtils.toObject(savedReport.getQueryFilterJson(), QQueryFilter.class));
////////////////////////// //////////////////////////
@ -96,69 +97,41 @@ public class SavedReportToReportMetaDataAdapter
view.setLabel(savedReport.getLabel()); // todo eh? view.setLabel(savedReport.getLabel()); // todo eh?
view.setIncludeHeaderRow(true); view.setIncludeHeaderRow(true);
// don't need: ////////////////////////////////////////////////////////////////////////////////////////////////
// view.setOrderByFields(); - only used for summary reports // columns in the saved-report should look like a serialized version of ReportColumns object //
// view.setTitleFormat(); - not using at this time // map them to a list of QReportField objects //
// view.setTitleFields(); - not using at this time // also keep track of what joinTables we find that we need to select //
// view.setRecordTransformStep(); ////////////////////////////////////////////////////////////////////////////////////////////////
// view.setViewCustomizer(); ReportColumns columnsObject = JsonUtils.toObject(savedReport.getColumnsJson(), ReportColumns.class, om -> om.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES));
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// columns in the saved-report look like a JSON object, w/ a key "columns", which is an array of objects //
///////////////////////////////////////////////////////////////////////////////////////////////////////////
Set<String> neededJoinTables = new HashSet<>();
List<QReportField> reportColumns = new ArrayList<>(); List<QReportField> reportColumns = new ArrayList<>();
view.setColumns(reportColumns); view.setColumns(reportColumns);
Map<String, Object> columnsObject = JsonUtils.toObject(savedReport.getColumnsJson(), new TypeReference<>() {}); Set<String> neededJoinTables = new HashSet<>();
List<Map<String, Object>> columns = (List<Map<String, Object>>) columnsObject.get("columns");
for(Map<String, Object> column : columns) for(ReportColumn column : columnsObject.getColumns())
{ {
if(column.containsKey("isVisible") && !"true".equals(ValueUtils.getValueAsString(column.get("isVisible")))) ////////////////////////////////////////////////////////////////////////////////////////////////////
// if isVisible is missing, we assume it to be true - so only if it isFalse do we skip the column //
////////////////////////////////////////////////////////////////////////////////////////////////////
if(BooleanUtils.isFalse(column.getIsVisible()))
{ {
continue; continue;
} }
QFieldMetaData field; ////////////////////////////////////////////////////
String fieldName = ValueUtils.getValueAsString(column.get("name")); // figure out the field being named by the column //
if(fieldName.contains(".")) ////////////////////////////////////////////////////
{ String fieldName = ValueUtils.getValueAsString(column.getName());
String joinTableName = fieldName.replaceAll("\\..*", ""); QFieldMetaData field = getField(savedReport, fieldName, qInstance, neededJoinTables, table);
String joinFieldName = fieldName.replaceAll(".*\\.", "");
QTableMetaData joinTable = qInstance.getTable(joinTableName);
if(joinTable == null)
{
LOG.warn("Saved Report has an unrecognized join table name", logPair("savedReportId", savedReport.getId()), logPair("joinTable", joinTable), logPair("fieldName", fieldName));
continue;
}
neededJoinTables.add(joinTableName);
field = joinTable.getFields().get(joinFieldName);
if(field == null) if(field == null)
{ {
LOG.warn("Saved Report has an unrecognized join field name", logPair("savedReportId", savedReport.getId()), logPair("fieldName", fieldName));
continue; continue;
} }
}
else
{
field = table.getFields().get(fieldName);
if(field == null)
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// frontend may often pass __checked__ (or maybe other __ prefixes in the future - so - don't warn that. //
///////////////////////////////////////////////////////////////////////////////////////////////////////////
if(!fieldName.startsWith("__"))
{
LOG.warn("Saved Report has an unexpected unrecognized field name", logPair("savedReportId", savedReport.getId()), logPair("table", table.getName()), logPair("fieldName", fieldName));
}
continue;
}
}
//////////////////////////////////////////////////
// make a QReportField based on the table field //
//////////////////////////////////////////////////
QReportField reportField = new QReportField(); QReportField reportField = new QReportField();
reportColumns.add(reportField); reportColumns.add(reportField);
@ -192,9 +165,8 @@ public class SavedReportToReportMetaDataAdapter
if(exposedJoin.getJoinPath().size() == 1) if(exposedJoin.getJoinPath().size() == 1)
{ {
// this is similar logic that QFMD has
////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Note, this is similar logic (and comment) in QFMD ... //
// todo - what about a join with a longer path? it would be nice to pass such joinNames through there too, // // todo - what about a join with a longer path? it would be nice to pass such joinNames through there too, //
// but what, that would actually be multiple queryJoins? needs a fair amount of thought. // // but what, that would actually be multiple queryJoins? needs a fair amount of thought. //
////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -213,7 +185,7 @@ public class SavedReportToReportMetaDataAdapter
{ {
QReportView pivotView = new QReportView(); QReportView pivotView = new QReportView();
reportMetaData.getViews().add(pivotView); reportMetaData.getViews().add(pivotView);
pivotView.setName("pivot"); // does this appear? pivotView.setName("pivot");
pivotView.setType(ReportType.PIVOT); pivotView.setType(ReportType.PIVOT);
pivotView.setPivotTableSourceViewName(view.getName()); pivotView.setPivotTableSourceViewName(view.getName());
pivotView.setPivotTableDefinition(JsonUtils.toObject(savedReport.getPivotTableJson(), PivotTableDefinition.class)); pivotView.setPivotTableDefinition(JsonUtils.toObject(savedReport.getPivotTableJson(), PivotTableDefinition.class));
@ -240,4 +212,51 @@ public class SavedReportToReportMetaDataAdapter
} }
} }
/*******************************************************************************
**
*******************************************************************************/
private static QFieldMetaData getField(SavedReport savedReport, String fieldName, QInstance qInstance, Set<String> neededJoinTables, QTableMetaData table)
{
QFieldMetaData field;
if(fieldName.contains("."))
{
String joinTableName = fieldName.replaceAll("\\..*", "");
String joinFieldName = fieldName.replaceAll(".*\\.", "");
QTableMetaData joinTable = qInstance.getTable(joinTableName);
if(joinTable == null)
{
LOG.warn("Saved Report has an unrecognized join table name", logPair("savedReportId", savedReport.getId()), logPair("joinTable", joinTable), logPair("fieldName", fieldName));
return null;
}
neededJoinTables.add(joinTableName);
field = joinTable.getFields().get(joinFieldName);
if(field == null)
{
LOG.warn("Saved Report has an unrecognized join field name", logPair("savedReportId", savedReport.getId()), logPair("fieldName", fieldName));
return null;
}
}
else
{
field = table.getFields().get(fieldName);
if(field == null)
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// frontend may often pass __checked__ (or maybe other __ prefixes in the future - so - don't warn that. //
///////////////////////////////////////////////////////////////////////////////////////////////////////////
if(!fieldName.startsWith("__"))
{
LOG.warn("Saved Report has an unexpected unrecognized field name", logPair("savedReportId", savedReport.getId()), logPair("table", table.getName()), logPair("fieldName", fieldName));
}
return null;
}
}
return field;
}
} }

View File

@ -64,19 +64,24 @@ class RenderSavedReportProcessTest extends BaseTest
String label = "Test Report"; String label = "Test Report";
//////////////////////////////////////////////////////////////////////////////////////////
// do columns json as a string, rather than a toJson'ed ReportColumns object, //
// to help verify that we don't choke on un-recognized properties (e.g., as QFMD sends) //
//////////////////////////////////////////////////////////////////////////////////////////
String columnsJson = """
{"columns":[
{"name": "k"},
{"name": "id"},
{"name": "firstName", "isVisible": true},
{"name": "lastName", "pinned": "left"},
{"name": "createDate", "isVisible": false}
]}
""";
QRecord savedReport = new InsertAction().execute(new InsertInput(SavedReport.TABLE_NAME).withRecordEntity(new SavedReport() QRecord savedReport = new InsertAction().execute(new InsertInput(SavedReport.TABLE_NAME).withRecordEntity(new SavedReport()
.withLabel(label) .withLabel(label)
.withTableName(TestUtils.TABLE_NAME_PERSON_MEMORY) .withTableName(TestUtils.TABLE_NAME_PERSON_MEMORY)
.withColumnsJson(""" .withColumnsJson(columnsJson)
{
"columns":
[
{"name": "id"},
{"name": "firstName"},
{"name": "lastName"}
]
}
""")
.withQueryFilterJson(JsonUtils.toJson(new QQueryFilter())) .withQueryFilterJson(JsonUtils.toJson(new QQueryFilter()))
)).getRecords().get(0); )).getRecords().get(0);

View File

@ -51,6 +51,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.reporting.QReportField;
import com.kingsrook.qqq.backend.core.model.metadata.reporting.QReportMetaData; import com.kingsrook.qqq.backend.core.model.metadata.reporting.QReportMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.reporting.QReportView; import com.kingsrook.qqq.backend.core.model.metadata.reporting.QReportView;
import com.kingsrook.qqq.backend.core.model.metadata.reporting.ReportType; import com.kingsrook.qqq.backend.core.model.metadata.reporting.ReportType;
import com.kingsrook.qqq.backend.core.model.savedreports.ReportColumns;
import com.kingsrook.qqq.backend.core.model.savedreports.SavedReport; import com.kingsrook.qqq.backend.core.model.savedreports.SavedReport;
import com.kingsrook.qqq.backend.core.model.savedreports.SavedReportsMetaDataProvider; import com.kingsrook.qqq.backend.core.model.savedreports.SavedReportsMetaDataProvider;
import com.kingsrook.qqq.backend.core.model.session.QSession; import com.kingsrook.qqq.backend.core.model.session.QSession;
@ -244,12 +245,10 @@ public class GenerateReportActionRDBMSTest extends RDBMSActionTest
{ {
List<String> lines = runSavedReportForCSV(new SavedReport() List<String> lines = runSavedReportForCSV(new SavedReport()
.withTableName(TestUtils.TABLE_NAME_ORDER) .withTableName(TestUtils.TABLE_NAME_ORDER)
.withColumnsJson(""" .withColumnsJson(JsonUtils.toJson(new ReportColumns()
{"columns":[ .withColumn("id")
{"name": "id"}, .withColumn("storeId")
{"name": "storeId"}, .withColumn("orderInstructions.instructions")))
{"name": "orderInstructions.instructions"}
]}""")
.withQueryFilterJson(JsonUtils.toJson(new QQueryFilter()))); .withQueryFilterJson(JsonUtils.toJson(new QQueryFilter())));
assertEquals(""" assertEquals("""
@ -261,6 +260,7 @@ public class GenerateReportActionRDBMSTest extends RDBMSActionTest
} }
/******************************************************************************* /*******************************************************************************
** in here, by potentially ambiguous, we mean where there are possible joins ** in here, by potentially ambiguous, we mean where there are possible joins
** between the order and orderInstructions tables. ** between the order and orderInstructions tables.
@ -270,12 +270,10 @@ public class GenerateReportActionRDBMSTest extends RDBMSActionTest
{ {
List<String> lines = runSavedReportForCSV(new SavedReport() List<String> lines = runSavedReportForCSV(new SavedReport()
.withTableName(TestUtils.TABLE_NAME_ORDER) .withTableName(TestUtils.TABLE_NAME_ORDER)
.withColumnsJson(""" .withColumnsJson(JsonUtils.toJson(new ReportColumns()
{"columns":[ .withColumn("id")
{"name": "id"}, .withColumn("storeId")
{"name": "storeId"}, .withColumn("orderInstructions.instructions")))
{"name": "orderInstructions.instructions"}
]}""")
.withQueryFilterJson(JsonUtils.toJson(new QQueryFilter() .withQueryFilterJson(JsonUtils.toJson(new QQueryFilter()
.withOrderBy(new QFilterOrderBy("orderInstructions.id", false)) .withOrderBy(new QFilterOrderBy("orderInstructions.id", false))
))); )));
@ -298,11 +296,9 @@ public class GenerateReportActionRDBMSTest extends RDBMSActionTest
{ {
List<String> lines = runSavedReportForCSV(new SavedReport() List<String> lines = runSavedReportForCSV(new SavedReport()
.withTableName(TestUtils.TABLE_NAME_ORDER) .withTableName(TestUtils.TABLE_NAME_ORDER)
.withColumnsJson(""" .withColumnsJson(JsonUtils.toJson(new ReportColumns()
{"columns":[ .withColumn("id")
{"name": "id"}, .withColumn("storeId")))
{"name": "storeId"}
]}""")
.withQueryFilterJson(JsonUtils.toJson(new QQueryFilter() .withQueryFilterJson(JsonUtils.toJson(new QQueryFilter()
.withCriteria(new QFilterCriteria("orderInstructions.instructions", QCriteriaOperator.CONTAINS, "v3")) .withCriteria(new QFilterCriteria("orderInstructions.instructions", QCriteriaOperator.CONTAINS, "v3"))
))); )));
@ -325,12 +321,10 @@ public class GenerateReportActionRDBMSTest extends RDBMSActionTest
{ {
List<String> lines = runSavedReportForCSV(new SavedReport() List<String> lines = runSavedReportForCSV(new SavedReport()
.withTableName(TestUtils.TABLE_NAME_ORDER) .withTableName(TestUtils.TABLE_NAME_ORDER)
.withColumnsJson(""" .withColumnsJson(JsonUtils.toJson(new ReportColumns()
{"columns":[ .withColumn("id")
{"name": "id"}, .withColumn("storeId")
{"name": "storeId"}, .withColumn("item.description")))
{"name": "item.description"}
]}""")
.withQueryFilterJson(JsonUtils.toJson(new QQueryFilter()))); .withQueryFilterJson(JsonUtils.toJson(new QQueryFilter())));
assertEquals(""" assertEquals("""
@ -352,11 +346,9 @@ public class GenerateReportActionRDBMSTest extends RDBMSActionTest
{ {
List<String> lines = runSavedReportForCSV(new SavedReport() List<String> lines = runSavedReportForCSV(new SavedReport()
.withTableName(TestUtils.TABLE_NAME_ORDER) .withTableName(TestUtils.TABLE_NAME_ORDER)
.withColumnsJson(""" .withColumnsJson(JsonUtils.toJson(new ReportColumns()
{"columns":[ .withColumn("id")
{"name": "id"}, .withColumn("storeId")))
{"name": "storeId"}
]}""")
.withQueryFilterJson(JsonUtils.toJson(new QQueryFilter() .withQueryFilterJson(JsonUtils.toJson(new QQueryFilter()
.withCriteria(new QFilterCriteria("item.description", QCriteriaOperator.CONTAINS, "Item 7")) .withCriteria(new QFilterCriteria("item.description", QCriteriaOperator.CONTAINS, "Item 7"))
))); )));

View File

@ -50,6 +50,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData; import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType; import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType;
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
import com.kingsrook.qqq.backend.core.model.savedreports.ReportColumns;
import com.kingsrook.qqq.backend.core.model.savedreports.SavedReport; import com.kingsrook.qqq.backend.core.model.savedreports.SavedReport;
import com.kingsrook.qqq.backend.core.utils.JsonUtils; import com.kingsrook.qqq.backend.core.utils.JsonUtils;
import com.kingsrook.qqq.backend.core.utils.SleepUtils; import com.kingsrook.qqq.backend.core.utils.SleepUtils;
@ -1417,13 +1418,10 @@ class QJavalinApiHandlerTest extends BaseTest
.withLabel("Person Report") .withLabel("Person Report")
.withTableName(TestUtils.TABLE_NAME_PERSON) .withTableName(TestUtils.TABLE_NAME_PERSON)
.withQueryFilterJson(JsonUtils.toJson(new QQueryFilter())) .withQueryFilterJson(JsonUtils.toJson(new QQueryFilter()))
.withColumnsJson(""" .withColumnsJson(JsonUtils.toJson(new ReportColumns()
{"columns":[ .withColumn("id")
{"name": "id"}, .withColumn("firstName")
{"name": "firstName"}, .withColumn("lastName"))));
{"name": "lastName"}
]}
"""));
HttpResponse<String> response = Unirest.get(BASE_URL + "/api/" + VERSION + "/savedReport/renderSavedReport/" + reportId + "?reportFormat=CSV").asString(); HttpResponse<String> response = Unirest.get(BASE_URL + "/api/" + VERSION + "/savedReport/renderSavedReport/" + reportId + "?reportFormat=CSV").asString();
assertEquals(HttpStatus.OK_200, response.getStatus()); assertEquals(HttpStatus.OK_200, response.getStatus());