diff --git a/core/flamingock-test-support/src/main/java/io/flamingock/support/domain/AuditEntryExpectation.java b/core/flamingock-test-support/src/main/java/io/flamingock/support/domain/AuditEntryExpectation.java index 3a6e04392..c31a4e15d 100644 --- a/core/flamingock-test-support/src/main/java/io/flamingock/support/domain/AuditEntryExpectation.java +++ b/core/flamingock-test-support/src/main/java/io/flamingock/support/domain/AuditEntryExpectation.java @@ -15,8 +15,10 @@ */ package io.flamingock.support.domain; +import io.flamingock.api.RecoveryStrategy; import io.flamingock.api.annotations.Apply; import io.flamingock.api.annotations.Change; +import io.flamingock.api.annotations.Recovery; import io.flamingock.api.annotations.Rollback; import io.flamingock.api.annotations.TargetSystem; import io.flamingock.internal.common.core.audit.AuditEntry; @@ -90,6 +92,9 @@ */ public class AuditEntryExpectation { + private static final String ORDER_PATTERN_PREFIX = "_"; + private static final String ORDER_PATTERN_SEPARATOR = "__"; + private final String expectedChangeId; private final AuditEntry.Status expectedState; @@ -104,6 +109,9 @@ public class AuditEntryExpectation { private String expectedExecutionHostname; private String expectedErrorTrace; private String expectedTargetSystemId; + private RecoveryStrategy expectedRecoveryStrategy; + private String expectedOrder; + private Boolean expectedTransactional; // Time range for flexible timestamp verification private LocalDateTime timestampAfter; @@ -279,6 +287,15 @@ private static AuditEntryExpectation fromChangeClass(Class changeClass, Audit expectation.expectedTargetSystemId = targetSystem.id(); } + Recovery recovery = changeClass.getAnnotation(Recovery.class); + expectation.expectedRecoveryStrategy = (recovery != null) + ? recovery.strategy() + : RecoveryStrategy.MANUAL_INTERVENTION; + + expectation.expectedOrder = extractOrderFromClassName(changeClass.getSimpleName()); + + expectation.expectedTransactional = changeAnnotation.transactional(); + return expectation; } @@ -298,6 +315,17 @@ private static String findMethodName(Class changeClass, AuditEntry.Status sta annotationClass.getSimpleName())); } + private static String extractOrderFromClassName(String className) { + if (className == null || !className.startsWith(ORDER_PATTERN_PREFIX)) { + return null; + } + int separatorIndex = className.indexOf(ORDER_PATTERN_SEPARATOR); + if (separatorIndex <= 1) { + return null; + } + return className.substring(1, separatorIndex); + } + /** * Sets the expected execution ID for verification. * @@ -456,6 +484,46 @@ public AuditEntryExpectation withTargetSystemId(String targetSystemId) { return this; } + /** + * Sets the expected recovery strategy for verification. + * + *

Enables verification of the recovery strategy field.

+ * + * @param recoveryStrategy the expected recovery strategy + * @return this builder for method chaining + */ + public AuditEntryExpectation withRecoveryStrategy(RecoveryStrategy recoveryStrategy) { + this.expectedRecoveryStrategy = recoveryStrategy; + return this; + } + + /** + * Sets the expected order value for verification. + * + *

The order is typically extracted from the class name pattern {@code _ORDER__CHANGE-NAME}, + * but can be overridden using this method.

+ * + * @param order the expected order value + * @return this builder for method chaining + */ + public AuditEntryExpectation withOrder(String order) { + this.expectedOrder = order; + return this; + } + + /** + * Sets the expected transactional flag for verification. + * + *

Indicates whether the change should run within a transaction.

+ * + * @param transactional the expected transactional flag + * @return this builder for method chaining + */ + public AuditEntryExpectation withTransactional(boolean transactional) { + this.expectedTransactional = transactional; + return this; + } + /** * Compares this expectation against an actual audit entry. * @@ -531,6 +599,22 @@ public List compareWith(AuditEntry actual) { errors.add(new FieldMismatchError("targetSystemId", expectedTargetSystemId, actual.getTargetSystemId())); } + if (expectedRecoveryStrategy != null && expectedRecoveryStrategy != actual.getRecoveryStrategy()) { + errors.add(new FieldMismatchError("recoveryStrategy", + expectedRecoveryStrategy.name(), + actual.getRecoveryStrategy() != null ? actual.getRecoveryStrategy().name() : null)); + } + + if (expectedOrder != null && !expectedOrder.equals(actual.getOrder())) { + errors.add(new FieldMismatchError("order", expectedOrder, actual.getOrder())); + } + + if (expectedTransactional != null && !expectedTransactional.equals(actual.getTransactionFlag())) { + errors.add(new FieldMismatchError("transactional", + String.valueOf(expectedTransactional), + String.valueOf(actual.getTransactionFlag()))); + } + errors.addAll(compareTimestamp(actual)); return errors;