diff --git a/src/test/java/net/hostsharing/hsadminng/arch/ArchitectureTest.java b/src/test/java/net/hostsharing/hsadminng/arch/ArchitectureTest.java index e53a7c75..9152d68f 100644 --- a/src/test/java/net/hostsharing/hsadminng/arch/ArchitectureTest.java +++ b/src/test/java/net/hostsharing/hsadminng/arch/ArchitectureTest.java @@ -68,6 +68,7 @@ public class ArchitectureTest { "..hs.hosting.asset", "..hs.hosting.asset.validators", "..hs.hosting.asset.factories", + "..hs.scenarios", "..errors", "..mapper", "..ping", @@ -160,9 +161,11 @@ public class ArchitectureTest { .that().resideInAPackage("..hs.office.(*)..") .should().onlyBeAccessed().byClassesThat() .resideInAnyPackage( + "..hs.office.(*)..", "..hs.office.(*)..", "..hs.booking.(*)..", "..hs.hosting.(*)..", + "..hs.scenarios", "..hs.migration", "..rbacgrant" // TODO.test: just because of RbacGrantsDiagramServiceIntegrationTest ); diff --git a/src/test/java/net/hostsharing/hsadminng/hs/migration/BaseOfficeDataImport.java b/src/test/java/net/hostsharing/hsadminng/hs/migration/BaseOfficeDataImport.java index 3ab17692..311ce4ad 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/migration/BaseOfficeDataImport.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/migration/BaseOfficeDataImport.java @@ -880,7 +880,9 @@ public abstract class BaseOfficeDataImport extends CsvDataImport { coopAssets.put(rec.getInteger("member_asset_id"), assetTransaction); }); - coopAssets.values().forEach(assetTransaction -> { + coopAssets.entrySet().forEach(entry -> { + final var legacyId = entry.getKey(); + final var assetTransaction = entry.getValue(); if (assetTransaction.getTransactionType() == HsOfficeCoopAssetsTransactionType.REVERSAL) { connectToRelatedRevertedAssetTx(assetTransaction); } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/HsOfficeScenarioTests.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/HsOfficeScenarioTests.java index 7c0f6d81..03f446f0 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/HsOfficeScenarioTests.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/HsOfficeScenarioTests.java @@ -30,14 +30,20 @@ import net.hostsharing.hsadminng.hs.office.scenarios.person.ShouldUpdatePersonDa import net.hostsharing.hsadminng.hs.office.scenarios.subscription.RemoveOperationsContactFromPartner; import net.hostsharing.hsadminng.hs.office.scenarios.subscription.SubscribeToMailinglist; import net.hostsharing.hsadminng.hs.office.scenarios.subscription.UnsubscribeFromMailinglist; +import net.hostsharing.hsadminng.hs.scenarios.Produces; +import net.hostsharing.hsadminng.hs.scenarios.Requires; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; import net.hostsharing.hsadminng.rbac.test.JpaAttempt; import net.hostsharing.hsadminng.test.DisableSecurityConfig; import net.hostsharing.hsadminng.test.IgnoreOnFailureExtension; +import org.junit.jupiter.api.ClassOrderer; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestClassOrder; import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; @@ -57,430 +63,486 @@ import org.springframework.test.context.ActiveProfiles; ) @ActiveProfiles("test") @DirtiesContext -@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +@TestClassOrder(ClassOrderer.OrderAnnotation.class) @ExtendWith(IgnoreOnFailureExtension.class) class HsOfficeScenarioTests extends ScenarioTest { - @Test - @Order(1010) - @Produces(explicitly = "Partner: P-31010 - Test AG", implicitly = { "Person: Test AG", "Contact: Test AG - Hamburg" }) - void shouldCreateLegalPersonAsPartner() { - new CreatePartner(this) - .given("partnerNumber", "P-31010") - .given("personType", "LEGAL_PERSON") - .given("tradeName", "Test AG") - .given("contactCaption", "Test AG - Hamburg") - .given("postalAddress", """ - "firm": "Test AG", - "street": "Shanghai-Allee 1", - "zipcode": "20123", - "city": "Hamburg", - "country": "Germany" - """) - .given("officePhoneNumber", "+49 40 654321-0") - .given("emailAddress", "hamburg@test-ag.example.org") - .doRun() - .keep(); + @Nested + @Order(10) + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class PartnerScenarios { + + @Test + @Order(1010) + @Produces(explicitly = "Partner: P-31010 - Test AG", implicitly = { "Person: Test AG", "Contact: Test AG - Hamburg" }) + void shouldCreateLegalPersonAsPartner() { + new CreatePartner(scenarioTest) + .given("partnerNumber", "P-31010") + .given("personType", "LEGAL_PERSON") + .given("tradeName", "Test AG") + .given("contactCaption", "Test AG - Hamburg") + .given( + "postalAddress", """ + "firm": "Test AG", + "street": "Shanghai-Allee 1", + "zipcode": "20123", + "city": "Hamburg", + "country": "Germany" + """) + .given("officePhoneNumber", "+49 40 654321-0") + .given("emailAddress", "hamburg@test-ag.example.org") + .doRun() + .keep(); + } + + @Test + @Order(1011) + @Produces(explicitly = "Partner: P-31011 - Michelle Matthieu", + implicitly = { "Person: Michelle Matthieu", "Contact: Michelle Matthieu" }) + void shouldCreateNaturalPersonAsPartner() { + new CreatePartner(scenarioTest) + .given("partnerNumber", "P-31011") + .given("personType", "NATURAL_PERSON") + .given("givenName", "Michelle") + .given("familyName", "Matthieu") + .given("contactCaption", "Michelle Matthieu") + .given( + "postalAddress", """ + "name": "Michelle Matthieu", + "street": "An der Wandse 34", + "zipcode": "22123", + "city": "Hamburg", + "country": "Germany" + """) + .given("officePhoneNumber", "+49 40 123456") + .given("emailAddress", "michelle.matthieu@example.org") + .doRun() + .keep(); + } + + @Test + @Order(1020) + @Requires("Person: Test AG") + @Produces("Representative: Tracy Trust for Test AG") + void shouldAddRepresentativeToPartner() { + new AddRepresentativeToPartner(scenarioTest) + .given("partnerPersonTradeName", "Test AG") + .given("representativeFamilyName", "Trust") + .given("representativeGivenName", "Tracy") + .given( + "representativePostalAddress", """ + "name": "Michelle Matthieu", + "street": "An der Alster 100", + "zipcode": "20000", + "city": "Hamburg", + "country": "Germany" + """) + .given("representativePhoneNumber", "+49 40 123456") + .given("representativeEMailAddress", "tracy.trust@example.org") + .doRun() + .keep(); + } + + @Test + @Order(1030) + @Requires("Person: Test AG") + @Produces("Operations-Contact: Dennis Krause for Test AG") + void shouldAddOperationsContactToPartner() { + new AddOperationsContactToPartner(scenarioTest) + .given("partnerPersonTradeName", "Test AG") + .given("operationsContactFamilyName", "Krause") + .given("operationsContactGivenName", "Dennis") + .given("operationsContactPhoneNumber", "+49 9932 587741") + .given("operationsContactEMailAddress", "dennis.krause@example.org") + .doRun() + .keep(); + } + + @Test + @Order(1039) + @Requires("Operations-Contact: Dennis Krause for Test AG") + void shouldRemoveOperationsContactFromPartner() { + new RemoveOperationsContactFromPartner(scenarioTest) + .given("operationsContactPerson", "Dennis Krause") + .doRun(); + } + + @Test + @Order(1090) + void shouldDeletePartner() { + new DeletePartner(scenarioTest) + .given("partnerNumber", "P-31020") + .doRun(); + } } - @Test - @Order(1011) - @Produces(explicitly = "Partner: P-31011 - Michelle Matthieu", - implicitly = { "Person: Michelle Matthieu", "Contact: Michelle Matthieu" }) - void shouldCreateNaturalPersonAsPartner() { - new CreatePartner(this) - .given("partnerNumber", "P-31011") - .given("personType", "NATURAL_PERSON") - .given("givenName", "Michelle") - .given("familyName", "Matthieu") - .given("contactCaption", "Michelle Matthieu") - .given("postalAddress", """ - "name": "Michelle Matthieu", - "street": "An der Wandse 34", - "zipcode": "22123", - "city": "Hamburg", - "country": "Germany" - """) - .given("officePhoneNumber", "+49 40 123456") - .given("emailAddress", "michelle.matthieu@example.org") - .doRun() - .keep(); + @Nested + @Order(11) + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class PartnerContactScenarios { + + @Test + @Order(1100) + @Requires("Partner: P-31011 - Michelle Matthieu") + void shouldAmendContactData() { + new AmendContactData(scenarioTest) + .given("partnerName", "Matthieu") + .given("newEmailAddress", "michelle@matthieu.example.org") + .doRun(); + } + + @Test + @Order(1101) + @Requires("Partner: P-31011 - Michelle Matthieu") + void shouldAddPhoneNumberToContactData() { + new AddPhoneNumberToContactData(scenarioTest) + .given("partnerName", "Matthieu") + .given("phoneNumberKeyToAdd", "mobile") + .given("phoneNumberToAdd", "+49 152 1234567") + .doRun(); + } + + @Test + @Order(1102) + @Requires("Partner: P-31011 - Michelle Matthieu") + void shouldRemovePhoneNumberFromContactData() { + new RemovePhoneNumberFromContactData(scenarioTest) + .given("partnerName", "Matthieu") + .given("phoneNumberKeyToRemove", "office") + .doRun(); + } + + @Test + @Order(1103) + @Requires("Partner: P-31010 - Test AG") + void shouldReplaceContactData() { + new ReplaceContactData(scenarioTest) + .given("partnerName", "Test AG") + .given("newContactCaption", "Test AG - China") + .given("newPostalAddress", """ + "firm": "Test AG", + "name": "Fi Zhong-Kha", + "building": "Thi Chi Koh Building", + "street": "No.2 Commercial Second Street", + "district": "Niushan Wei Wu", + "city": "Dongguan City", + "province": "Guangdong Province", + "country": "China" + """) + .given("newOfficePhoneNumber", "++15 999 654321") + .given("newEmailAddress", "norden@test-ag.example.org") + .doRun(); + } } - @Test - @Order(1020) - @Requires("Person: Test AG") - @Produces("Representative: Tracy Trust for Test AG") - void shouldAddRepresentativeToPartner() { - new AddRepresentativeToPartner(this) - .given("partnerPersonTradeName", "Test AG") - .given("representativeFamilyName", "Trust") - .given("representativeGivenName", "Tracy") - .given("representativePostalAddress", """ - "name": "Michelle Matthieu", - "street": "An der Alster 100", - "zipcode": "20000", - "city": "Hamburg", - "country": "Germany" - """) - .given("representativePhoneNumber", "+49 40 123456") - .given("representativeEMailAddress", "tracy.trust@example.org") - .doRun() - .keep(); + @Nested + @Order(12) + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class PartnerPersonScenarios { + + @Test + @Order(1201) + @Requires("Partner: P-31011 - Michelle Matthieu") + void shouldUpdatePersonData() { + new ShouldUpdatePersonData(scenarioTest) + .given("oldFamilyName", "Matthieu") + .given("newFamilyName", "Matthieu-Zhang") + .doRun(); + } } - @Test - @Order(1030) - @Requires("Person: Test AG") - @Produces("Operations-Contact: Dennis Krause for Test AG") - void shouldAddOperationsContactToPartner() { - new AddOperationsContactToPartner(this) - .given("partnerPersonTradeName", "Test AG") - .given("operationsContactFamilyName", "Krause") - .given("operationsContactGivenName", "Dennis") - .given("operationsContactPhoneNumber", "+49 9932 587741") - .given("operationsContactEMailAddress", "dennis.krause@example.org") - .doRun() - .keep(); + @Nested + @Order(20) + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class DebitorScenarios { + @Test + @Order(2010) + @Requires("Partner: P-31010 - Test AG") + @Produces("Debitor: D-3101000 - Test AG - main debitor") + void shouldCreateSelfDebitorForPartner() { + new CreateSelfDebitorForPartner(scenarioTest) + .given("partnerPersonTradeName", "Test AG") + .given("billingContactCaption", "Test AG - billing department") + .given("billingContactEmailAddress", "billing@test-ag.example.org") + .given("debitorNumberSuffix", "00") // TODO.impl: could be assigned automatically, but is not yet + .given("billable", true) + .given("vatId", "VAT123456") + .given("vatCountryCode", "DE") + .given("vatBusiness", true) + .given("vatReverseCharge", false) + .given("defaultPrefix", "tst") + .doRun() + .keep(); + } + + @Test + @Order(2011) + @Requires("Person: Test AG") + @Produces("Debitor: D-3101001 - Test AG - main debitor") + void shouldCreateExternalDebitorForPartner() { + new CreateExternalDebitorForPartner(scenarioTest) + .given("partnerPersonTradeName", "Test AG") + .given("billingContactCaption", "Billing GmbH - billing department") + .given("billingContactEmailAddress", "billing@test-ag.example.org") + .given("debitorNumberSuffix", "01") + .given("billable", true) + .given("vatId", "VAT123456") + .given("vatCountryCode", "DE") + .given("vatBusiness", true) + .given("vatReverseCharge", false) + .given("defaultPrefix", "tsx") + .doRun() + .keep(); + } + + @Test + @Order(2020) + @Requires("Person: Test AG") + @Produces(explicitly = "Debitor: D-3101000 - Test AG - delete debitor", permanent = false) + void shouldDeleteDebitor() { + new DeleteDebitor(scenarioTest) + .given("partnerNumber", "P-31020") + .given("debitorSuffix", "02") + .doRun(); + } + + @Test + @Order(2020) + @Requires("Debitor: D-3101000 - Test AG - main debitor") + @Disabled("see TODO.spec in DontDeleteDefaultDebitor") + void shouldNotDeleteDefaultDebitor() { + new DontDeleteDefaultDebitor(scenarioTest) + .given("partnerNumber", "P-31010") + .given("debitorSuffix", "00") + .doRun(); + } } - @Test - @Order(1039) - @Requires("Operations-Contact: Dennis Krause for Test AG") - void shouldRemoveOperationsContactFromPartner() { - new RemoveOperationsContactFromPartner(this) - .given("operationsContactPerson", "Dennis Krause") - .doRun(); + @Nested + @Order(31) + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class SepaMandateScenarios { + + @Test + @Order(3100) + @Requires("Debitor: D-3101000 - Test AG - main debitor") + @Produces("SEPA-Mandate: Test AG") + void shouldCreateSepaMandateForDebitor() { + new CreateSepaMandateForDebitor(scenarioTest) + // existing debitor + .given("debitorNumber", "D-3101000") + + // new sepa-mandate + .given("mandateReference", "Test AG - main debitor") + .given("mandateAgreement", "2022-10-12") + .given("mandateValidFrom", "2024-10-15") + + // new bank-account + .given("bankAccountHolder", "Test AG - debit bank account") + .given("bankAccountIBAN", "DE02701500000000594937") + .given("bankAccountBIC", "SSKMDEMM") + .doRun() + .keep(); + } + + @Test + @Order(3108) + @Requires("SEPA-Mandate: Test AG") + void shouldInvalidateSepaMandateForDebitor() { + new InvalidateSepaMandateForDebitor(scenarioTest) + .given("bankAccountIBAN", "DE02701500000000594937") + .given("mandateValidUntil", "2025-09-30") + .doRun(); + } + + @Test + @Order(3109) + @Requires("SEPA-Mandate: Test AG") + void shouldFinallyDeleteSepaMandateForDebitor() { + new FinallyDeleteSepaMandateForDebitor(scenarioTest) + .given("bankAccountIBAN", "DE02701500000000594937") + .doRun(); + } } - @Test - @Order(1090) - void shouldDeletePartner() { - new DeletePartner(this) - .given("partnerNumber", "P-31020") - .doRun(); + @Nested + @Order(40) + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class MembershipScenarios { + + @Test + @Order(4000) + @Requires("Partner: P-31010 - Test AG") + @Produces("Membership: M-3101000 - Test AG") + void shouldCreateMembershipForPartner() { + new CreateMembership(scenarioTest) + .given("partnerName", "Test AG") + .given("validFrom", "2024-10-15") + .given("newStatus", "ACTIVE") + .given("membershipFeeBillable", "true") + .doRun() + .keep(); + } + + @Test + @Order(4090) + @Requires("Membership: M-3101000 - Test AG") + void shouldCancelMembershipOfPartner() { + new CancelMembership(scenarioTest) + .given("memberNumber", "M-3101000") + .given("validTo", "2025-12-30") + .given("newStatus", "CANCELLED") + .doRun(); + } } - @Test - @Order(1100) - @Requires("Partner: P-31011 - Michelle Matthieu") - void shouldAmendContactData() { - new AmendContactData(this) - .given("partnerName", "Matthieu") - .given("newEmailAddress", "michelle@matthieu.example.org") - .doRun(); + @Nested + @Order(42) + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class CoopSharesScenarios { + + @Test + @Order(4201) + @Requires("Membership: M-3101000 - Test AG") + @Produces("Coop-Shares M-3101000 - Test AG - SUBSCRIPTION Transaction") + void shouldSubscribeCoopShares() { + new CreateCoopSharesSubscriptionTransaction(scenarioTest) + .given("memberNumber", "M-3101000") + .given("reference", "sign 2024-01-15") + .given("shareCount", 100) + .given("comment", "Signing the Membership") + .given("transactionDate", "2024-01-15") + .doRun(); + } + + @Test + @Order(4202) + @Requires("Membership: M-3101000 - Test AG") + void shouldRevertCoopSharesSubscription() { + new CreateCoopSharesRevertTransaction(scenarioTest) + .given("memberNumber", "M-3101000") + .given("comment", "reverting some incorrect transaction") + .given("dateOfIncorrectTransaction", "2024-02-15") + .doRun(); + } + + @Test + @Order(4202) + @Requires("Coop-Shares M-3101000 - Test AG - SUBSCRIPTION Transaction") + @Produces("Coop-Shares M-3101000 - Test AG - CANCELLATION Transaction") + void shouldCancelCoopSharesSubscription() { + new CreateCoopSharesCancellationTransaction(scenarioTest) + .given("memberNumber", "M-3101000") + .given("reference", "cancel 2024-01-15") + .given("sharesToCancel", 8) + .given("comment", "Cancelling 8 Shares") + .given("transactionDate", "2024-02-15") + .doRun(); + } } - @Test - @Order(1101) - @Requires("Partner: P-31011 - Michelle Matthieu") - void shouldAddPhoneNumberToContactData() { - new AddPhoneNumberToContactData(this) - .given("partnerName", "Matthieu") - .given("phoneNumberKeyToAdd", "mobile") - .given("phoneNumberToAdd", "+49 152 1234567") - .doRun(); + @Nested + @Order(43) + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class CoopAssetsScenarios { + + @Test + @Order(4301) + @Requires("Membership: M-3101000 - Test AG") + @Produces("Coop-Assets: M-3101000 - Test AG - DEPOSIT Transaction") + void shouldSubscribeCoopAssets() { + new CreateCoopAssetsDepositTransaction(scenarioTest) + .given("memberNumber", "M-3101000") + .given("reference", "sign 2024-01-15") + .given("assetValue", 100 * 64) + .given("comment", "disposal for initial shares") + .given("transactionDate", "2024-01-15") + .doRun(); + } + + @Test + @Order(4302) + @Requires("Membership: M-3101000 - Test AG") + void shouldRevertCoopAssetsSubscription() { + new CreateCoopAssetsRevertSimpleTransaction(scenarioTest) + .given("memberNumber", "M-3101000") + .given("comment", "reverting some incorrect transaction") + .given("dateOfIncorrectTransaction", "2024-02-15") + .doRun(); + } + + @Test + @Order(4303) + @Requires("Coop-Assets: M-3101000 - Test AG - DEPOSIT Transaction") + @Produces("Coop-Assets: M-3101000 - Test AG - DISBURSAL Transaction") + void shouldDisburseCoopAssets() { + new CreateCoopAssetsDisbursalTransaction(scenarioTest) + .given("memberNumber", "M-3101000") + .given("reference", "cancel 2024-01-15") + .given("valueToDisburse", 8 * 64) + .given("comment", "disbursal according to shares cancellation") + .given("transactionDate", "2024-02-15") + .doRun(); + } + + @Test + @Order(4304) + @Requires("Coop-Assets: M-3101000 - Test AG - DEPOSIT Transaction") + @Produces(explicitly = "Coop-Assets: M-3101000 - Test AG - TRANSFER Transaction", implicitly = "Membership: M-4303000 - New AG") + void shouldTransferCoopAssets() { + new CreateCoopAssetsTransferTransaction(scenarioTest) + .given("transferringMemberNumber", "M-3101000") + .given("adoptingMemberNumber", "M-4303000") + .given("reference", "transfer 2024-12-31") + .given("valueToTransfer", 2 * 64) + .given("comment", "transfer assets from M-3101000 to M-4303000") + .given("transactionDate", "2024-12-31") + .doRun(); + } + + @Test + @Order(4305) + @Requires("Coop-Assets: M-3101000 - Test AG - TRANSFER Transaction") + void shouldRevertCoopAssetsTransferIncludingRelatedAssetAdoption() { + new CreateCoopAssetsRevertTransferTransaction(scenarioTest) + .given("transferringMemberNumber", "M-3101000") + .given("adoptingMemberNumber", "M-4303000") + .given("transferredValue", 2 * 64) + .given("comment", "reverting some incorrect transfer transaction") + .given("dateOfIncorrectTransaction", "2024-02-15") + .doRun(); + } } - @Test - @Order(1102) - @Requires("Partner: P-31011 - Michelle Matthieu") - void shouldRemovePhoneNumberFromContactData() { - new RemovePhoneNumberFromContactData(this) - .given("partnerName", "Matthieu") - .given("phoneNumberKeyToRemove", "office") - .doRun(); - } + @Nested + @Order(50) + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class SubscriptionScenarios { - @Test - @Order(1103) - @Requires("Partner: P-31010 - Test AG") - void shouldReplaceContactData() { - new ReplaceContactData(this) - .given("partnerName", "Test AG") - .given("newContactCaption", "Test AG - China") - .given("newPostalAddress", """ - "firm": "Test AG", - "name": "Fi Zhong-Kha", - "building": "Thi Chi Koh Building", - "street": "No.2 Commercial Second Street", - "district": "Niushan Wei Wu", - "city": "Dongguan City", - "province": "Guangdong Province", - "country": "China" - """) - .given("newOfficePhoneNumber", "++15 999 654321") - .given("newEmailAddress", "norden@test-ag.example.org") - .doRun(); - } + @Test + @Order(5000) + @Requires("Person: Test AG") + @Produces("Subscription: Michael Miller to operations-announce") + void shouldSubscribeNewPersonAndContactToMailinglist() { + new SubscribeToMailinglist(scenarioTest) + // TODO.spec: do we need the personType? or is an operational contact always a natural person? what about distribution lists? + .given("partnerPersonTradeName", "Test AG") + .given("subscriberFamilyName", "Miller") + .given("subscriberGivenName", "Michael") + .given("subscriberEMailAddress", "michael.miller@example.org") + .given("mailingList", "operations-announce") + .doRun() + .keep(); + } - @Test - @Order(1201) - @Requires("Partner: P-31011 - Michelle Matthieu") - void shouldUpdatePersonData() { - new ShouldUpdatePersonData(this) - .given("oldFamilyName", "Matthieu") - .given("newFamilyName", "Matthieu-Zhang") - .doRun(); - } - - @Test - @Order(2010) - @Requires("Partner: P-31010 - Test AG") - @Produces("Debitor: D-3101000 - Test AG - main debitor") - void shouldCreateSelfDebitorForPartner() { - new CreateSelfDebitorForPartner(this) - .given("partnerPersonTradeName", "Test AG") - .given("billingContactCaption", "Test AG - billing department") - .given("billingContactEmailAddress", "billing@test-ag.example.org") - .given("debitorNumberSuffix", "00") // TODO.impl: could be assigned automatically, but is not yet - .given("billable", true) - .given("vatId", "VAT123456") - .given("vatCountryCode", "DE") - .given("vatBusiness", true) - .given("vatReverseCharge", false) - .given("defaultPrefix", "tst") - .doRun() - .keep(); - } - - @Test - @Order(2011) - @Requires("Person: Test AG") - @Produces("Debitor: D-3101001 - Test AG - main debitor") - void shouldCreateExternalDebitorForPartner() { - new CreateExternalDebitorForPartner(this) - .given("partnerPersonTradeName", "Test AG") - .given("billingContactCaption", "Billing GmbH - billing department") - .given("billingContactEmailAddress", "billing@test-ag.example.org") - .given("debitorNumberSuffix", "01") - .given("billable", true) - .given("vatId", "VAT123456") - .given("vatCountryCode", "DE") - .given("vatBusiness", true) - .given("vatReverseCharge", false) - .given("defaultPrefix", "tsx") - .doRun() - .keep(); - } - - @Test - @Order(2020) - @Requires("Person: Test AG") - @Produces(explicitly = "Debitor: D-3101000 - Test AG - delete debitor", permanent = false) - void shouldDeleteDebitor() { - new DeleteDebitor(this) - .given("partnerNumber", "P-31020") - .given("debitorSuffix", "02") - .doRun(); - } - - @Test - @Order(2020) - @Requires("Debitor: D-3101000 - Test AG - main debitor") - @Disabled("see TODO.spec in DontDeleteDefaultDebitor") - void shouldNotDeleteDefaultDebitor() { - new DontDeleteDefaultDebitor(this) - .given("partnerNumber", "P-31010") - .given("debitorSuffix", "00") - .doRun(); - } - - @Test - @Order(3100) - @Requires("Debitor: D-3101000 - Test AG - main debitor") - @Produces("SEPA-Mandate: Test AG") - void shouldCreateSepaMandateForDebitor() { - new CreateSepaMandateForDebitor(this) - // existing debitor - .given("debitorNumber", "D-3101000") - - // new sepa-mandate - .given("mandateReference", "Test AG - main debitor") - .given("mandateAgreement", "2022-10-12") - .given("mandateValidFrom", "2024-10-15") - - // new bank-account - .given("bankAccountHolder", "Test AG - debit bank account") - .given("bankAccountIBAN", "DE02701500000000594937") - .given("bankAccountBIC", "SSKMDEMM") - .doRun() - .keep(); - } - - @Test - @Order(3108) - @Requires("SEPA-Mandate: Test AG") - void shouldInvalidateSepaMandateForDebitor() { - new InvalidateSepaMandateForDebitor(this) - .given("bankAccountIBAN", "DE02701500000000594937") - .given("mandateValidUntil", "2025-09-30") - .doRun(); - } - - @Test - @Order(3109) - @Requires("SEPA-Mandate: Test AG") - void shouldFinallyDeleteSepaMandateForDebitor() { - new FinallyDeleteSepaMandateForDebitor(this) - .given("bankAccountIBAN", "DE02701500000000594937") - .doRun(); - } - - @Test - @Order(4000) - @Requires("Partner: P-31010 - Test AG") - @Produces("Membership: M-3101000 - Test AG") - void shouldCreateMembershipForPartner() { - new CreateMembership(this) - .given("partnerName", "Test AG") - .given("validFrom", "2024-10-15") - .given("newStatus", "ACTIVE") - .given("membershipFeeBillable", "true") - .doRun() - .keep(); - } - - @Test - @Order(4201) - @Requires("Membership: M-3101000 - Test AG") - @Produces("Coop-Shares M-3101000 - Test AG - SUBSCRIPTION Transaction") - void shouldSubscribeCoopShares() { - new CreateCoopSharesSubscriptionTransaction(this) - .given("memberNumber", "M-3101000") - .given("reference", "sign 2024-01-15") - .given("shareCount", 100) - .given("comment", "Signing the Membership") - .given("transactionDate", "2024-01-15") - .doRun(); - } - - @Test - @Order(4202) - @Requires("Membership: M-3101000 - Test AG") - void shouldRevertCoopSharesSubscription() { - new CreateCoopSharesRevertTransaction(this) - .given("memberNumber", "M-3101000") - .given("comment", "reverting some incorrect transaction") - .given("dateOfIncorrectTransaction", "2024-02-15") - .doRun(); - } - - @Test - @Order(4202) - @Requires("Coop-Shares M-3101000 - Test AG - SUBSCRIPTION Transaction") - @Produces("Coop-Shares M-3101000 - Test AG - CANCELLATION Transaction") - void shouldCancelCoopSharesSubscription() { - new CreateCoopSharesCancellationTransaction(this) - .given("memberNumber", "M-3101000") - .given("reference", "cancel 2024-01-15") - .given("sharesToCancel", 8) - .given("comment", "Cancelling 8 Shares") - .given("transactionDate", "2024-02-15") - .doRun(); - } - - @Test - @Order(4301) - @Requires("Membership: M-3101000 - Test AG") - @Produces("Coop-Assets M-3101000 - Test AG - DEPOSIT Transaction") - void shouldSubscribeCoopAssets() { - new CreateCoopAssetsDepositTransaction(this) - .given("memberNumber", "M-3101000") - .given("reference", "sign 2024-01-15") - .given("assetValue", 100 * 64) - .given("comment", "disposal for initial shares") - .given("transactionDate", "2024-01-15") - .doRun(); - } - - @Test - @Order(4302) - @Requires("Membership: M-3101000 - Test AG") - void shouldRevertCoopAssetsSubscription() { - new CreateCoopAssetsRevertSimpleTransaction(this) - .given("memberNumber", "M-3101000") - .given("comment", "reverting some incorrect transaction") - .given("dateOfIncorrectTransaction", "2024-02-15") - .doRun(); - } - - @Test - @Order(4303) - @Requires("Coop-Assets M-3101000 - Test AG - DEPOSIT Transaction") - @Produces("Coop-Assets M-3101000 - Test AG - DISBURSAL Transaction") - void shouldDisburseCoopAssets() { - new CreateCoopAssetsDisbursalTransaction(this) - .given("memberNumber", "M-3101000") - .given("reference", "cancel 2024-01-15") - .given("valueToDisburse", 8 * 64) - .given("comment", "disbursal according to shares cancellation") - .given("transactionDate", "2024-02-15") - .doRun(); - } - - @Test - @Order(4304) - @Requires("Coop-Assets M-3101000 - Test AG - DEPOSIT Transaction") - @Produces(explicitly = "Coop-Assets M-3101000 - Test AG - TRANSFER Transaction", implicitly = "Membership M-4303000") - void shouldTransferCoopAssets() { - new CreateCoopAssetsTransferTransaction(this) - .given("transferringMemberNumber", "M-3101000") - .given("adoptingMemberNumber", "M-4303000") - .given("reference", "transfer 2024-12-31") - .given("valueToTransfer", 2 * 64) - .given("comment", "transfer assets from M-3101000 to M-4303000") - .given("transactionDate", "2024-12-31") - .doRun(); - } - - @Test - @Order(4305) - @Requires("Membership M-4303000") - void shouldRevertCoopAssetsTransferIncludingRelatedAssetAdoption() { - new CreateCoopAssetsRevertTransferTransaction(this) - .given("transferringMemberNumber", "M-3101000") - .given("adoptingMemberNumber", "M-4303000") - .given("transferredValue", 2*64) - .given("comment", "reverting some incorrect transfer transaction") - .given("dateOfIncorrectTransaction", "2024-02-15") - .doRun(); - } - - @Test - @Order(4900) - @Requires("Membership: M-3101000 - Test AG") - void shouldCancelMembershipOfPartner() { - new CancelMembership(this) - .given("memberNumber", "M-3101000") - .given("validTo", "2025-12-30") - .given("newStatus", "CANCELLED") - .doRun(); - } - - @Test - @Order(5000) - @Requires("Person: Test AG") - @Produces("Subscription: Michael Miller to operations-announce") - void shouldSubscribeNewPersonAndContactToMailinglist() { - new SubscribeToMailinglist(this) - // TODO.spec: do we need the personType? or is an operational contact always a natural person? what about distribution lists? - .given("partnerPersonTradeName", "Test AG") - .given("subscriberFamilyName", "Miller") - .given("subscriberGivenName", "Michael") - .given("subscriberEMailAddress", "michael.miller@example.org") - .given("mailingList", "operations-announce") - .doRun() - .keep(); - } - - @Test - @Order(5001) - @Requires("Subscription: Michael Miller to operations-announce") - void shouldUnsubscribeNewPersonAndContactToMailinglist() { - new UnsubscribeFromMailinglist(this) - .given("mailingList", "operations-announce") - .given("subscriberEMailAddress", "michael.miller@example.org") - .doRun(); + @Test + @Order(5001) + @Requires("Subscription: Michael Miller to operations-announce") + void shouldUnsubscribeNewPersonAndContactToMailinglist() { + new UnsubscribeFromMailinglist(scenarioTest) + .given("mailingList", "operations-announce") + .given("subscriberEMailAddress", "michael.miller@example.org") + .doRun(); + } } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/Produces.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/Produces.java deleted file mode 100644 index 5d24fd2c..00000000 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/Produces.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.hostsharing.hsadminng.hs.office.scenarios; - -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -@Target(METHOD) -@Retention(RUNTIME) -public @interface Produces { - String value() default ""; // same as explicitly, makes it possible to omit the property name - String explicitly() default ""; // same as value - String[] implicitly() default {}; - boolean permanent() default true; // false means that the object gets deleted again in the process -} diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/ScenarioTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/ScenarioTest.java deleted file mode 100644 index 4e3557eb..00000000 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/ScenarioTest.java +++ /dev/null @@ -1,200 +0,0 @@ -package net.hostsharing.hsadminng.hs.office.scenarios; - -import lombok.SneakyThrows; -import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; -import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository; -import net.hostsharing.hsadminng.hs.office.scenarios.TemplateResolver.Resolver; -import net.hostsharing.hsadminng.lambda.Reducer; -import net.hostsharing.hsadminng.rbac.context.ContextBasedTest; -import net.hostsharing.hsadminng.rbac.test.JpaAttempt; -import org.apache.commons.collections4.SetUtils; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.TestInfo; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.testcontainers.shaded.org.apache.commons.lang3.ObjectUtils; - -import java.lang.reflect.Method; -import java.math.BigDecimal; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.stream.Collectors; - -import static java.util.Arrays.asList; -import static java.util.Optional.ofNullable; -import static net.hostsharing.hsadminng.hs.office.scenarios.TemplateResolver.Resolver.DROP_COMMENTS; -import static net.hostsharing.hsadminng.hs.office.scenarios.TemplateResolver.Resolver.DROP_COMMENTS; -import static org.assertj.core.api.Assertions.assertThat; - -public abstract class ScenarioTest extends ContextBasedTest { - - final static String RUN_AS_USER = "superuser-alex@hostsharing.net"; // TODO.test: use global:AGENT when implemented - - record Alias>(Class useCase, UUID uuid) { - - @Override - public String toString() { - return ObjectUtils.toString(uuid); - } - - } - private final static Map> aliases = new HashMap<>(); - - private final static Map properties = new HashMap<>(); - public final TestReport testReport = new TestReport(aliases); - - @LocalServerPort - Integer port; - - @Autowired - HsOfficePersonRepository personRepo; - - @Autowired - JpaAttempt jpaAttempt; - - @SneakyThrows - @BeforeEach - void init(final TestInfo testInfo) { - createHostsharingPerson(); - try { - testInfo.getTestMethod().ifPresent(this::callRequiredProducers); - testReport.createTestLogMarkdownFile(testInfo); - } catch (Exception exc) { - throw exc; - } - } - - @AfterEach - void cleanup() { // final TestInfo testInfo - properties.clear(); - testReport.close(); - } - - private void createHostsharingPerson() { - jpaAttempt.transacted(() -> - { - context.define("superuser-alex@hostsharing.net"); - aliases.put( - "Person: Hostsharing eG", - new Alias<>( - null, - personRepo.findPersonByOptionalNameLike("Hostsharing eG") - .stream() - .map(HsOfficePersonEntity::getUuid) - .reduce(Reducer::toSingleElement).orElseThrow()) - ); - } - ); - } - - @SneakyThrows - private void callRequiredProducers(final Method currentTestMethod) { - final var testMethodRequired = Optional.of(currentTestMethod) - .map(m -> m.getAnnotation(Requires.class)) - .map(Requires::value) - .orElse(null); - if (testMethodRequired != null) { - for (Method potentialProducerMethod : getClass().getDeclaredMethods()) { - final var producesAnnot = potentialProducerMethod.getAnnotation(Produces.class); - if (producesAnnot != null) { - final var testMethodProduces = allOf( - producesAnnot.value(), - producesAnnot.explicitly(), - producesAnnot.implicitly()); - // @formatter:off - if ( // that method can produce something required - testMethodProduces.contains(testMethodRequired) && - - // and it does not produce anything we already have (would cause errors) - SetUtils.intersection(testMethodProduces, knowVariables().keySet()).isEmpty() - ) { - assertThat(producesAnnot.permanent()).as("cannot depend on non-permanent producer: " + potentialProducerMethod); - - // then we recursively produce the pre-requisites of the producer method - callRequiredProducers(potentialProducerMethod); - - // and finally we call the producer method - potentialProducerMethod.invoke(this); - } - // @formatter:on - } - } - } - } - - private Set allOf(final String value, final String explicitly, final String[] implicitly) { - final var all = new HashSet(); - if (!value.isEmpty()) { - all.add(value); - } - if (!explicitly.isEmpty()) { - all.add(explicitly); - } - all.addAll(asList(implicitly)); - return all; - } - - static boolean containsAlias(final String alias) { - return aliases.containsKey(alias); - } - - static UUID uuid(final String nameWithPlaceholders) { - final var resolvedName = resolve(nameWithPlaceholders, DROP_COMMENTS); - final UUID alias = ofNullable(knowVariables().get(resolvedName)).filter(v -> v instanceof UUID).map(UUID.class::cast).orElse(null); - assertThat(alias).as("alias '" + resolvedName + "' not found in aliases nor in properties [" + - knowVariables().keySet().stream().map(v -> "'" + v + "'").collect(Collectors.joining(", ")) + "]" - ).isNotNull(); - return alias; - } - - static void putAlias(final String name, final Alias value) { - aliases.put(name, value); - } - - static void putProperty(final String name, final Object value) { - properties.put(name, (value instanceof String string) ? resolveTyped(string) : value); - } - - static void removeProperty(final String propName) { - properties.remove(propName); - } - - static Map knowVariables() { - final var map = new LinkedHashMap(); - ScenarioTest.aliases.forEach((key, value) -> map.put(key, value.uuid())); - map.putAll(ScenarioTest.properties); - return map; - } - - public static String resolve(final String text, final Resolver resolver) { - final var resolved = new TemplateResolver(text, ScenarioTest.knowVariables()).resolve(resolver); - return resolved; - } - - public static Object resolveTyped(final String resolvableText) { - final var resolved = resolve(resolvableText, DROP_COMMENTS); - try { - return UUID.fromString(resolved); - } catch (final IllegalArgumentException e) { - // ignore and just use the String value - } - return resolved; - } - - public static T resolveTyped(final String resolvableText, final Class valueType) { - final var resolvedValue = resolve(resolvableText, DROP_COMMENTS); - if (valueType == BigDecimal.class) { - //noinspection unchecked - return (T) new BigDecimal(resolvedValue); - } - //noinspection unchecked - return (T) resolvedValue; - } - -} diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/contact/AddPhoneNumberToContactData.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/contact/AddPhoneNumberToContactData.java index 5f8d266d..501a2a6d 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/contact/AddPhoneNumberToContactData.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/contact/AddPhoneNumberToContactData.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.scenarios.contact; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; import org.springframework.http.HttpStatus; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/contact/AmendContactData.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/contact/AmendContactData.java index 0c0e3021..5f05b6a8 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/contact/AmendContactData.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/contact/AmendContactData.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.scenarios.contact; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; import org.springframework.http.HttpStatus; import static io.restassured.http.ContentType.JSON; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/contact/RemovePhoneNumberFromContactData.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/contact/RemovePhoneNumberFromContactData.java index 715e1832..03a8e07a 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/contact/RemovePhoneNumberFromContactData.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/contact/RemovePhoneNumberFromContactData.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.scenarios.contact; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; import org.springframework.http.HttpStatus; import static io.restassured.http.ContentType.JSON; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/contact/ReplaceContactData.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/contact/ReplaceContactData.java index 2638a4e5..d7a0569a 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/contact/ReplaceContactData.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/contact/ReplaceContactData.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.scenarios.contact; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; import static io.restassured.http.ContentType.JSON; import static org.springframework.http.HttpStatus.CREATED; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/CreateExternalDebitorForPartner.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/CreateExternalDebitorForPartner.java index cf525c30..f05a9e47 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/CreateExternalDebitorForPartner.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/CreateExternalDebitorForPartner.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.scenarios.debitor; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; import net.hostsharing.hsadminng.hs.office.scenarios.person.CreatePerson; import static io.restassured.http.ContentType.JSON; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/CreateSelfDebitorForPartner.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/CreateSelfDebitorForPartner.java index 41b40ee6..daa00811 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/CreateSelfDebitorForPartner.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/CreateSelfDebitorForPartner.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.scenarios.debitor; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; import static io.restassured.http.ContentType.JSON; import static org.springframework.http.HttpStatus.CREATED; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/CreateSepaMandateForDebitor.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/CreateSepaMandateForDebitor.java index 549848f1..b50cc7c9 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/CreateSepaMandateForDebitor.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/CreateSepaMandateForDebitor.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.scenarios.debitor; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; import static io.restassured.http.ContentType.JSON; import static org.springframework.http.HttpStatus.CREATED; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/DeleteDebitor.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/DeleteDebitor.java index 84e9cd30..2ff0484d 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/DeleteDebitor.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/DeleteDebitor.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.scenarios.debitor; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; import org.springframework.http.HttpStatus; public class DeleteDebitor extends UseCase { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/DontDeleteDefaultDebitor.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/DontDeleteDefaultDebitor.java index e5459c88..00d7fa79 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/DontDeleteDefaultDebitor.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/DontDeleteDefaultDebitor.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.scenarios.debitor; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; import org.springframework.http.HttpStatus; public class DontDeleteDefaultDebitor extends UseCase { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/FinallyDeleteSepaMandateForDebitor.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/FinallyDeleteSepaMandateForDebitor.java index 224a98f3..7dff8d6a 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/FinallyDeleteSepaMandateForDebitor.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/FinallyDeleteSepaMandateForDebitor.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.scenarios.debitor; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; import org.springframework.http.HttpStatus; import static io.restassured.http.ContentType.JSON; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/InvalidateSepaMandateForDebitor.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/InvalidateSepaMandateForDebitor.java index 3af160c7..501e9f06 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/InvalidateSepaMandateForDebitor.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/debitor/InvalidateSepaMandateForDebitor.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.scenarios.debitor; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; import static io.restassured.http.ContentType.JSON; import static org.springframework.http.HttpStatus.OK; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/CancelMembership.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/CancelMembership.java index 23f718b5..d5d00900 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/CancelMembership.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/CancelMembership.java @@ -1,8 +1,8 @@ package net.hostsharing.hsadminng.hs.office.scenarios.membership; import io.restassured.http.ContentType; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; import org.springframework.http.HttpStatus; import static io.restassured.http.ContentType.JSON; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/CreateMembership.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/CreateMembership.java index 890dfedf..63541e09 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/CreateMembership.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/CreateMembership.java @@ -1,8 +1,8 @@ package net.hostsharing.hsadminng.hs.office.scenarios.membership; import io.restassured.http.ContentType; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; import org.springframework.http.HttpStatus; import static io.restassured.http.ContentType.JSON; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsDepositTransaction.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsDepositTransaction.java index af9b01a1..7c7a05ad 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsDepositTransaction.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsDepositTransaction.java @@ -1,6 +1,6 @@ package net.hostsharing.hsadminng.hs.office.scenarios.membership.coopassets; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; public class CreateCoopAssetsDepositTransaction extends CreateCoopAssetsTransaction { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsDisbursalTransaction.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsDisbursalTransaction.java index 542f75d8..e605782f 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsDisbursalTransaction.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsDisbursalTransaction.java @@ -1,6 +1,6 @@ package net.hostsharing.hsadminng.hs.office.scenarios.membership.coopassets; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; public class CreateCoopAssetsDisbursalTransaction extends CreateCoopAssetsTransaction { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsRevertSimpleTransaction.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsRevertSimpleTransaction.java index 0ba384a1..45cba19d 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsRevertSimpleTransaction.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsRevertSimpleTransaction.java @@ -1,6 +1,6 @@ package net.hostsharing.hsadminng.hs.office.scenarios.membership.coopassets; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; public class CreateCoopAssetsRevertSimpleTransaction extends CreateCoopAssetsTransaction { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsRevertTransferTransaction.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsRevertTransferTransaction.java index 56ca670c..a1680682 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsRevertTransferTransaction.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsRevertTransferTransaction.java @@ -1,13 +1,13 @@ package net.hostsharing.hsadminng.hs.office.scenarios.membership.coopassets; import io.restassured.http.ContentType; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; import org.springframework.http.HttpStatus; import java.math.BigDecimal; -import static net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest.resolveTyped; +import static net.hostsharing.hsadminng.hs.scenarios.ScenarioTest.resolveTyped; public class CreateCoopAssetsRevertTransferTransaction extends CreateCoopAssetsTransaction { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsTransaction.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsTransaction.java index fbe4b8d5..beb78b52 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsTransaction.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsTransaction.java @@ -1,8 +1,8 @@ package net.hostsharing.hsadminng.hs.office.scenarios.membership.coopassets; import io.restassured.http.ContentType; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; import org.springframework.http.HttpStatus; import static io.restassured.http.ContentType.JSON; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsTransferTransaction.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsTransferTransaction.java index 9cfe871f..bf43bd85 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsTransferTransaction.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsTransferTransaction.java @@ -1,10 +1,10 @@ package net.hostsharing.hsadminng.hs.office.scenarios.membership.coopassets; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; import net.hostsharing.hsadminng.hs.office.scenarios.membership.CreateMembership; import net.hostsharing.hsadminng.hs.office.scenarios.partner.CreatePartner; -import static net.hostsharing.hsadminng.hs.office.scenarios.TemplateResolver.Resolver.DROP_COMMENTS; +import static net.hostsharing.hsadminng.hs.scenarios.TemplateResolver.Resolver.DROP_COMMENTS; public class CreateCoopAssetsTransferTransaction extends CreateCoopAssetsTransaction { @@ -19,7 +19,7 @@ public class CreateCoopAssetsTransferTransaction extends CreateCoopAssetsTransac .given("emailAddress", "board-of-directors@new-ag.example.org") ); - requires("Membership: New AG", alias -> new CreateMembership(testSuite) + requires("Membership: %{adoptingMemberNumber} - New AG", alias -> new CreateMembership(testSuite) .given("memberNumber", toPartnerNumber("%{adoptingMemberNumber}")) .given("partnerName", "New AG") .given("validFrom", "2024-11-15") diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopshares/CreateCoopSharesCancellationTransaction.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopshares/CreateCoopSharesCancellationTransaction.java index 16549b36..19f02820 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopshares/CreateCoopSharesCancellationTransaction.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopshares/CreateCoopSharesCancellationTransaction.java @@ -1,6 +1,6 @@ package net.hostsharing.hsadminng.hs.office.scenarios.membership.coopshares; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; public class CreateCoopSharesCancellationTransaction extends CreateCoopSharesTransaction { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopshares/CreateCoopSharesRevertTransaction.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopshares/CreateCoopSharesRevertTransaction.java index 8464393a..4f2a8555 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopshares/CreateCoopSharesRevertTransaction.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopshares/CreateCoopSharesRevertTransaction.java @@ -1,6 +1,6 @@ package net.hostsharing.hsadminng.hs.office.scenarios.membership.coopshares; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; public class CreateCoopSharesRevertTransaction extends CreateCoopSharesTransaction { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopshares/CreateCoopSharesSubscriptionTransaction.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopshares/CreateCoopSharesSubscriptionTransaction.java index 84db07dd..79f79285 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopshares/CreateCoopSharesSubscriptionTransaction.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopshares/CreateCoopSharesSubscriptionTransaction.java @@ -1,6 +1,6 @@ package net.hostsharing.hsadminng.hs.office.scenarios.membership.coopshares; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; public class CreateCoopSharesSubscriptionTransaction extends CreateCoopSharesTransaction { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopshares/CreateCoopSharesTransaction.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopshares/CreateCoopSharesTransaction.java index cd8d9c14..a70cbdf5 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopshares/CreateCoopSharesTransaction.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopshares/CreateCoopSharesTransaction.java @@ -1,8 +1,8 @@ package net.hostsharing.hsadminng.hs.office.scenarios.membership.coopshares; import io.restassured.http.ContentType; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; import org.springframework.http.HttpStatus; import static io.restassured.http.ContentType.JSON; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/AddOperationsContactToPartner.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/AddOperationsContactToPartner.java index f862c782..4ea68cba 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/AddOperationsContactToPartner.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/AddOperationsContactToPartner.java @@ -1,8 +1,8 @@ package net.hostsharing.hsadminng.hs.office.scenarios.partner; import io.restassured.http.ContentType; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; import org.springframework.http.HttpStatus; import static io.restassured.http.ContentType.JSON; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/AddRepresentativeToPartner.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/AddRepresentativeToPartner.java index 0e4a28c5..41732d3a 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/AddRepresentativeToPartner.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/AddRepresentativeToPartner.java @@ -1,8 +1,8 @@ package net.hostsharing.hsadminng.hs.office.scenarios.partner; import io.restassured.http.ContentType; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; import org.springframework.http.HttpStatus; import static io.restassured.http.ContentType.JSON; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/CreatePartner.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/CreatePartner.java index 3896bbf6..87ca7c87 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/CreatePartner.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/CreatePartner.java @@ -1,8 +1,8 @@ package net.hostsharing.hsadminng.hs.office.scenarios.partner; import io.restassured.http.ContentType; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; import org.springframework.http.HttpStatus; import static io.restassured.http.ContentType.JSON; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/DeletePartner.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/DeletePartner.java index 4453d959..df0a0c57 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/DeletePartner.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/DeletePartner.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.scenarios.partner; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; import org.springframework.http.HttpStatus; public class DeletePartner extends UseCase { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/person/CreatePerson.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/person/CreatePerson.java index 4a43503c..39e39068 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/person/CreatePerson.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/person/CreatePerson.java @@ -1,8 +1,8 @@ package net.hostsharing.hsadminng.hs.office.scenarios.person; import io.restassured.http.ContentType; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; import org.springframework.http.HttpStatus; public class CreatePerson extends UseCase { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/person/ShouldUpdatePersonData.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/person/ShouldUpdatePersonData.java index 04a61c5f..1d092936 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/person/ShouldUpdatePersonData.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/person/ShouldUpdatePersonData.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.scenarios.person; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; import org.springframework.http.HttpStatus; import static io.restassured.http.ContentType.JSON; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/subscription/RemoveOperationsContactFromPartner.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/subscription/RemoveOperationsContactFromPartner.java index 2190e6d9..905c3a72 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/subscription/RemoveOperationsContactFromPartner.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/subscription/RemoveOperationsContactFromPartner.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.scenarios.subscription; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; import static io.restassured.http.ContentType.JSON; import static org.springframework.http.HttpStatus.NOT_FOUND; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/subscription/SubscribeToMailinglist.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/subscription/SubscribeToMailinglist.java index 7cca9ba4..c524fb18 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/subscription/SubscribeToMailinglist.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/subscription/SubscribeToMailinglist.java @@ -1,8 +1,8 @@ package net.hostsharing.hsadminng.hs.office.scenarios.subscription; import io.restassured.http.ContentType; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; import org.springframework.http.HttpStatus; import static io.restassured.http.ContentType.JSON; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/subscription/UnsubscribeFromMailinglist.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/subscription/UnsubscribeFromMailinglist.java index dfb17ea1..4a6b34cb 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/subscription/UnsubscribeFromMailinglist.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/subscription/UnsubscribeFromMailinglist.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.scenarios.subscription; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase; -import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest; +import net.hostsharing.hsadminng.hs.scenarios.UseCase; +import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest; import static io.restassured.http.ContentType.JSON; import static org.springframework.http.HttpStatus.NO_CONTENT; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/JsonOptional.java b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/JsonOptional.java similarity index 95% rename from src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/JsonOptional.java rename to src/test/java/net/hostsharing/hsadminng/hs/scenarios/JsonOptional.java index 2a169fe2..f5c829c6 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/JsonOptional.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/JsonOptional.java @@ -1,4 +1,4 @@ -package net.hostsharing.hsadminng.hs.office.scenarios; +package net.hostsharing.hsadminng.hs.scenarios; public final class JsonOptional { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/PathAssertion.java b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/PathAssertion.java similarity index 84% rename from src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/PathAssertion.java rename to src/test/java/net/hostsharing/hsadminng/hs/scenarios/PathAssertion.java index e7aac280..4a51932e 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/PathAssertion.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/PathAssertion.java @@ -1,10 +1,10 @@ -package net.hostsharing.hsadminng.hs.office.scenarios; +package net.hostsharing.hsadminng.hs.scenarios; -import net.hostsharing.hsadminng.hs.office.scenarios.UseCase.HttpResponse; +import net.hostsharing.hsadminng.hs.scenarios.UseCase.HttpResponse; import java.util.function.Consumer; -import static net.hostsharing.hsadminng.hs.office.scenarios.TemplateResolver.Resolver.DROP_COMMENTS; +import static net.hostsharing.hsadminng.hs.scenarios.TemplateResolver.Resolver.DROP_COMMENTS; import static org.junit.jupiter.api.Assertions.fail; public class PathAssertion { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/scenarios/Produces.java b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/Produces.java new file mode 100644 index 00000000..181d6648 --- /dev/null +++ b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/Produces.java @@ -0,0 +1,46 @@ +package net.hostsharing.hsadminng.hs.scenarios; + +import lombok.experimental.UtilityClass; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.util.HashSet; +import java.util.Set; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.util.Arrays.asList; + +@Target(METHOD) +@Retention(RUNTIME) +public @interface Produces { + String value() default ""; // same as explicitly, makes it possible to omit the property name + String explicitly() default ""; // same as value + String[] implicitly() default {}; + boolean permanent() default true; // false means that the object gets deleted again in the process + + @UtilityClass + final class Aggregator { + + public static Set producedAliases(final Produces producesAnnot) { + return allOf( + producesAnnot.value(), + producesAnnot.explicitly(), + producesAnnot.implicitly()); + } + + + + private Set allOf(final String value, final String explicitly, final String[] implicitly) { + final var all = new HashSet(); + if (!value.isEmpty()) { + all.add(value); + } + if (!explicitly.isEmpty()) { + all.add(explicitly); + } + all.addAll(asList(implicitly)); + return all; + } + } +} diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/README.md b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/README.md similarity index 100% rename from src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/README.md rename to src/test/java/net/hostsharing/hsadminng/hs/scenarios/README.md diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/Requires.java b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/Requires.java similarity index 83% rename from src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/Requires.java rename to src/test/java/net/hostsharing/hsadminng/hs/scenarios/Requires.java index 59ea21ec..d0a3ed5a 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/Requires.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/Requires.java @@ -1,4 +1,4 @@ -package net.hostsharing.hsadminng.hs.office.scenarios; +package net.hostsharing.hsadminng.hs.scenarios; import java.lang.annotation.Retention; import java.lang.annotation.Target; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/scenarios/ScenarioTest.java b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/ScenarioTest.java new file mode 100644 index 00000000..d1da4bb1 --- /dev/null +++ b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/ScenarioTest.java @@ -0,0 +1,257 @@ +package net.hostsharing.hsadminng.hs.scenarios; + +import lombok.SneakyThrows; +import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; +import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository; +import net.hostsharing.hsadminng.lambda.Reducer; +import net.hostsharing.hsadminng.rbac.context.ContextBasedTest; +import net.hostsharing.hsadminng.rbac.test.JpaAttempt; +import net.hostsharing.hsadminng.hs.scenarios.TemplateResolver.Resolver; +import org.apache.commons.collections4.SetUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.TestInfo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.web.server.LocalServerPort; + +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Stack; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static java.util.Arrays.stream; +import static java.util.Optional.ofNullable; +import static net.hostsharing.hsadminng.hs.scenarios.Produces.Aggregator.producedAliases; +import static net.hostsharing.hsadminng.hs.scenarios.TemplateResolver.Resolver.DROP_COMMENTS; +import static org.apache.commons.lang3.StringUtils.isNotBlank; +import static org.assertj.core.api.Assertions.assertThat; + +public abstract class ScenarioTest extends ContextBasedTest { + + final static String RUN_AS_USER = "superuser-alex@hostsharing.net"; // TODO.test: use global:AGENT when implemented + + private final Stack currentTestMethodProduces = new Stack<>(); + + protected ScenarioTest scenarioTest = this; + + Optional takeProducedAlias() { + if (currentTestMethodProduces.isEmpty()) { + return Optional.empty(); + } + return Optional.of(currentTestMethodProduces.pop()); + } + + record Alias>(Class useCase, UUID uuid) { + + @Override + public String toString() { + return Objects.toString(uuid); + } + + } + + private final static Map> aliases = new HashMap<>(); + + private final static Map properties = new HashMap<>(); + public final TestReport testReport = new TestReport(aliases); + + @LocalServerPort + Integer port; + + @Autowired + HsOfficePersonRepository personRepo; + + @Autowired + JpaAttempt jpaAttempt; + + @SneakyThrows + @BeforeEach + void beforeScenario(final TestInfo testInfo) { + createHostsharingPerson(); + try { + testInfo.getTestMethod().ifPresent(currentTestMethod -> { + callRequiredProducers(currentTestMethod); + keepProducesAlias(currentTestMethod); + }); + testReport.createTestLogMarkdownFile(testInfo); + } catch (Exception exc) { + throw exc; + } + } + + @AfterEach + void afterScenario(final TestInfo testInfo) { // final TestInfo testInfo + testInfo.getTestMethod() .ifPresent(currentTestMethod -> { + // FIXME: extract to method + final var producesAnnot = currentTestMethod.getAnnotation(Produces.class); + if (producesAnnot != null && producesAnnot.permanent()) { + final var testMethodProduces = producedAliases(producesAnnot); + testMethodProduces.forEach(declaredAlias -> + assertThat(knowVariables().containsKey(declaredAlias)) + .as("@Producer method " + currentTestMethod.getName() + + " did declare but not produce \"" + declaredAlias + "\"") + .isTrue() ); + } + }); + + properties.clear(); + testReport.close(); + } + + private void createHostsharingPerson() { + jpaAttempt.transacted(() -> + { + context.define("superuser-alex@hostsharing.net"); + aliases.put( + "Person: Hostsharing eG", + new Alias<>( + null, + personRepo.findPersonByOptionalNameLike("Hostsharing eG") + .stream() + .map(HsOfficePersonEntity::getUuid) + .reduce(Reducer::toSingleElement).orElseThrow()) + ); + } + ); + } + + @SneakyThrows + private void callRequiredProducers(final Method currentTestMethod) { + final var testMethodRequires = Optional.of(currentTestMethod) + .map(m -> m.getAnnotation(Requires.class)) + .map(Requires::value) + .orElse(null); + if (testMethodRequires != null) { + for (Method potentialProducerMethod : getPotentialProducerMethods()) { + final var producesAnnot = potentialProducerMethod.getAnnotation(Produces.class); + final var testMethodProduces = producedAliases(producesAnnot); + // @formatter:off + if ( // that method can produce something required + testMethodProduces.contains(testMethodRequires) && + + // and it does not produce anything we already have (would cause errors) + SetUtils.intersection(testMethodProduces, knowVariables().keySet()).isEmpty() + ) { + assertThat(producesAnnot.permanent()).as("cannot depend on non-permanent producer: " + potentialProducerMethod); + + // then we recursively produce the pre-requisites of the producer method + callRequiredProducers(potentialProducerMethod); + keepProducesAlias(currentTestMethod); + + // and finally we call the producer method + invokeProducerMethod(this, potentialProducerMethod); + } + // @formatter:on + } + + assertThat(knowVariables().containsKey(testMethodRequires)) + .as("no @Producer for @Required(\"" + testMethodRequires + "\") found") + .isTrue(); + } + } + + private void keepProducesAlias(final Method currentTestMethod) { + final var producesAnnot = currentTestMethod.getAnnotation(Produces.class); + if (producesAnnot != null) { + final var producesAlias = isNotBlank(producesAnnot.value()) ? producesAnnot.value() : producesAnnot.explicitly(); + assertThat(producesAlias) + .as(currentTestMethod.getName() + " must define either value or explicit for @Produces") + .isNotNull(); + this.currentTestMethodProduces.push(producesAlias); + } + } + + private Method @NotNull [] getPotentialProducerMethods() { + final var methodsDeclaredInOuterTestClass = stream(getClass().getDeclaredMethods()) + .filter(m -> m.getAnnotation(Produces.class) != null) + .toArray(Method[]::new); + final var methodsDeclaredInInnerTestClasses = stream(getClass().getDeclaredClasses()) + .map(Class::getDeclaredMethods).flatMap(Stream::of) + .filter(m -> m.getAnnotation(Produces.class) != null) + .toArray(Method[]::new); + return ArrayUtils.addAll(methodsDeclaredInOuterTestClass, methodsDeclaredInInnerTestClasses); + } + + @SneakyThrows + private void invokeProducerMethod(final ScenarioTest scenarioTest, final Method producerMethod) { + producerMethod.setAccessible(true); + if (producerMethod.getDeclaringClass() == scenarioTest.getClass()) { + producerMethod.invoke(this); + } else { + final var innerClassConstructor = producerMethod.getDeclaringClass() + .getDeclaredConstructor(scenarioTest.getClass()); + innerClassConstructor.setAccessible(true); + final var inner = innerClassConstructor.newInstance(this); + producerMethod.invoke(inner); + } + } + + static boolean containsAlias(final String alias) { + return aliases.containsKey(alias); + } + + static UUID uuid(final String nameWithPlaceholders) { + final var resolvedName = resolve(nameWithPlaceholders, DROP_COMMENTS); + final UUID alias = ofNullable(knowVariables().get(resolvedName)).filter(v -> v instanceof UUID) + .map(UUID.class::cast) + .orElse(null); + assertThat(alias).as("alias '" + resolvedName + "' not found in aliases nor in properties [" + + knowVariables().keySet().stream().map(v -> "'" + v + "'").collect(Collectors.joining(", ")) + "]" + ).isNotNull(); + return alias; + } + + static void putAlias(final String name, final Alias value) { + aliases.put(name, value); + } + + static void putProperty(final String name, final Object value) { + properties.put(name, (value instanceof String string) ? resolveTyped(string) : value); + } + + static void removeProperty(final String propName) { + properties.remove(propName); + } + + static Map knowVariables() { + final var map = new LinkedHashMap(); + ScenarioTest.aliases.forEach((key, value) -> map.put(key, value.uuid())); + map.putAll(ScenarioTest.properties); + return map; + } + + public static String resolve(final String text, final Resolver resolver) { + final var resolved = new TemplateResolver(text, ScenarioTest.knowVariables()).resolve(resolver); + return resolved; + } + + public static Object resolveTyped(final String resolvableText) { + final var resolved = resolve(resolvableText, DROP_COMMENTS); + try { + return UUID.fromString(resolved); + } catch (final IllegalArgumentException e) { + // ignore and just use the String value + } + return resolved; + } + + public static T resolveTyped(final String resolvableText, final Class valueType) { + final var resolvedValue = resolve(resolvableText, DROP_COMMENTS); + if (valueType == BigDecimal.class) { + //noinspection unchecked + return (T) new BigDecimal(resolvedValue); + } + //noinspection unchecked + return (T) resolvedValue; + } + +} diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/TemplateResolver.java b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/TemplateResolver.java similarity index 98% rename from src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/TemplateResolver.java rename to src/test/java/net/hostsharing/hsadminng/hs/scenarios/TemplateResolver.java index 002d0512..d28adb26 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/TemplateResolver.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/TemplateResolver.java @@ -1,4 +1,4 @@ -package net.hostsharing.hsadminng.hs.office.scenarios; +package net.hostsharing.hsadminng.hs.scenarios; import org.apache.commons.lang3.StringUtils; @@ -10,7 +10,7 @@ import java.util.Objects; import java.util.regex.Pattern; import java.util.stream.Collectors; -import static net.hostsharing.hsadminng.hs.office.scenarios.TemplateResolver.Resolver.DROP_COMMENTS; +import static net.hostsharing.hsadminng.hs.scenarios.TemplateResolver.Resolver.DROP_COMMENTS; public class TemplateResolver { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/TemplateResolverUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/TemplateResolverUnitTest.java similarity index 92% rename from src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/TemplateResolverUnitTest.java rename to src/test/java/net/hostsharing/hsadminng/hs/scenarios/TemplateResolverUnitTest.java index 435d44d3..34e2783f 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/TemplateResolverUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/TemplateResolverUnitTest.java @@ -1,10 +1,10 @@ -package net.hostsharing.hsadminng.hs.office.scenarios; +package net.hostsharing.hsadminng.hs.scenarios; import org.junit.jupiter.api.Test; import java.util.Map; -import static net.hostsharing.hsadminng.hs.office.scenarios.TemplateResolver.Resolver.DROP_COMMENTS; +import static net.hostsharing.hsadminng.hs.scenarios.TemplateResolver.Resolver.DROP_COMMENTS; import static org.assertj.core.api.Assertions.assertThat; class TemplateResolverUnitTest { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/TestReport.java b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/TestReport.java similarity index 99% rename from src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/TestReport.java rename to src/test/java/net/hostsharing/hsadminng/hs/scenarios/TestReport.java index f0b47bcc..b700d556 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/TestReport.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/TestReport.java @@ -1,4 +1,4 @@ -package net.hostsharing.hsadminng.hs.office.scenarios; +package net.hostsharing.hsadminng.hs.scenarios; import lombok.SneakyThrows; import net.hostsharing.hsadminng.system.SystemProcess; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/UseCase.java b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/UseCase.java similarity index 94% rename from src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/UseCase.java rename to src/test/java/net/hostsharing/hsadminng/hs/scenarios/UseCase.java index 58d76759..7b438134 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/UseCase.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/UseCase.java @@ -1,4 +1,4 @@ -package net.hostsharing.hsadminng.hs.office.scenarios; +package net.hostsharing.hsadminng.hs.scenarios; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; @@ -35,8 +35,8 @@ import java.util.function.Supplier; import static java.net.URLEncoder.encode; import static java.util.stream.Collectors.joining; -import static net.hostsharing.hsadminng.hs.office.scenarios.TemplateResolver.Resolver.DROP_COMMENTS; -import static net.hostsharing.hsadminng.hs.office.scenarios.TemplateResolver.Resolver.KEEP_COMMENTS; +import static net.hostsharing.hsadminng.hs.scenarios.TemplateResolver.Resolver.DROP_COMMENTS; +import static net.hostsharing.hsadminng.hs.scenarios.TemplateResolver.Resolver.KEEP_COMMENTS; import static net.hostsharing.hsadminng.test.DebuggerDetection.isDebuggerAttached; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.fail; @@ -71,9 +71,7 @@ public abstract class UseCase> { } public final void requires(final String alias, final Function> useCaseFactory) { - if (!ScenarioTest.containsAlias(alias)) { - requirements.put(alias, useCaseFactory); - } + requirements.put(alias, useCaseFactory); } public final HttpResponse doRun() { @@ -89,13 +87,15 @@ public abstract class UseCase> { testReport.printLine(""); testReport.silent(() -> requirements.forEach((alias, factory) -> { - if (!ScenarioTest.containsAlias(alias)) { - factory.apply(alias).run().keepAs(alias); + final var resolvedAlias = ScenarioTest.resolve(alias, DROP_COMMENTS); + if (!ScenarioTest.containsAlias(resolvedAlias)) { + factory.apply(resolvedAlias).run().keepAs(resolvedAlias); } }) ); final var response = run(); verify(response); + keepInProduceAlias(response); resetProperties(); @@ -113,7 +113,7 @@ public abstract class UseCase> { } public final UseCase given(final String propName, final Object propValue) { - givenProperties.put(propName, ScenarioTest.resolve(propValue == null ? null : propValue.toString(), KEEP_COMMENTS)); + givenProperties.put(propName, ScenarioTest.resolve(propValue == null ? null : propValue.toString(), TemplateResolver.Resolver.KEEP_COMMENTS)); ScenarioTest.putProperty(propName, propValue); return this; } @@ -244,6 +244,13 @@ public abstract class UseCase> { } + private void keepInProduceAlias(final HttpResponse response) { + final var producedAlias = testSuite.takeProducedAlias(); + if (response != null) { + producedAlias.ifPresent(response::keepAs); + } + } + private static Duration seconds(final int secondsIfNoDebuggerAttached) { return isDebuggerAttached() ? Duration.ofHours(1) : Duration.ofSeconds(secondsIfNoDebuggerAttached); } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/UseCaseNotImplementedYet.java b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/UseCaseNotImplementedYet.java similarity index 87% rename from src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/UseCaseNotImplementedYet.java rename to src/test/java/net/hostsharing/hsadminng/hs/scenarios/UseCaseNotImplementedYet.java index d21d6413..98073e65 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/UseCaseNotImplementedYet.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/scenarios/UseCaseNotImplementedYet.java @@ -1,4 +1,4 @@ -package net.hostsharing.hsadminng.hs.office.scenarios; +package net.hostsharing.hsadminng.hs.scenarios; import static org.assertj.core.api.Assumptions.assumeThat;