From 2a2d0130e075e82243ddd607659eff7f66b0acbe Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Tue, 21 Jan 2025 16:29:56 +0100 Subject: [PATCH] assertHasLegacyId for all tables with legacy_id-support, add primary key + unique to legacy_id tables --- .../5016-hs-office-contact-migration.sql | 6 ++-- .../5046-hs-office-partner-migration.sql | 6 ++-- .../5076-hs-office-sepamandate-migration.sql | 6 ++-- .../5116-hs-office-coopshares-migration.sql | 6 ++-- .../5126-hs-office-coopassets-migration.sql | 6 ++-- .../7016-hs-hosting-asset-migration.sql | 6 ++-- ...eContactRbacRepositoryIntegrationTest.java | 33 +++++++++++-------- ...sTransactionRepositoryIntegrationTest.java | 1 + ...sTransactionRepositoryIntegrationTest.java | 1 + ...ePartnerRbacRepositoryIntegrationTest.java | 1 + ...eSepaMandateRepositoryIntegrationTest.java | 1 + .../rbac/context/ContextBasedTest.java | 33 ++++++++++++++++++- 12 files changed, 73 insertions(+), 33 deletions(-) diff --git a/src/main/resources/db/changelog/5-hs-office/501-contact/5016-hs-office-contact-migration.sql b/src/main/resources/db/changelog/5-hs-office/501-contact/5016-hs-office-contact-migration.sql index c9cb699f..a46ad6d2 100644 --- a/src/main/resources/db/changelog/5-hs-office/501-contact/5016-hs-office-contact-migration.sql +++ b/src/main/resources/db/changelog/5-hs-office/501-contact/5016-hs-office-contact-migration.sql @@ -4,13 +4,13 @@ -- Once we don't need the external remote views anymore, create revert changesets. -- ============================================================================ ---changeset michael.hoennig:hs-office-contact-MIGRATION-mapping endDelimiter:--// +--changeset michael.hoennig:hs-office-contact-MIGRATION-legacy-mapping endDelimiter:--// -- ---------------------------------------------------------------------------- CREATE TABLE hs_office.contact_legacy_id ( - uuid uuid NOT NULL REFERENCES hs_office.contact(uuid), - contact_id integer NOT NULL + uuid uuid PRIMARY KEY NOT NULL REFERENCES hs_office.contact(uuid), + contact_id integer UNIQUE NOT NULL ); --// diff --git a/src/main/resources/db/changelog/5-hs-office/504-partner/5046-hs-office-partner-migration.sql b/src/main/resources/db/changelog/5-hs-office/504-partner/5046-hs-office-partner-migration.sql index 8118102e..02cd1ac1 100644 --- a/src/main/resources/db/changelog/5-hs-office/504-partner/5046-hs-office-partner-migration.sql +++ b/src/main/resources/db/changelog/5-hs-office/504-partner/5046-hs-office-partner-migration.sql @@ -4,13 +4,13 @@ -- Once we don't need the external remote views anymore, create revert changesets. -- ============================================================================ ---changeset michael.hoennig:hs-office-partner-MIGRATION-mapping endDelimiter:--// +--changeset michael.hoennig:hs-office-partner-MIGRATION-legacy-mapping endDelimiter:--// -- ---------------------------------------------------------------------------- CREATE TABLE hs_office.partner_legacy_id ( - uuid uuid NOT NULL REFERENCES hs_office.partner(uuid), - bp_id integer NOT NULL + uuid uuid PRIMARY KEY NOT NULL REFERENCES hs_office.partner(uuid), + bp_id integer UNIQUE NOT NULL ); --// diff --git a/src/main/resources/db/changelog/5-hs-office/507-sepamandate/5076-hs-office-sepamandate-migration.sql b/src/main/resources/db/changelog/5-hs-office/507-sepamandate/5076-hs-office-sepamandate-migration.sql index c92b0ea1..237e7073 100644 --- a/src/main/resources/db/changelog/5-hs-office/507-sepamandate/5076-hs-office-sepamandate-migration.sql +++ b/src/main/resources/db/changelog/5-hs-office/507-sepamandate/5076-hs-office-sepamandate-migration.sql @@ -4,13 +4,13 @@ -- Once we don't need the external remote views anymore, create revert changesets. -- ============================================================================ ---changeset michael.hoennig:hs-office-sepamandate-MIGRATION-mapping endDelimiter:--// +--changeset michael.hoennig:hs-office-sepamandate-MIGRATION-legacy-mapping endDelimiter:--// -- ---------------------------------------------------------------------------- CREATE TABLE hs_office.sepamandate_legacy_id ( - uuid uuid NOT NULL REFERENCES hs_office.sepamandate(uuid), - sepa_mandate_id integer NOT NULL + uuid uuid PRIMARY KEY NOT NULL REFERENCES hs_office.sepamandate(uuid), + sepa_mandate_id integer UNIQUE NOT NULL ); --// diff --git a/src/main/resources/db/changelog/5-hs-office/511-coopshares/5116-hs-office-coopshares-migration.sql b/src/main/resources/db/changelog/5-hs-office/511-coopshares/5116-hs-office-coopshares-migration.sql index a13b54ef..6dc9a9f4 100644 --- a/src/main/resources/db/changelog/5-hs-office/511-coopshares/5116-hs-office-coopshares-migration.sql +++ b/src/main/resources/db/changelog/5-hs-office/511-coopshares/5116-hs-office-coopshares-migration.sql @@ -4,13 +4,13 @@ -- Once we don't need the external remote views anymore, create revert changesets. -- ============================================================================ ---changeset michael.hoennig:hs-office-coopshares-MIGRATION-mapping endDelimiter:--// +--changeset michael.hoennig:hs-office-coopshares-MIGRATION-legacy-mapping endDelimiter:--// -- ---------------------------------------------------------------------------- CREATE TABLE hs_office.coopsharetx_legacy_id ( - uuid uuid NOT NULL REFERENCES hs_office.coopsharetx(uuid), - member_share_id integer NOT NULL + uuid uuid PRIMARY KEY NOT NULL REFERENCES hs_office.coopsharetx(uuid), + member_share_id integer UNIQUE NOT NULL ); --// diff --git a/src/main/resources/db/changelog/5-hs-office/512-coopassets/5126-hs-office-coopassets-migration.sql b/src/main/resources/db/changelog/5-hs-office/512-coopassets/5126-hs-office-coopassets-migration.sql index f8d5f610..49d47288 100644 --- a/src/main/resources/db/changelog/5-hs-office/512-coopassets/5126-hs-office-coopassets-migration.sql +++ b/src/main/resources/db/changelog/5-hs-office/512-coopassets/5126-hs-office-coopassets-migration.sql @@ -4,13 +4,13 @@ -- Once we don't need the external remote views anymore, create revert changesets. -- ============================================================================ ---changeset michael.hoennig:hs-office-coopassets-MIGRATION-mapping endDelimiter:--// +--changeset michael.hoennig:hs-office-coopassets-MIGRATION-legacy-mapping endDelimiter:--// -- ---------------------------------------------------------------------------- CREATE TABLE hs_office.coopassettx_legacy_id ( - uuid uuid NOT NULL REFERENCES hs_office.coopassettx(uuid), - member_asset_id integer NOT NULL + uuid uuid PRIMARY KEY NOT NULL REFERENCES hs_office.coopassettx(uuid), + member_asset_id integer UNIQUE NOT NULL ); --// diff --git a/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7016-hs-hosting-asset-migration.sql b/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7016-hs-hosting-asset-migration.sql index a0305e8d..a351cc0b 100644 --- a/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7016-hs-hosting-asset-migration.sql +++ b/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7016-hs-hosting-asset-migration.sql @@ -4,13 +4,13 @@ -- Once we don't need the external remote views anymore, create revert changesets. -- ============================================================================ ---changeset hs-hosting-asset-MIGRATION-mapping:1 endDelimiter:--// +--changeset hs-hosting-asset-MIGRATION-legacy-mapping:1 endDelimiter:--// -- ---------------------------------------------------------------------------- CREATE TABLE hs_hosting.asset_legacy_id ( - uuid uuid NOT NULL REFERENCES hs_hosting.asset(uuid), - legacy_id integer NOT NULL + uuid uuid PRIMARY KEY NOT NULL REFERENCES hs_hosting.asset(uuid), + legacy_id integer NOT NULL -- not unique because we sometimes create multiple asset types for the same legacy asset ); --// diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactRbacRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactRbacRepositoryIntegrationTest.java index 2073057c..4efd72cb 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactRbacRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactRbacRepositoryIntegrationTest.java @@ -1,10 +1,10 @@ package net.hostsharing.hsadminng.hs.office.contact; import net.hostsharing.hsadminng.context.Context; -import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup; +import net.hostsharing.hsadminng.mapper.Array; import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository; import net.hostsharing.hsadminng.rbac.role.RawRbacRoleRepository; -import net.hostsharing.hsadminng.mapper.Array; +import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup; import net.hostsharing.hsadminng.rbac.test.JpaAttempt; import org.apache.commons.lang3.RandomStringUtils; import org.junit.jupiter.api.Nested; @@ -12,8 +12,8 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; @@ -29,7 +29,7 @@ import static net.hostsharing.hsadminng.rbac.test.JpaAttempt.attempt; import static org.assertj.core.api.Assertions.assertThat; @DataJpaTest -@Import( { Context.class, JpaAttempt.class }) +@Import({ Context.class, JpaAttempt.class }) @Tag("officeIntegrationTest") class HsOfficeContactRbacRepositoryIntegrationTest extends ContextBasedTestWithCleanup { @@ -62,8 +62,9 @@ class HsOfficeContactRbacRepositoryIntegrationTest extends ContextBasedTestWithC // when - final var result = attempt(em, () -> toCleanup(contactRepo.save( - hsOfficeContact("a new contact", "contact-admin@www.example.com")))); + final var result = attempt( + em, () -> toCleanup(contactRepo.save( + hsOfficeContact("a new contact", "contact-admin@www.example.com")))); // then result.assertSuccessful(); @@ -79,14 +80,16 @@ class HsOfficeContactRbacRepositoryIntegrationTest extends ContextBasedTestWithC final var count = contactRepo.count(); // when - final var result = attempt(em, () -> toCleanup(contactRepo.save( - hsOfficeContact("another new contact", "another-new-contact@example.com")))); + final var result = attempt( + em, () -> toCleanup(contactRepo.save( + hsOfficeContact("another new contact", "another-new-contact@example.com")))); // then result.assertSuccessful(); assertThat(result.returnedValue()).isNotNull().extracting(HsOfficeContactRbacEntity::getUuid).isNotNull(); assertThatContactIsPersisted(result.returnedValue()); assertThat(contactRepo.count()).isEqualTo(count + 1); + assertHasLegacyId(result.returnedValue(), "contact_id"); } @Test @@ -97,8 +100,9 @@ class HsOfficeContactRbacRepositoryIntegrationTest extends ContextBasedTestWithC final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll()); // when - attempt(em, () -> toCleanup(contactRepo.save( - hsOfficeContact("another new contact", "another-new-contact@example.com"))) + attempt( + em, () -> toCleanup(contactRepo.save( + hsOfficeContact("another new contact", "another-new-contact@example.com"))) ).assumeSuccessful(); // then @@ -300,10 +304,11 @@ class HsOfficeContactRbacRepositoryIntegrationTest extends ContextBasedTestWithC private HsOfficeContactRbacEntity givenSomeTemporaryContact(final String createdByUser) { final var random = RandomStringUtils.randomAlphabetic(12); - return givenSomeTemporaryContact(createdByUser, () -> - hsOfficeContact( - "some temporary contact #" + random, - "some-temporary-contact" + random + "@example.com")); + return givenSomeTemporaryContact( + createdByUser, () -> + hsOfficeContact( + "some temporary contact #" + random, + "some-temporary-contact" + random + "@example.com")); } void exactlyTheseContactsAreReturned(final List actualResult, final String... contactCaptions) { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionRepositoryIntegrationTest.java index 09cc75d1..088eee76 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionRepositoryIntegrationTest.java @@ -83,6 +83,7 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase assertThat(result.returnedValue()).isNotNull().extracting(HsOfficeCoopAssetsTransactionEntity::getUuid).isNotNull(); assertThatCoopAssetsTransactionIsPersisted(result.returnedValue()); assertThat(coopAssetsTransactionRepo.count()).isEqualTo(count + 1); + assertHasLegacyId(result.returnedValue(), "member_asset_id"); } @Test diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionRepositoryIntegrationTest.java index 24df54cd..f0fbeb84 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionRepositoryIntegrationTest.java @@ -82,6 +82,7 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase assertThat(result.returnedValue()).isNotNull().extracting(HsOfficeCoopSharesTransactionEntity::getUuid).isNotNull(); assertThatCoopSharesTransactionIsPersisted(result.returnedValue()); assertThat(coopSharesTransactionRepo.count()).isEqualTo(count + 1); + assertHasLegacyId(result.returnedValue(), "member_share_id"); } @Test diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepositoryIntegrationTest.java index 0fbf6990..278006fa 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepositoryIntegrationTest.java @@ -98,6 +98,7 @@ class HsOfficePartnerRbacRepositoryIntegrationTest extends ContextBasedTestWithC assertThat(result.returnedValue()).isNotNull().extracting(HsOfficePartnerRbacEntity::getUuid).isNotNull(); assertThatPartnerIsPersisted(result.returnedValue()); assertThat(partnerRepo.count()).isEqualTo(count + 1); + assertHasLegacyId(result.returnedValue(), "bp_id"); } @Test diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateRepositoryIntegrationTest.java index b9a49708..20ecbd2c 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateRepositoryIntegrationTest.java @@ -89,6 +89,7 @@ class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTestWithC assertThat(result.returnedValue()).isNotNull().extracting(HsOfficeSepaMandateEntity::getUuid).isNotNull(); assertThatSepaMandateIsPersisted(result.returnedValue()); assertThat(sepaMandateRepo.count()).isEqualTo(count + 1); + assertHasLegacyId(result.returnedValue(), "sepa_mandate_id"); } @Test diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/context/ContextBasedTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/context/ContextBasedTest.java index 455be002..2f1b3750 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/context/ContextBasedTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/context/ContextBasedTest.java @@ -1,6 +1,7 @@ package net.hostsharing.hsadminng.rbac.context; import net.hostsharing.hsadminng.context.Context; +import net.hostsharing.hsadminng.persistence.BaseEntity; import net.hostsharing.hsadminng.rbac.grant.RbacGrantsDiagramService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.TestInfo; @@ -9,8 +10,11 @@ import org.springframework.context.annotation.Import; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; +import jakarta.persistence.Table; import java.sql.Timestamp; +import static org.assertj.core.api.Assertions.assertThat; + @Import(RbacGrantsDiagramService.class) public abstract class ContextBasedTest { @@ -59,7 +63,6 @@ public abstract class ContextBasedTest { """).executeUpdate(); } - protected void historicalContext(final Timestamp txTimestamp) { // set local cannot be used with query parameters em.createNativeQuery(""" @@ -70,4 +73,32 @@ public abstract class ContextBasedTest { """).executeUpdate(); } + protected void assertHasLegacyId(final BaseEntity entity, final String legacyIdColumnName) { + final var table = entity.getClass().getAnnotation(Table.class); + final var legacyIdTable = table.schema() + "." + table.name().replace("_rv", "") + "_legacy_id"; + + final var legacyId = getSingleLegacyIdByUuidOrFail(entity, legacyIdTable, legacyIdColumnName); + assertThatLegacyIdExistsExactlyOnce(legacyIdColumnName, legacyIdTable, legacyId); + } + + private void assertThatLegacyIdExistsExactlyOnce(final String legacyIdColumnName, final String legacyIdTable, final long legacyId) { + em.createNativeQuery("SELECT *" + + " FROM " + legacyIdTable + + " WHERE " + legacyIdColumnName + " = '" + legacyId + "'") + .getSingleResult(); // fails if there is not exactly one result + } + + private long getSingleLegacyIdByUuidOrFail(final BaseEntity entity, + final String legacyIdTable, + final String legacyIdColumnName) { + final var uuid = entity.getUuid(); + @SuppressWarnings("unchecked") // the auto-formatter should keep this linebreak + final var legacyId = (Long) em.createNativeQuery("SELECT " + legacyIdColumnName + + " FROM " + legacyIdTable + + " WHERE uuid = '" + uuid + "'", Long.class) + .getSingleResult(); + assertThat(legacyId).isNotNull(); + return legacyId; + } + }