diff --git a/.tc-environment b/.tc-environment index c1816e80..35fe2c87 100644 --- a/.tc-environment +++ b/.tc-environment @@ -4,4 +4,5 @@ export HSADMINNG_POSTGRES_ADMIN_PASSWORD= export HSADMINNG_POSTGRES_RESTRICTED_USERNAME=restricted export HSADMINNG_SUPERUSER=superuser-alex@hostsharing.net export HSADMINNG_MIGRATION_DATA_PATH=migration +export HSADMINNG_OFFICE_DATA_SQL_FILE= export LANG=en_US.UTF-8 diff --git a/.unset-environment b/.unset-environment index 6f00ada4..2be52333 100644 --- a/.unset-environment +++ b/.unset-environment @@ -4,4 +4,5 @@ unset HSADMINNG_POSTGRES_ADMIN_PASSWORD unset HSADMINNG_POSTGRES_RESTRICTED_USERNAME unset HSADMINNG_SUPERUSER unset HSADMINNG_MIGRATION_DATA_PATH +unset HSADMINNG_OFFICE_DATA_SQL_FILE diff --git a/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java b/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java index 66450e69..2226a924 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java @@ -16,6 +16,9 @@ import org.junit.jupiter.api.extension.TestWatcher; import org.opentest4j.AssertionFailedError; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.AbstractResource; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.FileSystemResource; import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.core.io.Resource; import org.springframework.transaction.support.TransactionTemplate; @@ -26,6 +29,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.ValidationException; import jakarta.validation.constraints.NotNull; import java.io.BufferedReader; +import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; @@ -118,10 +122,16 @@ public class CsvDataImport extends ContextBasedTest { return stream(lines.getFirst()).map(String::trim).toArray(String[]::new); } + public static @NotNull AbstractResource resourceOf(final String sqlFile) { + return new File(sqlFile).exists() + ? new FileSystemResource(sqlFile) + : new ClassPathResource(sqlFile); + } + protected Reader resourceReader(@NotNull final String resourcePath) { try { - return new InputStreamReader(requireNonNull(getClass().getClassLoader().getResourceAsStream(resourcePath))); - } catch (Exception exc) { + return new InputStreamReader(requireNonNull(resourceOf(resourcePath).getInputStream())); + } catch (final Exception exc) { throw new AssertionFailedError("cannot open '" + resourcePath + "'"); } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/migration/ImportHostingAssets.java b/src/test/java/net/hostsharing/hsadminng/hs/migration/ImportHostingAssets.java index 139706e0..6359560a 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/migration/ImportHostingAssets.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/migration/ImportHostingAssets.java @@ -30,14 +30,18 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.Import; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.orm.jpa.EntityManagerFactoryInfo; import org.springframework.test.annotation.Commit; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.jdbc.Sql; +import java.io.IOException; +import java.io.InputStream; import java.io.Reader; import java.net.IDN; import java.util.ArrayList; @@ -53,6 +57,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; +import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Arrays.stream; import static java.util.Map.entry; import static java.util.Map.ofEntries; @@ -81,7 +86,7 @@ import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.UNIX import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assumptions.assumeThat; -import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.BEFORE_TEST_CLASS; +import static org.springframework.util.FileCopyUtils.copyToByteArray; @Tag("importHostingAssets") @DataJpaTest(properties = { @@ -96,7 +101,6 @@ import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.BEFORE_TE @ActiveProfiles({ "without-test-data", "liquibase-migration", "hosting-asset-import" }) @TestMethodOrder(MethodOrderer.OrderAnnotation.class) @ExtendWith(OrderedDependedTestsExtension.class) -@Sql(value = "/db/released-only-office-schema-with-import-test-data.sql", executionPhase = BEFORE_TEST_CLASS) // release-schema public class ImportHostingAssets extends CsvDataImport { private static final Set NOBODY_SUBSTITUTES = Set.of("nomail", "bounce"); @@ -134,9 +138,14 @@ public class ImportHostingAssets extends CsvDataImport { @Autowired LiquibaseMigration liquibase; + @Value("${HSADMINNG_OFFICE_DATA_SQL_FILE:/db/released-only-office-schema-with-import-test-data.sql}") + String officeSchemaAndDataSqlFile; + @Test @Order(11000) + @SneakyThrows void liquibaseMigrationForBookingAndHosting() { + executeSqlScript(officeSchemaAndDataSqlFile); liquibase.assertReferenceStatusAfterRestore(286, "hs-booking-SCHEMA"); makeSureThatTheImportAdminUserExists(); liquibase.runWithContexts("migration", "without-test-data"); @@ -147,8 +156,8 @@ public class ImportHostingAssets extends CsvDataImport { @Order(11010) void createBookingProjects() { - record PartnerLegacyIdMapping(UUID uuid, Integer bp_id){} - record DebitorRecord(UUID uuid, Integer version, String defaultPrefix){} + record PartnerLegacyIdMapping(UUID uuid, Integer bp_id) {} + record DebitorRecord(UUID uuid, Integer version, String defaultPrefix) {} final var partnerLegacyIdMappings = em.createNativeQuery( """ @@ -162,16 +171,18 @@ public class ImportHostingAssets extends CsvDataImport { //noinspection unchecked final var debitorUuidToLegacyBpIdMap = ((List) partnerLegacyIdMappings).stream() .collect(toMap(row -> row.uuid, row -> row.bp_id)); - final var debitors = em.createNativeQuery("SELECT debitor.uuid, debitor.version, debitor.defaultPrefix FROM hs_office.debitor debitor", DebitorRecord.class).getResultList(); + final var debitors = em.createNativeQuery( + "select debitor.uuid, debitor.version, debitor.defaultPrefix from hs_office.debitor debitor", + DebitorRecord.class).getResultList(); //noinspection unchecked - ((List)debitors).forEach(debitor -> { - bookingProjects.put( - debitorUuidToLegacyBpIdMap.get(debitor.uuid), HsBookingProjectRealEntity.builder() - .version(debitor.version) - .caption(debitor.defaultPrefix + " default project") - .debitor(em.find(HsBookingDebitorEntity.class, debitor.uuid)) - .build()); - }); + ((List) debitors).forEach(debitor -> { + bookingProjects.put( + debitorUuidToLegacyBpIdMap.get(debitor.uuid), HsBookingProjectRealEntity.builder() + .version(debitor.version) + .caption(debitor.defaultPrefix + " default project") + .debitor(em.find(HsBookingDebitorEntity.class, debitor.uuid)) + .build()); + }); } @Test @@ -1291,7 +1302,7 @@ public class ImportHostingAssets extends CsvDataImport { return ofNullable(bookingItem.getProject()) .map(HsBookingProject::getDebitor) .map(HsBookingDebitorEntity::getDefaultPrefix) - .orElse(""); + .orElse(""); } private void importPacketComponents(final String[] header, final List records) { @@ -1946,4 +1957,17 @@ public class ImportHostingAssets extends CsvDataImport { .map(row -> row.stream().map(Object::toString).collect(joining(", "))) .collect(joining("\n")); } + + @SneakyThrows + private void executeSqlScript(final String sqlFile) { + jpaAttempt.transacted(() -> { + try (InputStream resourceStream = resourceOf(sqlFile).getInputStream()) { + final var sqlScript = new String(copyToByteArray(resourceStream), UTF_8); + final var emf = (EntityManagerFactoryInfo) em.getEntityManagerFactory(); + new JdbcTemplate(emf.getDataSource()).execute(sqlScript); + } catch (IOException e) { + throw new RuntimeException(e); + } + }).assertSuccessful(); + } }