diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/tables/helpers/UpdateActionRecordSplitHelper.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/tables/helpers/UpdateActionRecordSplitHelper.java index ac0acdcb..5762480e 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/tables/helpers/UpdateActionRecordSplitHelper.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/tables/helpers/UpdateActionRecordSplitHelper.java @@ -171,7 +171,7 @@ public class UpdateActionRecordSplitHelper /******************************************************************************* - ** Getter for haveAnyWithoutErorrs + ** Getter for haveAnyWithoutErrors ** *******************************************************************************/ public boolean getHaveAnyWithoutErrors() diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/processes/QProcessCallbackFactoryTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/processes/QProcessCallbackFactoryTest.java new file mode 100644 index 00000000..cc660cfe --- /dev/null +++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/processes/QProcessCallbackFactoryTest.java @@ -0,0 +1,58 @@ +/* + * 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 . + */ + +package com.kingsrook.qqq.backend.core.actions.processes; + + +import java.util.ArrayList; +import java.util.Collections; +import com.kingsrook.qqq.backend.core.BaseTest; +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 org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + + +/******************************************************************************* + ** Unit test for QProcessCallbackFactory + *******************************************************************************/ +class QProcessCallbackFactoryTest extends BaseTest +{ + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void test() + { + QProcessCallback qProcessCallback = QProcessCallbackFactory.forFilter(new QQueryFilter(new QFilterCriteria("foo", QCriteriaOperator.EQUALS, "bar"))); + + QQueryFilter queryFilter = qProcessCallback.getQueryFilter(); + assertEquals(1, queryFilter.getCriteria().size()); + assertEquals("foo", queryFilter.getCriteria().get(0).getFieldName()); + assertEquals(QCriteriaOperator.EQUALS, queryFilter.getCriteria().get(0).getOperator()); + assertEquals("bar", queryFilter.getCriteria().get(0).getValues().get(0)); + + assertEquals(Collections.emptyMap(), qProcessCallback.getFieldValues(new ArrayList<>())); + } + +} \ No newline at end of file diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/tables/helpers/UpdateActionRecordSplitHelperTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/tables/helpers/UpdateActionRecordSplitHelperTest.java new file mode 100644 index 00000000..7d3a55d0 --- /dev/null +++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/tables/helpers/UpdateActionRecordSplitHelperTest.java @@ -0,0 +1,147 @@ +/* + * 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 . + */ + +package com.kingsrook.qqq.backend.core.actions.tables.helpers; + + +import java.time.Instant; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; +import com.kingsrook.qqq.backend.core.BaseTest; +import com.kingsrook.qqq.backend.core.context.QContext; +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.fields.QFieldMetaData; +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.statusmessages.SystemErrorStatusMessage; +import com.kingsrook.qqq.backend.core.utils.ListingHash; +import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + + +/******************************************************************************* + ** Unit test for UpdateActionRecordSplitHelper + *******************************************************************************/ +class UpdateActionRecordSplitHelperTest extends BaseTest +{ + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void test() + { + String tableName = getClass().getSimpleName(); + QContext.getQInstance().addTable(new QTableMetaData() + .withName(tableName) + .withField(new QFieldMetaData("id", QFieldType.INTEGER)) + .withField(new QFieldMetaData("A", QFieldType.INTEGER)) + .withField(new QFieldMetaData("B", QFieldType.INTEGER)) + .withField(new QFieldMetaData("modifyDate", QFieldType.DATE_TIME))); + + UpdateInput updateInput = new UpdateInput(tableName) + .withRecord(new QRecord().withValue("id", 1).withValue("A", 1)) + .withRecord(new QRecord().withValue("id", 2).withValue("A", 2)) + .withRecord(new QRecord().withValue("id", 3).withValue("B", 3)) + .withRecord(new QRecord().withValue("id", 4).withValue("B", 3)) + .withRecord(new QRecord().withValue("id", 5).withValue("B", 3)) + .withRecord(new QRecord().withValue("id", 6).withValue("A", 4).withValue("B", 5)); + UpdateActionRecordSplitHelper updateActionRecordSplitHelper = new UpdateActionRecordSplitHelper(); + updateActionRecordSplitHelper.init(updateInput); + ListingHash, QRecord> recordsByFieldBeingUpdated = updateActionRecordSplitHelper.getRecordsByFieldBeingUpdated(); + + Function, Set> extractIds = (records) -> + records.stream().map(r -> r.getValueInteger("id")).collect(Collectors.toSet()); + + //////////////////////////////////////// + // validate that modify dates got set // + //////////////////////////////////////// + updateInput.getRecords().forEach(r -> + assertThat(r.getValue("modifyDate")).isInstanceOf(Instant.class)); + + ////////////////////////////////////////////////////////////// + // validate the grouping of records by fields-being-updated // + ////////////////////////////////////////////////////////////// + assertEquals(3, recordsByFieldBeingUpdated.size()); + assertEquals(Set.of(1, 2), extractIds.apply(recordsByFieldBeingUpdated.get(List.of("A", "modifyDate")))); + assertEquals(Set.of(3, 4, 5), extractIds.apply(recordsByFieldBeingUpdated.get(List.of("B", "modifyDate")))); + assertEquals(Set.of(6), extractIds.apply(recordsByFieldBeingUpdated.get(List.of("A", "B", "modifyDate")))); + + /////////////////////////////////////////////////////////////////// + // validate the output records were built, in the order expected // + /////////////////////////////////////////////////////////////////// + List outputRecords = updateActionRecordSplitHelper.getOutputRecords(); + for(int i = 0; i < outputRecords.size(); i++) + { + assertEquals(i + 1, outputRecords.get(i).getValueInteger("id")); + } + + ///////////////////////////////////////////////////// + // test the areAllValuesBeingUpdatedTheSame method // + ///////////////////////////////////////////////////// + Function, Boolean> runAreAllValuesBeingUpdatedTheSame = (fields) -> + UpdateActionRecordSplitHelper.areAllValuesBeingUpdatedTheSame(updateInput, recordsByFieldBeingUpdated.get(fields), fields); + + assertFalse(runAreAllValuesBeingUpdatedTheSame.apply(List.of("A", "modifyDate"))); + assertTrue(runAreAllValuesBeingUpdatedTheSame.apply(List.of("B", "modifyDate"))); + assertTrue(runAreAllValuesBeingUpdatedTheSame.apply(List.of("A", "B", "modifyDate"))); + + //////////////////////////////////////////////////////////////////// + // make sure that the override of the logic for this method works // + //////////////////////////////////////////////////////////////////// + updateInput.setAreAllValuesBeingUpdatedTheSame(true); + assertTrue(runAreAllValuesBeingUpdatedTheSame.apply(List.of("A", "modifyDate"))); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testRecordsWithErrors() + { + String tableName = getClass().getSimpleName() + "WithErrors"; + QContext.getQInstance().addTable(new QTableMetaData() + .withName(tableName) + .withField(new QFieldMetaData("id", QFieldType.INTEGER)) + .withField(new QFieldMetaData("A", QFieldType.INTEGER))); + + { + UpdateInput updateInput = new UpdateInput(tableName) + .withRecord(new QRecord().withValue("id", 1).withValue("A", 1).withError(new SystemErrorStatusMessage("error"))) + .withRecord(new QRecord().withValue("id", 2).withValue("A", 2).withError(new SystemErrorStatusMessage("error"))) + .withRecord(new QRecord().withValue("id", 2).withValue("A", 3).withError(new SystemErrorStatusMessage("error"))); + UpdateActionRecordSplitHelper updateActionRecordSplitHelper = new UpdateActionRecordSplitHelper(); + updateActionRecordSplitHelper.init(updateInput); + assertFalse(updateActionRecordSplitHelper.getHaveAnyWithoutErrors()); + } + + } + +} \ No newline at end of file