mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-19 05:30:43 +00:00
Merge branch 'feature/script-audit-and-audit-change-cleanup' into integration/20230921
This commit is contained in:
@ -48,6 +48,8 @@ public class BaseTest
|
||||
@BeforeEach
|
||||
void baseBeforeEach()
|
||||
{
|
||||
System.setProperty("qqq.logger.logSessionId.disabled", "true");
|
||||
|
||||
QContext.init(TestUtils.defineInstance(), new QSession()
|
||||
.withUser(new QUser()
|
||||
.withIdReference("001")
|
||||
|
@ -31,6 +31,7 @@ import com.kingsrook.qqq.backend.core.BaseTest;
|
||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.audits.AuditInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.audits.AuditSingleInput;
|
||||
import com.kingsrook.qqq.backend.core.model.audits.AuditsMetaDataProvider;
|
||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
@ -38,6 +39,7 @@ import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||
import com.kingsrook.qqq.backend.core.model.session.QUser;
|
||||
import com.kingsrook.qqq.backend.core.processes.utils.GeneralProcessUtils;
|
||||
import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
||||
import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
@ -197,4 +199,31 @@ class AuditActionTest extends BaseTest
|
||||
assertThat(auditDetails).anyMatch(r -> r.getValueString("message").equals("Detail3"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testAppendToInputThatTakesRecordNotIdAndSecurityKeyValues()
|
||||
{
|
||||
AuditInput auditInput = new AuditInput();
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// make sure the recordId & securityKey got build correctly //
|
||||
//////////////////////////////////////////////////////////////
|
||||
AuditAction.appendToInput(auditInput, QContext.getQInstance().getTable(TestUtils.TABLE_NAME_ORDER), new QRecord().withValue("id", 47).withValue("storeId", 42), "Test");
|
||||
AuditSingleInput auditSingleInput = auditInput.getAuditSingleInputList().get(0);
|
||||
assertEquals(47, auditSingleInput.getRecordId());
|
||||
assertEquals(MapBuilder.of(TestUtils.SECURITY_KEY_TYPE_STORE, 42), auditSingleInput.getSecurityKeyValues());
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// acknowledge that we might get back a null key value if the record doesn't have it set //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
AuditAction.appendToInput(auditInput, QContext.getQInstance().getTable(TestUtils.TABLE_NAME_ORDER), new QRecord().withValue("id", 47), "Test");
|
||||
auditSingleInput = auditInput.getAuditSingleInputList().get(1);
|
||||
assertEquals(47, auditSingleInput.getRecordId());
|
||||
assertEquals(MapBuilder.of(TestUtils.SECURITY_KEY_TYPE_STORE, null), auditSingleInput.getSecurityKeyValues());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,12 +22,14 @@
|
||||
package com.kingsrook.qqq.backend.core.actions.audits;
|
||||
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.BaseTest;
|
||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.audits.DMLAuditInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.delete.DeleteInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateInput;
|
||||
@ -36,10 +38,18 @@ 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.audits.AuditLevel;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.audits.QAuditRules;
|
||||
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.session.QSession;
|
||||
import com.kingsrook.qqq.backend.core.model.statusmessages.BadInputStatusMessage;
|
||||
import com.kingsrook.qqq.backend.core.modules.backend.implementations.memory.MemoryRecordStore;
|
||||
import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
||||
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static com.kingsrook.qqq.backend.core.actions.audits.DMLAuditAction.DMLType.INSERT;
|
||||
import static com.kingsrook.qqq.backend.core.actions.audits.DMLAuditAction.DMLType.UPDATE;
|
||||
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.assertNull;
|
||||
@ -200,4 +210,194 @@ class DMLAuditActionTest extends BaseTest
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testMakeAuditDetailRecordForField()
|
||||
{
|
||||
QTableMetaData table = new QTableMetaData()
|
||||
.withField(new QFieldMetaData("createDate", QFieldType.DATE_TIME).withLabel("Create Date"))
|
||||
.withField(new QFieldMetaData("modifyDate", QFieldType.DATE_TIME).withLabel("Modify Date"))
|
||||
.withField(new QFieldMetaData("someTimestamp", QFieldType.DATE_TIME).withLabel("Some Timestamp"))
|
||||
.withField(new QFieldMetaData("name", QFieldType.STRING).withLabel("Name"))
|
||||
.withField(new QFieldMetaData("seqNo", QFieldType.INTEGER).withLabel("Sequence No."))
|
||||
.withField(new QFieldMetaData("price", QFieldType.DECIMAL).withLabel("Price"));
|
||||
|
||||
///////////////////////////////
|
||||
// create date - never audit //
|
||||
///////////////////////////////
|
||||
assertThat(DMLAuditAction.makeAuditDetailRecordForField("createDate", table, INSERT,
|
||||
new QRecord().withValue("createDate", Instant.now()),
|
||||
new QRecord().withValue("createDate", Instant.now().minusSeconds(100))))
|
||||
.isEmpty();
|
||||
|
||||
///////////////////////////////
|
||||
// modify date - never audit //
|
||||
///////////////////////////////
|
||||
assertThat(DMLAuditAction.makeAuditDetailRecordForField("modifyDate", table, UPDATE,
|
||||
new QRecord().withValue("modifyDate", Instant.now()),
|
||||
new QRecord().withValue("modifyDate", Instant.now().minusSeconds(100))))
|
||||
.isEmpty();
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// datetime different only in precision - don't audit //
|
||||
////////////////////////////////////////////////////////
|
||||
assertThat(DMLAuditAction.makeAuditDetailRecordForField("someTimestamp", table, UPDATE,
|
||||
new QRecord().withValue("someTimestamp", ValueUtils.getValueAsInstant("2023-04-17T14:33:08.777")),
|
||||
new QRecord().withValue("someTimestamp", Instant.parse("2023-04-17T14:33:08Z"))))
|
||||
.isEmpty();
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// datetime actually different - audit it. //
|
||||
/////////////////////////////////////////////
|
||||
assertThat(DMLAuditAction.makeAuditDetailRecordForField("someTimestamp", table, UPDATE,
|
||||
new QRecord().withValue("someTimestamp", Instant.parse("2023-04-17T14:33:09Z")),
|
||||
new QRecord().withValue("someTimestamp", Instant.parse("2023-04-17T14:33:08Z"))))
|
||||
.isPresent()
|
||||
.get().extracting(r -> r.getValueString("message"))
|
||||
.matches(s -> s.matches("Changed Some Timestamp from 2023.* to 2023.*"));
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// datetime changing null to not null - audit //
|
||||
////////////////////////////////////////////////
|
||||
assertThat(DMLAuditAction.makeAuditDetailRecordForField("someTimestamp", table, UPDATE,
|
||||
new QRecord().withValue("someTimestamp", ValueUtils.getValueAsInstant("2023-04-17T14:33:08.777")),
|
||||
new QRecord().withValue("someTimestamp", null)))
|
||||
.isPresent()
|
||||
.get().extracting(r -> r.getValueString("message"))
|
||||
.matches(s -> s.matches("Set Some Timestamp to 2023.*"));
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// datetime changing not null to null - audit //
|
||||
////////////////////////////////////////////////
|
||||
assertThat(DMLAuditAction.makeAuditDetailRecordForField("someTimestamp", table, UPDATE,
|
||||
new QRecord().withValue("someTimestamp", null),
|
||||
new QRecord().withValue("someTimestamp", Instant.parse("2023-04-17T14:33:08Z"))))
|
||||
.isPresent()
|
||||
.get().extracting(r -> r.getValueString("message"))
|
||||
.matches(s -> s.matches("Removed 2023.*from Some Timestamp"));
|
||||
|
||||
////////////////////////////////////////
|
||||
// string that is the same - no audit //
|
||||
////////////////////////////////////////
|
||||
assertThat(DMLAuditAction.makeAuditDetailRecordForField("name", table, UPDATE,
|
||||
new QRecord().withValue("name", "Homer"),
|
||||
new QRecord().withValue("name", "Homer")))
|
||||
.isEmpty();
|
||||
|
||||
//////////////////////////////////////////
|
||||
// string from null to empty - no audit //
|
||||
//////////////////////////////////////////
|
||||
assertThat(DMLAuditAction.makeAuditDetailRecordForField("name", table, UPDATE,
|
||||
new QRecord().withValue("name", null),
|
||||
new QRecord().withValue("name", "")))
|
||||
.isEmpty();
|
||||
|
||||
//////////////////////////////////////////
|
||||
// string from empty to null - no audit //
|
||||
//////////////////////////////////////////
|
||||
assertThat(DMLAuditAction.makeAuditDetailRecordForField("name", table, UPDATE,
|
||||
new QRecord().withValue("name", ""),
|
||||
new QRecord().withValue("name", null)))
|
||||
.isEmpty();
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// decimal that only changes in precision - don't audit //
|
||||
//////////////////////////////////////////////////////////
|
||||
assertThat(DMLAuditAction.makeAuditDetailRecordForField("price", table, UPDATE,
|
||||
new QRecord().withValue("price", "10"),
|
||||
new QRecord().withValue("price", new BigDecimal("10.00"))))
|
||||
.isEmpty();
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// decimal that's actually different - do audit //
|
||||
//////////////////////////////////////////////////
|
||||
assertThat(DMLAuditAction.makeAuditDetailRecordForField("price", table, UPDATE,
|
||||
new QRecord().withValue("price", "10.01"),
|
||||
new QRecord().withValue("price", new BigDecimal("10.00"))))
|
||||
.isPresent()
|
||||
.get().extracting(r -> r.getValueString("message"))
|
||||
.matches(s -> s.matches("Changed Price from 10.00 to 10.01"));
|
||||
|
||||
///////////////////////////////////////
|
||||
// decimal null, input "" - no audit //
|
||||
///////////////////////////////////////
|
||||
assertThat(DMLAuditAction.makeAuditDetailRecordForField("price", table, UPDATE,
|
||||
new QRecord().withValue("price", ""),
|
||||
new QRecord().withValue("price", null)))
|
||||
.isEmpty();
|
||||
|
||||
/////////////////////////////////////////
|
||||
// decimal not-null to null - do audit //
|
||||
/////////////////////////////////////////
|
||||
assertThat(DMLAuditAction.makeAuditDetailRecordForField("price", table, UPDATE,
|
||||
new QRecord().withValue("price", BigDecimal.ONE),
|
||||
new QRecord().withValue("price", null)))
|
||||
.isPresent()
|
||||
.get().extracting(r -> r.getValueString("message"))
|
||||
.matches(s -> s.matches("Set Price to 1"));
|
||||
|
||||
/////////////////////////////////////////
|
||||
// decimal null to not-null - do audit //
|
||||
/////////////////////////////////////////
|
||||
assertThat(DMLAuditAction.makeAuditDetailRecordForField("price", table, UPDATE,
|
||||
new QRecord().withValue("price", null),
|
||||
new QRecord().withValue("price", BigDecimal.ONE)))
|
||||
.isPresent()
|
||||
.get().extracting(r -> r.getValueString("message"))
|
||||
.matches(s -> s.matches("Removed 1 from Price"));
|
||||
|
||||
///////////////////////////////////////
|
||||
// integer null, input "" - no audit //
|
||||
///////////////////////////////////////
|
||||
assertThat(DMLAuditAction.makeAuditDetailRecordForField("seqNo", table, UPDATE,
|
||||
new QRecord().withValue("seqNo", ""),
|
||||
new QRecord().withValue("seqNo", null)))
|
||||
.isEmpty();
|
||||
|
||||
////////////////////////////////
|
||||
// integer changed - do audit //
|
||||
////////////////////////////////
|
||||
assertThat(DMLAuditAction.makeAuditDetailRecordForField("seqNo", table, UPDATE,
|
||||
new QRecord().withValue("seqNo", 2),
|
||||
new QRecord().withValue("seqNo", 1)))
|
||||
.isPresent()
|
||||
.get().extracting(r -> r.getValueString("message"))
|
||||
.matches(s -> s.matches("Changed Sequence No. from 1 to 2"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testGetContextSuffix()
|
||||
{
|
||||
assertEquals("", DMLAuditAction.getContentSuffix(new DMLAuditInput()));
|
||||
assertEquals(" while shipping an order", DMLAuditAction.getContentSuffix(new DMLAuditInput().withAuditContext("while shipping an order")));
|
||||
|
||||
QContext.pushAction(new RunProcessInput().withValue(DMLAuditAction.AUDIT_CONTEXT_FIELD_NAME, "via Script \"My Script\""));
|
||||
assertEquals(" via Script \"My Script\"", DMLAuditAction.getContentSuffix(new DMLAuditInput()));
|
||||
QContext.popAction();
|
||||
|
||||
QContext.pushAction(new RunProcessInput().withProcessName(TestUtils.PROCESS_NAME_GREET_PEOPLE));
|
||||
assertEquals(" during process: Greet", DMLAuditAction.getContentSuffix(new DMLAuditInput()));
|
||||
QContext.popAction();
|
||||
|
||||
QContext.setQSession(new QSession().withValue("apiVersion", "1.0"));
|
||||
assertEquals(" via API Version: 1.0", DMLAuditAction.getContentSuffix(new DMLAuditInput()));
|
||||
|
||||
QContext.setQSession(new QSession().withValue("apiVersion", "20230921").withValue("apiLabel", "Our Public API"));
|
||||
assertEquals(" via Our Public API Version: 20230921", DMLAuditAction.getContentSuffix(new DMLAuditInput()));
|
||||
|
||||
QContext.pushAction(new RunProcessInput().withProcessName(TestUtils.PROCESS_NAME_GREET_PEOPLE).withValue(DMLAuditAction.AUDIT_CONTEXT_FIELD_NAME, "via Script \"My Script\""));
|
||||
QContext.setQSession(new QSession().withValue("apiVersion", "20230921").withValue("apiLabel", "Our Public API"));
|
||||
assertEquals(" while shipping an order via Script \"My Script\" during process: Greet via Our Public API Version: 20230921", DMLAuditAction.getContentSuffix(new DMLAuditInput().withAuditContext("while shipping an order")));
|
||||
QContext.popAction();
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user