Make domain:renew commands use the renewal price behavior (#1683)

* Make domain:renew commands use the renewal price behavior

This is based on PR #1592 by @rachelguan.
This commit is contained in:
Ben McIlwain 2022-06-24 17:36:28 -04:00 committed by GitHub
parent fb7558121b
commit cddcfc49ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 128 additions and 2 deletions

View file

@ -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<FeeRenewCommandExtension> 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 =

View file

@ -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<DomainRenewFlow, DomainBa
}
private void persistDomain(StatusValue... statusValues) throws Exception {
persistDomain(DEFAULT, null, statusValues);
}
private void persistDomain(
RenewalPriceBehavior renewalPriceBehavior,
@Nullable Money renewalPrice,
StatusValue... statusValues)
throws Exception {
DomainBase domain = newDomainBase(getUniqueIdFromCommand());
tm().transact(
() -> {
@ -145,6 +159,8 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, DomainBa
.setEventTime(expirationTime)
.setRecurrenceEndTime(END_OF_TIME)
.setParent(historyEntryDomainCreate)
.setRenewalPriceBehavior(renewalPriceBehavior)
.setRenewalPrice(renewalPrice)
.build();
PollMessage.Autorenew autorenewPollMessage =
new PollMessage.Autorenew.Builder()
@ -187,7 +203,9 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, DomainBa
"TheRegistrar",
UserPrivileges.NORMAL,
substitutions,
Money.of(USD, 11).multipliedBy(renewalYears));
Money.of(USD, 11).multipliedBy(renewalYears),
DEFAULT,
null);
}
private void doSuccessfulTest(
@ -198,6 +216,27 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, DomainBa
Map<String, String> 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<String, String> 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<DomainRenewFlow, DomainBa
renewBillingEvent,
new BillingEvent.Recurring.Builder()
.setReason(Reason.RENEW)
.setRenewalPriceBehavior(renewalPriceBehavior)
.setRenewalPrice(renewalPrice)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(getUniqueIdFromCommand())
.setRegistrarId("TheRegistrar")
@ -248,6 +289,8 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, DomainBa
.build(),
new BillingEvent.Recurring.Builder()
.setReason(Reason.RENEW)
.setRenewalPriceBehavior(renewalPriceBehavior)
.setRenewalPrice(renewalPrice)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(getUniqueIdFromCommand())
.setRegistrarId("TheRegistrar")
@ -317,6 +360,80 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, DomainBa
Money.of(USD, 55));
}
@TestOfyAndSql
void testSuccess_internalRegistration_standardDomain() throws Exception {
persistDomain(SPECIFIED, Money.of(USD, 2));
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, 10),
SPECIFIED,
Money.of(USD, 2));
}
@TestOfyAndSql
void testSuccess_internalRegiration_premiumDomain() throws Exception {
persistResource(
Registry.get("tld")
.asBuilder()
.setPremiumList(persistPremiumList("tld", USD, "example,USD 100"))
.build());
persistDomain(SPECIFIED, Money.of(USD, 2));
setRegistrarIdForFlow("NewRegistrar");
ImmutableMap<String, String> 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<String, String> 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