From e3de6bd60b4133fb6eb968b70d2d91d89ae11745 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Wed, 27 Nov 2024 09:48:24 +0100 Subject: [PATCH] add REST-test case REVERTING_TRANSFER_ASSET_TRANSACTION_IMPLICITLY_REVERTS_ADOPTING_ASSET_TRANSACTION --- ...OfficeCoopAssetsTransactionController.java | 2 +- ...opAssetsTransactionControllerRestTest.java | 128 +++++++++++++++--- .../hsadminng/test/TestUuidGenerator.java | 3 + 3 files changed, 112 insertions(+), 21 deletions(-) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionController.java b/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionController.java index a0282c6c..4ec037b3 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionController.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionController.java @@ -227,7 +227,7 @@ public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAsse throw new ValidationException("REVERSAL asset transaction requires revertedAssetTx.uuid"); } final var revertedAssetTx = coopAssetsTransactionRepo.findByUuid(resource.getRevertedAssetTxUuid()) - .orElseThrow(() -> new EntityNotFoundException("ERROR: [400] revertedEntityUuid %s not found".formatted( + .orElseThrow(() -> new EntityNotFoundException("ERROR: [400] revertedAssetTx.uuid %s not found".formatted( resource.getRevertedAssetTxUuid()))); revertedAssetTx.setReversalAssetTx(entity); entity.setRevertedAssetTx(revertedAssetTx); diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerRestTest.java index e6f91c85..bb150082 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerRestTest.java @@ -30,6 +30,7 @@ import java.util.function.Function; import static net.hostsharing.hsadminng.rbac.test.JsonBuilder.jsonObject; import static net.hostsharing.hsadminng.rbac.test.JsonMatcher.lenientlyEquals; +import static org.assertj.core.api.Assumptions.assumeThat; import static org.hamcrest.Matchers.is; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -42,6 +43,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @RunWith(SpringRunner.class) class HsOfficeCoopAssetsTransactionControllerRestTest { + // If you need to run just a single test-case in this data-driven test-method, + // set SINGLE_TEST_CASE_EXECUTION to true and make sure you do NOT EVER commit it to git! + private static final boolean SINGLE_TEST_CASE_EXECUTION = false; + private static final UUID UNAVAILABLE_MEMBERSHIP_UUID = TestUuidGenerator.use(0); private static final String UNAVAILABLE_MEMBER_NUMBER = "M-1234699"; @@ -68,8 +73,8 @@ class HsOfficeCoopAssetsTransactionControllerRestTest { // The following refs depend on the implementation of the respective implementation and might change if it changes. // The same TestUuidGenerator.ref(#) does NOT mean the UUIDs refer to the same entity, // its rather coincidence because different test-cases have different execution paths in the production code. - private static final UUID NEW_EXPLICITLY_CREATED_REVERSAL_ASSET_TX_UUID = TestUuidGenerator.ref(4); - private static final UUID NEW_EXPLICITLY_CREATED_TRANSFER_ASSET_TX_UUID = TestUuidGenerator.ref(4); + private static final UUID NEW_EXPLICITLY_CREATED_REVERSAL_ASSET_TX_UUID = TestUuidGenerator.ref(6); + private static final UUID NEW_EXPLICITLY_CREATED_TRANSFER_ASSET_TX_UUID = TestUuidGenerator.ref(6); private static final UUID SOME_EXISTING_LOSS_ASSET_TX_UUID = TestUuidGenerator.use(3); public final HsOfficeCoopAssetsTransactionEntity SOME_EXISTING_LOSS_ASSET_TX_ENTITY = HsOfficeCoopAssetsTransactionEntity.builder() @@ -82,6 +87,33 @@ class HsOfficeCoopAssetsTransactionControllerRestTest { .valueDate(LocalDate.parse("2024-10-15")) .build(); + private static final UUID SOME_EXISTING_TRANSFER_ASSET_TX_UUID = TestUuidGenerator.use(4); + public final HsOfficeCoopAssetsTransactionEntity SOME_EXISTING_TRANSFER_ASSET_TX_ENTITY = HsOfficeCoopAssetsTransactionEntity.builder() + .uuid(SOME_EXISTING_TRANSFER_ASSET_TX_UUID) + .membership(ORIGIN_TARGET_MEMBER_ENTITY) + .transactionType(HsOfficeCoopAssetsTransactionType.TRANSFER) + .assetValue(BigDecimal.valueOf(-256)) + .reference("some transfer asset tx ref") + .comment("some transfer asset tx comment") + .valueDate(LocalDate.parse("2024-10-15")) + .build(); + + private static final UUID SOME_EXISTING_ADOPTION_ASSET_TX_UUID = TestUuidGenerator.use(5); + public final HsOfficeCoopAssetsTransactionEntity SOME_EXISTING_ADOPTION_ASSET_TX_ENTITY = HsOfficeCoopAssetsTransactionEntity.builder() + .uuid(SOME_EXISTING_ADOPTION_ASSET_TX_UUID) + .membership(ORIGIN_TARGET_MEMBER_ENTITY) + .transactionType(HsOfficeCoopAssetsTransactionType.TRANSFER) + .assetValue(SOME_EXISTING_TRANSFER_ASSET_TX_ENTITY.getAssetValue().negate()) + .reference("some adoption asset tx ref") + .comment("some adoption asset tx comment") + .valueDate(LocalDate.parse("2024-10-15")) + .transferAssetTx(SOME_EXISTING_TRANSFER_ASSET_TX_ENTITY) + .build(); + + { + SOME_EXISTING_TRANSFER_ASSET_TX_ENTITY.setAdoptionAssetTx(SOME_EXISTING_ADOPTION_ASSET_TX_ENTITY); + } + @Autowired MockMvc mockMvc; @@ -192,8 +224,10 @@ class HsOfficeCoopAssetsTransactionControllerRestTest { @EnumSource(BadRequestTestCases.class) void respondWithBadRequest(final BadRequestTestCases testCase) throws Exception { // HOWTO: run just a single test-case in a data-driven test-method - // org.assertj.core.api.Assumptions.assumeThat( - // testCase == ADOPTING_MEMBERSHIP_NUMBER_FOR_TRANSFER_MUST_BE_GIVEN_AND_AVAILABLE).isTrue(); + // - set SINGLE_TEST_CASE_EXECUTION to true - see above + // - select the test case enum value you want to run + assumeThat(!SINGLE_TEST_CASE_EXECUTION || + testCase == BadRequestTestCases.ADOPTING_MEMBERSHIP_NUMBER_FOR_TRANSFER_MUST_BE_GIVEN_AND_AVAILABLE).isTrue(); // when mockMvc.perform(MockMvcRequestBuilders @@ -217,10 +251,10 @@ class HsOfficeCoopAssetsTransactionControllerRestTest { .with("transactionType", "REVERSAL") .with("assetValue", "64.00") .with("valueDate", "2024-10-15") - .with("reference", "reversal ref") - .with("comment", "reversal comment") + .with("reference", "reversal of loss ref") + .with("comment", "reversal of loss asset tx comment") .with("revertedAssetTx.uuid", SOME_EXISTING_LOSS_ASSET_TX_UUID.toString()), - Expected.REVERT_RESPONSE), + Expected.REVERT_LOSS_RESPONSE), TRANSFER_TO_GIVEN_AVAILABLE_MEMBERSHIP_NUMBER( requestBody -> requestBody @@ -235,7 +269,17 @@ class HsOfficeCoopAssetsTransactionControllerRestTest { .with("assetValue", -64.00) .with("membership.uuid", ORIGIN_MEMBERSHIP_UUID.toString()) .with("adoptingMembership.uuid", AVAILABLE_TARGET_MEMBERSHIP_UUID.toString()), - Expected.TRANSFER_RESPONSE); + Expected.TRANSFER_RESPONSE), + + REVERTING_TRANSFER_ASSET_TRANSACTION_IMPLICITLY_REVERTS_ADOPTING_ASSET_TRANSACTION( + requestBody -> requestBody + .with("transactionType", "REVERSAL") + .with("assetValue", "256.00") + .with("valueDate", "2024-10-15") + .with("reference", "reversal of transfer ref") + .with("comment", "reversal of transfer asset tx comment") + .with("revertedAssetTx.uuid", SOME_EXISTING_TRANSFER_ASSET_TX_UUID.toString()), + Expected.REVERT_TRANSFER_RESPONSE); private final Function givenBodyTransformation; private final String expectedResponseBody; @@ -253,7 +297,7 @@ class HsOfficeCoopAssetsTransactionControllerRestTest { private static class Expected { - public static final String REVERT_RESPONSE = """ + public static final String REVERT_LOSS_RESPONSE = """ { "uuid": "%{NEW_EXPLICITLY_CREATED_REVERSAL_ASSET_TX_UUID}", "membership.uuid": "%{ORIGIN_MEMBERSHIP_UUID}", @@ -261,8 +305,8 @@ class HsOfficeCoopAssetsTransactionControllerRestTest { "transactionType": "REVERSAL", "assetValue": 64.00, "valueDate": "2024-10-15", - "reference": "reversal ref", - "comment": "reversal comment", + "reference": "reversal of loss ref", + "comment": "reversal of loss asset tx comment", "adoptionAssetTx": null, "transferAssetTx": null, "revertedAssetTx": { @@ -281,7 +325,9 @@ class HsOfficeCoopAssetsTransactionControllerRestTest { } } """ - .replace("%{NEW_EXPLICITLY_CREATED_REVERSAL_ASSET_TX_UUID}", NEW_EXPLICITLY_CREATED_REVERSAL_ASSET_TX_UUID.toString()) + .replace( + "%{NEW_EXPLICITLY_CREATED_REVERSAL_ASSET_TX_UUID}", + NEW_EXPLICITLY_CREATED_REVERSAL_ASSET_TX_UUID.toString()) .replace("%{ORIGIN_MEMBERSHIP_UUID}", ORIGIN_MEMBERSHIP_UUID.toString()) .replace("%{ORIGIN_MEMBER_NUMBER}", ORIGIN_MEMBER_NUMBER) .replace("%{SOME_EXISTING_LOSS_ASSET_TX_UUID}", SOME_EXISTING_LOSS_ASSET_TX_UUID.toString()); @@ -305,20 +351,57 @@ class HsOfficeCoopAssetsTransactionControllerRestTest { "reversalAssetTx": null } """ - .replace("%{NEW_EXPLICITLY_CREATED_TRANSFER_ASSET_TX_UUID}", NEW_EXPLICITLY_CREATED_TRANSFER_ASSET_TX_UUID.toString()) + .replace( + "%{NEW_EXPLICITLY_CREATED_TRANSFER_ASSET_TX_UUID}", + NEW_EXPLICITLY_CREATED_TRANSFER_ASSET_TX_UUID.toString()) .replace("%{ORIGIN_MEMBERSHIP_UUID}", ORIGIN_MEMBERSHIP_UUID.toString()) .replace("%{ORIGIN_MEMBER_NUMBER}", ORIGIN_MEMBER_NUMBER) .replace("%{AVAILABLE_MEMBERSHIP_UUID}", AVAILABLE_TARGET_MEMBERSHIP_UUID.toString()) .replace("%{AVAILABLE_TARGET_MEMBER_NUMBER}", AVAILABLE_TARGET_MEMBER_NUMBER); + + public static final String REVERT_TRANSFER_RESPONSE = """ + { + "uuid": "%{NEW_EXPLICITLY_CREATED_REVERSAL_ASSET_TX_UUID}", + "membership.uuid": "%{ORIGIN_MEMBERSHIP_UUID}", + "membership.memberNumber": "%{ORIGIN_MEMBER_NUMBER}", + "transactionType": "REVERSAL", + "assetValue": 256.00, + "valueDate": "2024-10-15", + "reference": "reversal of transfer ref", + "comment": "reversal of transfer asset tx comment", + "adoptionAssetTx": null, + "transferAssetTx": null, + "revertedAssetTx": { + "uuid": "%{SOME_EXISTING_TRANSFER_ASSET_TX_UUID}", + "membership.uuid": "%{ORIGIN_MEMBERSHIP_UUID}", + "membership.memberNumber": "%{ORIGIN_MEMBER_NUMBER}", + "transactionType": "TRANSFER", + "assetValue": -256.00, + "valueDate": "2024-10-15", + "reference": "some transfer asset tx ref", + "comment": "some transfer asset tx comment", + "adoptionAssetTx.uuid": "%{SOME_EXISTING_ADOPTION_ASSET_TX_UUID}", + "transferAssetTx.uuid": null, + "revertedAssetTx.uuid": null, + "reversalAssetTx.uuid": "%{NEW_EXPLICITLY_CREATED_REVERSAL_ASSET_TX_UUID}" + } + } + """ + .replace( + "%{NEW_EXPLICITLY_CREATED_REVERSAL_ASSET_TX_UUID}", + NEW_EXPLICITLY_CREATED_REVERSAL_ASSET_TX_UUID.toString()) + .replace("%{ORIGIN_MEMBERSHIP_UUID}", ORIGIN_MEMBERSHIP_UUID.toString()) + .replace("%{ORIGIN_MEMBER_NUMBER}", ORIGIN_MEMBER_NUMBER) + .replace("%{SOME_EXISTING_TRANSFER_ASSET_TX_UUID}", SOME_EXISTING_TRANSFER_ASSET_TX_UUID.toString()) + .replace("%{SOME_EXISTING_ADOPTION_ASSET_TX_UUID}", SOME_EXISTING_ADOPTION_ASSET_TX_UUID.toString()); } } @ParameterizedTest @EnumSource(SuccessfullyCreatedTestCases.class) void respondWithSuccessfullyCreated(final SuccessfullyCreatedTestCases testCase) throws Exception { - // uncomment, if you need to run just a single test-case in this data-driven test-method - // org.assertj.core.api.Assumptions.assumeThat( - // testCase == ADOPTING_MEMBERSHIP_UUID_FOR_TRANSFER_MUST_BE_GIVEN_AND_AVAILABLE).isTrue(); + assumeThat(!SINGLE_TEST_CASE_EXECUTION || + testCase == SuccessfullyCreatedTestCases.REVERTING_TRANSFER_ASSET_TRANSACTION_IMPLICITLY_REVERTS_ADOPTING_ASSET_TRANSACTION).isTrue(); // when mockMvc.perform(MockMvcRequestBuilders @@ -335,10 +418,11 @@ class HsOfficeCoopAssetsTransactionControllerRestTest { @BeforeEach void initMocks() { - TestUuidGenerator.start(4); + TestUuidGenerator.start(6); when(emw.find(eq(HsOfficeMembershipEntity.class), eq(ORIGIN_MEMBERSHIP_UUID))).thenReturn(ORIGIN_TARGET_MEMBER_ENTITY); - when(emw.find(eq(HsOfficeMembershipEntity.class), eq(AVAILABLE_TARGET_MEMBERSHIP_UUID))).thenReturn(AVAILABLE_MEMBER_ENTITY); + when(emw.find(eq(HsOfficeMembershipEntity.class), eq(AVAILABLE_TARGET_MEMBERSHIP_UUID))).thenReturn( + AVAILABLE_MEMBER_ENTITY); final var availableMemberNumber = Integer.valueOf(AVAILABLE_TARGET_MEMBER_NUMBER.substring("M-".length())); when(membershipRepo.findMembershipByMemberNumber(eq(availableMemberNumber))).thenReturn(AVAILABLE_MEMBER_ENTITY); @@ -348,6 +432,10 @@ class HsOfficeCoopAssetsTransactionControllerRestTest { when(coopAssetsTransactionRepo.findByUuid(SOME_EXISTING_LOSS_ASSET_TX_UUID)) .thenReturn(Optional.of(SOME_EXISTING_LOSS_ASSET_TX_ENTITY)); + when(coopAssetsTransactionRepo.findByUuid(SOME_EXISTING_TRANSFER_ASSET_TX_UUID)) + .thenReturn(Optional.of(SOME_EXISTING_TRANSFER_ASSET_TX_ENTITY)); + when(coopAssetsTransactionRepo.findByUuid(SOME_EXISTING_ADOPTION_ASSET_TX_UUID)) + .thenReturn(Optional.of(SOME_EXISTING_ADOPTION_ASSET_TX_ENTITY)); when(coopAssetsTransactionRepo.save(any(HsOfficeCoopAssetsTransactionEntity.class))) .thenAnswer(invocation -> { final var entity = (HsOfficeCoopAssetsTransactionEntity) invocation.getArgument(0); @@ -360,10 +448,10 @@ class HsOfficeCoopAssetsTransactionControllerRestTest { } private int partnerNumberOf(final String memberNumber) { - return Integer.parseInt(memberNumber.substring("M-".length(), memberNumber.length()-2)); + return Integer.parseInt(memberNumber.substring("M-".length(), memberNumber.length() - 2)); } private String suffixOf(final String memberNumber) { - return memberNumber.substring("M-".length()+5); + return memberNumber.substring("M-".length() + 5); } } diff --git a/src/test/java/net/hostsharing/hsadminng/test/TestUuidGenerator.java b/src/test/java/net/hostsharing/hsadminng/test/TestUuidGenerator.java index b75424c1..e0737bb9 100644 --- a/src/test/java/net/hostsharing/hsadminng/test/TestUuidGenerator.java +++ b/src/test/java/net/hostsharing/hsadminng/test/TestUuidGenerator.java @@ -63,6 +63,9 @@ public class TestUuidGenerator { * @return a constant UUID related to the given index */ public static UUID use(final int index) { + if (staticallyUsedIndexes.contains(index)) { + throw new IllegalArgumentException("index " + index + " already used statically"); + } staticallyUsedIndexes.add(index); return GIVEN_UUIDS.get(index); }