CE-936 - Update to send warnings from insert & update back not as an exception, but as a success, with warnings in the record.

This commit is contained in:
2024-03-19 11:32:41 -05:00
parent 7015322bf3
commit c8c7051628
3 changed files with 155 additions and 8 deletions

View File

@ -710,10 +710,15 @@ public class QJavalinImplementation
{
throw (new QUserFacingException("Error updating " + tableMetaData.getLabel() + ": " + joinErrorsWithCommasAndAnd(outputRecord.getErrors())));
}
if(CollectionUtils.nullSafeHasContents(outputRecord.getWarnings()))
{
throw (new QUserFacingException("Warning updating " + tableMetaData.getLabel() + ": " + joinErrorsWithCommasAndAnd(outputRecord.getWarnings())));
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
// at one time, we threw upon warning - but //
// on insert we need to return the record (e.g., to get a generated id), so, make update do the same. //
////////////////////////////////////////////////////////////////////////////////////////////////////////
// if(CollectionUtils.nullSafeHasContents(outputRecord.getWarnings()))
// {
// throw (new QUserFacingException("Warning updating " + tableMetaData.getLabel() + ": " + joinErrorsWithCommasAndAnd(outputRecord.getWarnings())));
// }
QJavalinAccessLogger.logEndSuccess();
context.result(JsonUtils.toJson(updateOutput));
@ -902,10 +907,16 @@ public class QJavalinImplementation
{
throw (new QUserFacingException("Error inserting " + table.getLabel() + ": " + joinErrorsWithCommasAndAnd(outputRecord.getErrors())));
}
if(CollectionUtils.nullSafeHasContents(outputRecord.getWarnings()))
{
throw (new QUserFacingException("Warning inserting " + table.getLabel() + ": " + joinErrorsWithCommasAndAnd(outputRecord.getWarnings())));
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// at one time, we threw upon warning - but //
// our use-case is, the frontend, it wants to get the record, and show a success (with the generated id) //
// and then to also show a warning message - so - let it all be returned and handled on the frontend. //
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// if(CollectionUtils.nullSafeHasContents(outputRecord.getWarnings()))
// {
// throw (new QUserFacingException("Warning inserting " + table.getLabel() + ": " + joinErrorsWithCommasAndAnd(outputRecord.getWarnings())));
// }
QJavalinAccessLogger.logEndSuccess(logPair("primaryKey", () -> (outputRecord.getValue(table.getPrimaryKeyField()))));
context.result(JsonUtils.toJson(insertOutput));

View File

@ -514,6 +514,42 @@ class QJavalinImplementationTest extends QJavalinTestBase
/*******************************************************************************
** test an insert that returns a warning
**
*******************************************************************************/
@Test
public void test_dataInsertWithWarning()
{
Map<String, Serializable> body = new HashMap<>();
body.put("firstName", "Warning");
body.put("lastName", "Kelkhoff");
body.put("email", "warning@kelkhoff.com");
HttpResponse<String> response = Unirest.post(BASE_URL + "/data/person")
.header("Content-Type", "application/json")
.body(body)
.asString();
assertEquals(200, response.getStatus());
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
assertTrue(jsonObject.has("records"));
JSONArray records = jsonObject.getJSONArray("records");
assertEquals(1, records.length());
JSONObject record0 = records.getJSONObject(0);
assertTrue(record0.has("values"));
JSONObject values0 = record0.getJSONObject("values");
assertTrue(values0.has("id"));
assertEquals(7, values0.getInt("id"));
assertTrue(record0.has("warnings"));
JSONArray warnings = record0.getJSONArray("warnings");
assertEquals(1, warnings.length());
assertTrue(warnings.getJSONObject(0).has("message"));
}
/*******************************************************************************
** test an insert - posting a multipart form.
**
@ -594,6 +630,52 @@ class QJavalinImplementationTest extends QJavalinTestBase
/*******************************************************************************
** test an update - with a warning returned
**
*******************************************************************************/
@Test
public void test_dataUpdateWithWarning()
{
Map<String, Serializable> body = new HashMap<>();
body.put("firstName", "Warning");
body.put("birthDate", "");
HttpResponse<String> response = Unirest.patch(BASE_URL + "/data/person/4")
.header("Content-Type", "application/json")
.body(body)
.asString();
assertEquals(200, response.getStatus());
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
assertTrue(jsonObject.has("records"));
JSONArray records = jsonObject.getJSONArray("records");
assertEquals(1, records.length());
JSONObject record0 = records.getJSONObject(0);
assertTrue(record0.has("values"));
assertEquals("person", record0.getString("tableName"));
JSONObject values0 = record0.getJSONObject("values");
assertEquals(4, values0.getInt("id"));
assertEquals("Warning", values0.getString("firstName"));
assertTrue(record0.has("warnings"));
JSONArray warnings = record0.getJSONArray("warnings");
assertEquals(1, warnings.length());
assertTrue(warnings.getJSONObject(0).has("message"));
///////////////////////////////////////////////////////////////////
// re-GET the record, and validate that birthDate was nulled out //
///////////////////////////////////////////////////////////////////
response = Unirest.get(BASE_URL + "/data/person/4").asString();
assertEquals(200, response.getStatus());
jsonObject = JsonUtils.toJSONObject(response.getBody());
assertTrue(jsonObject.has("values"));
JSONObject values = jsonObject.getJSONObject("values");
assertFalse(values.has("birthDate"));
}
/*******************************************************************************
** test an update - posting the data as a multipart form
**

View File

@ -25,6 +25,10 @@ package com.kingsrook.qqq.backend.javalin;
import java.io.InputStream;
import java.sql.Connection;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import com.kingsrook.qqq.backend.core.actions.customizers.TableCustomizerInterface;
import com.kingsrook.qqq.backend.core.actions.customizers.TableCustomizers;
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
import com.kingsrook.qqq.backend.core.exceptions.QException;
@ -35,6 +39,7 @@ 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.tables.update.UpdateInput;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.model.metadata.QAuthenticationType;
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
@ -68,6 +73,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.tables.AssociatedScript;
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
import com.kingsrook.qqq.backend.core.model.savedviews.SavedViewsMetaDataProvider;
import com.kingsrook.qqq.backend.core.model.scripts.ScriptsMetaDataProvider;
import com.kingsrook.qqq.backend.core.model.statusmessages.QWarningMessage;
import com.kingsrook.qqq.backend.core.processes.implementations.mock.MockBackendStep;
import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager;
import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager;
@ -255,6 +261,9 @@ public class TestUtils
.withScriptTypeId(1)
.withScriptTester(new QCodeReference(TestScriptAction.class)));
qTableMetaData.withCustomizer(TableCustomizers.POST_INSERT_RECORD, new QCodeReference(PersonTableCustomizer.class));
qTableMetaData.withCustomizer(TableCustomizers.POST_UPDATE_RECORD, new QCodeReference(PersonTableCustomizer.class));
qTableMetaData.getField("photo")
.withIsHeavy(true)
.withFieldAdornment(new FieldAdornment(AdornmentType.FILE_DOWNLOAD)
@ -265,6 +274,51 @@ public class TestUtils
}
/*******************************************************************************
**
*******************************************************************************/
public static class PersonTableCustomizer implements TableCustomizerInterface
{
/*******************************************************************************
**
*******************************************************************************/
@Override
public List<QRecord> postInsert(InsertInput insertInput, List<QRecord> records) throws QException
{
return warnPostInsertOrUpdate(records);
}
/*******************************************************************************
**
*******************************************************************************/
@Override
public List<QRecord> postUpdate(UpdateInput updateInput, List<QRecord> records, Optional<List<QRecord>> oldRecordList) throws QException
{
return warnPostInsertOrUpdate(records);
}
/*******************************************************************************
**
*******************************************************************************/
private List<QRecord> warnPostInsertOrUpdate(List<QRecord> records)
{
for(QRecord record : records)
{
if(Objects.requireNonNullElse(record.getValueString("firstName"), "").toLowerCase().contains("warn"))
{
record.addWarning(new QWarningMessage("Warning in firstName."));
}
}
return records;
}
}
/*******************************************************************************
**