diff --git a/core/src/main/java/google/registry/flows/domain/DomainRenewFlow.java b/core/src/main/java/google/registry/flows/domain/DomainRenewFlow.java index d5ea48f12..563ba33d7 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainRenewFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainRenewFlow.java @@ -54,6 +54,7 @@ import google.registry.flows.custom.EntityChanges; import google.registry.model.billing.BillingEvent; import google.registry.model.billing.BillingEvent.OneTime; import google.registry.model.billing.BillingEvent.Reason; +import google.registry.model.billing.BillingEvent.Recurring; import google.registry.model.domain.DomainBase; import google.registry.model.domain.DomainCommand.Renew; import google.registry.model.domain.DomainHistory; @@ -153,9 +154,15 @@ public final class DomainRenewFlow implements TransactionalFlow { validateRegistrationPeriod(now, newExpirationTime); Optional feeRenew = eppInput.getSingleExtension(FeeRenewCommandExtension.class); + Recurring existingRecurringBillingEvent = + tm().loadByKey(existingDomain.getAutorenewBillingEvent()); FeesAndCredits feesAndCredits = pricingLogic.getRenewPrice( - Registry.get(existingDomain.getTld()), targetId, now, years, null); + Registry.get(existingDomain.getTld()), + targetId, + now, + years, + existingRecurringBillingEvent); validateFeeChallenge(targetId, now, feeRenew, feesAndCredits); flowCustomLogic.afterValidation( AfterValidationParameters.newBuilder() @@ -173,6 +180,8 @@ public final class DomainRenewFlow implements TransactionalFlow { BillingEvent.Recurring newAutorenewEvent = newAutorenewBillingEvent(existingDomain) .setEventTime(newExpirationTime) + .setRenewalPrice(existingRecurringBillingEvent.getRenewalPrice().orElse(null)) + .setRenewalPriceBehavior(existingRecurringBillingEvent.getRenewalPriceBehavior()) .setParent(domainHistoryKey) .build(); PollMessage.Autorenew newAutorenewPollMessage = diff --git a/core/src/test/java/google/registry/flows/domain/DomainRenewFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainRenewFlowTest.java index 0676a056e..8bf34aaef 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainRenewFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainRenewFlowTest.java @@ -16,6 +16,9 @@ package google.registry.flows.domain; import static com.google.common.truth.Truth.assertThat; import static google.registry.flows.domain.DomainTransferFlowTestCase.persistWithPendingTransfer; +import static google.registry.model.billing.BillingEvent.RenewalPriceBehavior.DEFAULT; +import static google.registry.model.billing.BillingEvent.RenewalPriceBehavior.NONPREMIUM; +import static google.registry.model.billing.BillingEvent.RenewalPriceBehavior.SPECIFIED; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.testing.DatabaseHelper.assertBillingEvents; import static google.registry.testing.DatabaseHelper.assertPollMessages; @@ -26,6 +29,7 @@ import static google.registry.testing.DatabaseHelper.loadRegistrar; import static google.registry.testing.DatabaseHelper.newDomainBase; import static google.registry.testing.DatabaseHelper.persistActiveDomain; import static google.registry.testing.DatabaseHelper.persistDeletedDomain; +import static google.registry.testing.DatabaseHelper.persistPremiumList; import static google.registry.testing.DatabaseHelper.persistResource; import static google.registry.testing.DatabaseHelper.persistResources; import static google.registry.testing.DomainBaseSubject.assertAboutDomains; @@ -64,6 +68,7 @@ import google.registry.flows.exceptions.ResourceStatusProhibitsOperationExceptio import google.registry.model.billing.BillingEvent; import google.registry.model.billing.BillingEvent.Flag; import google.registry.model.billing.BillingEvent.Reason; +import google.registry.model.billing.BillingEvent.RenewalPriceBehavior; import google.registry.model.domain.DomainBase; import google.registry.model.domain.DomainHistory; import google.registry.model.domain.GracePeriod; @@ -80,6 +85,7 @@ import google.registry.testing.DualDatabaseTest; import google.registry.testing.SetClockExtension; import google.registry.testing.TestOfyAndSql; import java.util.Map; +import javax.annotation.Nullable; import org.joda.money.Money; import org.joda.time.DateTime; import org.joda.time.Duration; @@ -125,6 +131,14 @@ class DomainRenewFlowTest extends ResourceFlowTestCase { @@ -145,6 +159,8 @@ class DomainRenewFlowTest extends ResourceFlowTestCase substitutions, Money totalRenewCost) throws Exception { + doSuccessfulTest( + responseFilename, + renewalYears, + renewalClientId, + userPrivileges, + substitutions, + totalRenewCost, + DEFAULT, + null); + } + + private void doSuccessfulTest( + String responseFilename, + int renewalYears, + String renewalClientId, + UserPrivileges userPrivileges, + Map substitutions, + Money totalRenewCost, + RenewalPriceBehavior renewalPriceBehavior, + @Nullable Money renewalPrice) + throws Exception { assertTransactionalFlow(true); DateTime currentExpiration = reloadResourceByForeignKey().getRegistrationExpirationTime(); DateTime newExpiration = currentExpiration.plusYears(renewalYears); @@ -237,6 +276,8 @@ class DomainRenewFlowTest extends ResourceFlowTestCase customFeeMap = updateSubstitutions(FEE_06_MAP, "FEE", "10.0"); + setEppInput("domain_renew_fee.xml", customFeeMap); + doSuccessfulTest( + "domain_renew_response_fee.xml", + 5, + "NewRegistrar", + UserPrivileges.SUPERUSER, + customFeeMap, + Money.of(USD, 10), + SPECIFIED, + Money.of(USD, 2)); + } + + @TestOfyAndSql + void testSuccess_anchorTenant_standardDomain() throws Exception { + persistDomain(NONPREMIUM, null); + setRegistrarIdForFlow("NewRegistrar"); + doSuccessfulTest( + "domain_renew_response.xml", + 5, + "NewRegistrar", + UserPrivileges.SUPERUSER, + ImmutableMap.of("DOMAIN", "example.tld", "EXDATE", "2005-04-03T22:00:00.0Z"), + Money.of(USD, 55), + NONPREMIUM, + null); + } + + @TestOfyAndSql + void testSuccess_anchorTenant_premiumDomain() throws Exception { + persistResource( + Registry.get("tld") + .asBuilder() + .setPremiumList(persistPremiumList("tld", USD, "example,USD 100")) + .build()); + persistDomain(NONPREMIUM, null); + setRegistrarIdForFlow("NewRegistrar"); + ImmutableMap customFeeMap = updateSubstitutions(FEE_06_MAP, "FEE", "55.0"); + setEppInput("domain_renew_fee.xml", customFeeMap); + doSuccessfulTest( + "domain_renew_response_fee.xml", + 5, + "NewRegistrar", + UserPrivileges.SUPERUSER, + customFeeMap, + Money.of(USD, 55), + NONPREMIUM, + null); + } + @TestOfyAndSql void testSuccess_customLogicFee() throws Exception { // The "costly-renew" domain has an additional RENEW fee of 100 from custom logic on top of the