From a334bb5ceb062217f1004ef97b71dfabc37f02cb Mon Sep 17 00:00:00 2001 From: Lai Jiang Date: Tue, 21 Jun 2022 16:53:56 -0400 Subject: [PATCH] Add some helper methods to JPA test extension (#1673) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added methods that exist in AppEngineExtension that preload some canned data. This data is loaded by default and a lot of tests rely on them. As we migrate away from App Engine, it is helpful to have them in the JPA test extension which will replace the app engine extension that is used to set up the database in dual database tests. --- This change is [Reviewable](https://reviewable.io/reviews/google/nomulus/1673) --- .../beam/common/RegistryJpaReadTest.java | 5 +- .../model/tmch/ClaimsListDaoTest.java | 5 +- .../transaction/JpaTestExtensions.java | 23 ++- .../JpaTransactionManagerExtension.java | 144 ++++++++++++++++-- 4 files changed, 158 insertions(+), 19 deletions(-) diff --git a/core/src/test/java/google/registry/beam/common/RegistryJpaReadTest.java b/core/src/test/java/google/registry/beam/common/RegistryJpaReadTest.java index 76959f2da..706def3b4 100644 --- a/core/src/test/java/google/registry/beam/common/RegistryJpaReadTest.java +++ b/core/src/test/java/google/registry/beam/common/RegistryJpaReadTest.java @@ -67,7 +67,10 @@ public class RegistryJpaReadTest { @RegisterExtension final transient JpaIntegrationTestExtension database = - new JpaTestExtensions.Builder().withClock(fakeClock).buildIntegrationTestExtension(); + new JpaTestExtensions.Builder() + .withClock(fakeClock) + .withoutCannedData() + .buildIntegrationTestExtension(); @RegisterExtension final transient TestPipelineExtension testPipeline = diff --git a/core/src/test/java/google/registry/model/tmch/ClaimsListDaoTest.java b/core/src/test/java/google/registry/model/tmch/ClaimsListDaoTest.java index 9bfdbc500..973dda958 100644 --- a/core/src/test/java/google/registry/model/tmch/ClaimsListDaoTest.java +++ b/core/src/test/java/google/registry/model/tmch/ClaimsListDaoTest.java @@ -32,7 +32,10 @@ public class ClaimsListDaoTest { @RegisterExtension final JpaIntegrationWithCoverageExtension jpa = - new JpaTestExtensions.Builder().withClock(fakeClock).buildIntegrationWithCoverageExtension(); + new JpaTestExtensions.Builder() + .withClock(fakeClock) + .withoutCannedData() + .buildIntegrationWithCoverageExtension(); @Test void save_insertsClaimsListSuccessfully() { diff --git a/core/src/test/java/google/registry/persistence/transaction/JpaTestExtensions.java b/core/src/test/java/google/registry/persistence/transaction/JpaTestExtensions.java index 001d202a6..72b0903d9 100644 --- a/core/src/test/java/google/registry/persistence/transaction/JpaTestExtensions.java +++ b/core/src/test/java/google/registry/persistence/transaction/JpaTestExtensions.java @@ -52,8 +52,15 @@ public class JpaTestExtensions { private JpaIntegrationTestExtension( Clock clock, ImmutableList> extraEntityClasses, - ImmutableMap userProperties) { - super(clock, Optional.of(GOLDEN_SCHEMA_SQL_PATH), extraEntityClasses, userProperties); + ImmutableMap userProperties, + boolean withCannedData) { + super( + clock, + Optional.of(GOLDEN_SCHEMA_SQL_PATH), + true, + extraEntityClasses, + userProperties, + withCannedData); } } @@ -67,7 +74,7 @@ public class JpaTestExtensions { Optional initScriptPath, ImmutableList> extraEntityClasses, ImmutableMap userProperties) { - super(clock, initScriptPath, false, extraEntityClasses, userProperties); + super(clock, initScriptPath, false, extraEntityClasses, userProperties, false); } } @@ -109,6 +116,7 @@ public class JpaTestExtensions { private Clock clock; private List> extraEntityClasses = new ArrayList<>(); private Map userProperties = new HashMap<>(); + private boolean withoutCannedData = false; /** * Sets the SQL script to be used to initialize the database. If not set, @@ -132,6 +140,12 @@ public class JpaTestExtensions { return this; } + /** Disables insertion of canned data. */ + public Builder withoutCannedData() { + this.withoutCannedData = true; + return this; + } + /** Adds the specified property to those used to initialize the transaction manager. */ Builder withProperty(String name, String value) { this.userProperties.put(name, value); @@ -154,7 +168,8 @@ public class JpaTestExtensions { return new JpaIntegrationTestExtension( clock == null ? new FakeClock(DateTime.now(UTC)) : clock, ImmutableList.copyOf(extraEntityClasses), - ImmutableMap.copyOf(userProperties)); + ImmutableMap.copyOf(userProperties), + !withoutCannedData); } /** diff --git a/core/src/test/java/google/registry/persistence/transaction/JpaTransactionManagerExtension.java b/core/src/test/java/google/registry/persistence/transaction/JpaTransactionManagerExtension.java index 53dfbc2c2..0ba4e78d3 100644 --- a/core/src/test/java/google/registry/persistence/transaction/JpaTransactionManagerExtension.java +++ b/core/src/test/java/google/registry/persistence/transaction/JpaTransactionManagerExtension.java @@ -17,6 +17,7 @@ package google.registry.persistence.transaction; import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.truth.Truth.assertWithMessage; +import static google.registry.testing.DatabaseHelper.insertSimpleResources; import static org.testcontainers.containers.PostgreSQLContainer.POSTGRESQL_PORT; import com.google.common.base.Charsets; @@ -24,9 +25,14 @@ import com.google.common.base.Joiner; import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import com.google.common.collect.Streams; import com.google.common.io.Resources; +import google.registry.model.registrar.Registrar; +import google.registry.model.registrar.Registrar.State; +import google.registry.model.registrar.RegistrarAddress; +import google.registry.model.registrar.RegistrarContact; import google.registry.persistence.HibernateSchemaExporter; import google.registry.persistence.NomulusPostgreSql; import google.registry.persistence.PersistenceModule; @@ -56,6 +62,7 @@ import javax.persistence.EntityManagerFactory; import org.hibernate.cfg.Environment; import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor; import org.hibernate.jpa.boot.spi.Bootstrap; +import org.joda.money.CurrencyUnit; import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.ExtensionContext; @@ -83,6 +90,9 @@ abstract class JpaTransactionManagerExtension implements BeforeEachCallback, Aft // is documented in PSQL's official user guide. private static final String CONNECTION_BACKEND_TYPE = "client backend"; private static final int ACTIVE_CONNECTIONS_CAP = 5; + public static final String NEW_REGISTRAR_GAE_USER_ID = "666"; + public static final String THE_REGISTRAR_GAE_USER_ID = "31337"; + public static final String MARLA_SINGER_GAE_USER_ID = "12345"; private final Clock clock; private final Optional initScriptPath; @@ -107,30 +117,23 @@ abstract class JpaTransactionManagerExtension implements BeforeEachCallback, Aft // to false. private boolean includeNomulusSchema = true; + // Whether to prepolulate some registrars for ease of testing. + private boolean withCannedData = false; + JpaTransactionManagerExtension( Clock clock, Optional initScriptPath, boolean includeNomulusSchema, ImmutableList> extraEntityClasses, - ImmutableMap userProperties) { + ImmutableMap userProperties, + boolean withCannedData) { this.clock = clock; this.initScriptPath = initScriptPath; this.includeNomulusSchema = includeNomulusSchema; this.extraEntityClasses = extraEntityClasses; this.userProperties = userProperties; this.entityHash = getOrmEntityHash(initScriptPath, extraEntityClasses); - } - - JpaTransactionManagerExtension( - Clock clock, - Optional initScriptPath, - ImmutableList> extraEntityClasses, - ImmutableMap userProperties) { - this.clock = clock; - this.initScriptPath = initScriptPath; - this.extraEntityClasses = extraEntityClasses; - this.userProperties = userProperties; - this.entityHash = getOrmEntityHash(initScriptPath, extraEntityClasses); + this.withCannedData = withCannedData; } private static JdbcDatabaseContainer create() { @@ -218,6 +221,9 @@ abstract class JpaTransactionManagerExtension implements BeforeEachCallback, Aft TransactionManagerFactory.setJpaTm(Suppliers.ofInstance(txnManager)); TransactionManagerFactory.setReplicaJpaTm( Suppliers.ofInstance(new ReplicaSimulatingJpaTransactionManager(txnManager))); + if (withCannedData) { + loadInitialData(); + } } @Override @@ -322,6 +328,118 @@ abstract class JpaTransactionManagerExtension implements BeforeEachCallback, Aft } } + private static Registrar.Builder makeRegistrarCommon() { + return new Registrar.Builder() + .setType(Registrar.Type.REAL) + .setState(State.ACTIVE) + .setIcannReferralEmail("lol@sloth.test") + .setUrl("http://my.fake.url") + .setInternationalizedAddress( + new RegistrarAddress.Builder() + .setStreet(ImmutableList.of("123 Example Boulevard")) + .setCity("Williamsburg") + .setState("NY") + .setZip("11211") + .setCountryCode("US") + .build()) + .setLocalizedAddress( + new RegistrarAddress.Builder() + .setStreet(ImmutableList.of("123 Example B\u0151ulevard")) + .setCity("Williamsburg") + .setState("NY") + .setZip("11211") + .setCountryCode("US") + .build()) + .setPhoneNumber("+1.3334445555") + .setPhonePasscode("12345") + .setBillingAccountMap(ImmutableMap.of(CurrencyUnit.USD, "abc123")) + .setContactsRequireSyncing(true); + } + + /** Public factory for first Registrar to allow comparison against stored value in unit tests. */ + public static Registrar makeRegistrar1() { + return makeRegistrarCommon() + .setRegistrarId("NewRegistrar") + .setRegistrarName("New Registrar") + .setEmailAddress("new.registrar@example.com") + .setIanaIdentifier(8L) + .setPassword("foo-BAR2") + .setPhoneNumber("+1.3334445555") + .setPhonePasscode("12345") + .setRegistryLockAllowed(false) + .build(); + } + + /** Public factory for second Registrar to allow comparison against stored value in unit tests. */ + public static Registrar makeRegistrar2() { + return makeRegistrarCommon() + .setRegistrarId("TheRegistrar") + .setRegistrarName("The Registrar") + .setEmailAddress("the.registrar@example.com") + .setIanaIdentifier(1L) + .setPassword("password2") + .setPhoneNumber("+1.2223334444") + .setPhonePasscode("22222") + .setRegistryLockAllowed(true) + .build(); + } + + /** + * Public factory for first RegistrarContact to allow comparison against stored value in unit + * tests. + */ + public static RegistrarContact makeRegistrarContact1() { + return new RegistrarContact.Builder() + .setParent(makeRegistrar1()) + .setName("Jane Doe") + .setVisibleInWhoisAsAdmin(true) + .setVisibleInWhoisAsTech(false) + .setEmailAddress("janedoe@theregistrar.com") + .setPhoneNumber("+1.1234567890") + .setTypes(ImmutableSet.of(RegistrarContact.Type.ADMIN)) + .build(); + } + + /** + * Public factory for second RegistrarContact to allow comparison against stored value in unit + * tests. + */ + public static RegistrarContact makeRegistrarContact2() { + return new RegistrarContact.Builder() + .setParent(makeRegistrar2()) + .setName("John Doe") + .setEmailAddress("johndoe@theregistrar.com") + .setPhoneNumber("+1.1234567890") + .setTypes(ImmutableSet.of(RegistrarContact.Type.ADMIN)) + .setGaeUserId(THE_REGISTRAR_GAE_USER_ID) + .build(); + } + + public static RegistrarContact makeRegistrarContact3() { + return new RegistrarContact.Builder() + .setParent(makeRegistrar2()) + .setName("Marla Singer") + .setEmailAddress("Marla.Singer@crr.com") + .setRegistryLockEmailAddress("Marla.Singer.RegistryLock@crr.com") + .setPhoneNumber("+1.2128675309") + .setTypes(ImmutableSet.of(RegistrarContact.Type.TECH)) + .setGaeUserId(MARLA_SINGER_GAE_USER_ID) + .setAllowedToSetRegistryLockPassword(true) + .setRegistryLockPassword("hi") + .build(); + } + + /** Create some fake registrars. */ + public static void loadInitialData() { + insertSimpleResources( + ImmutableList.of( + makeRegistrar1(), + makeRegistrarContact1(), + makeRegistrar2(), + makeRegistrarContact2(), + makeRegistrarContact3())); + } + /** Constructs the {@link EntityManagerFactory} instance. */ private EntityManagerFactory createEntityManagerFactory(ImmutableMap properties) { ParsedPersistenceXmlDescriptor descriptor =