mirror of
https://github.com/google/nomulus.git
synced 2025-04-30 12:07:51 +02:00
Remove package token on manual transfer approval (#1819)
* Remove package token on manual transfer approval * remove extra variables * Add back white space * Don't overwrite existingDomain * Format fixes, use available helper variables * Use PACKAGE allocation tokens in tests * Refactor * Fix merge conflicts * Dont overwrite existingRecurring
This commit is contained in:
parent
38e82a197d
commit
c03adf7091
2 changed files with 100 additions and 3 deletions
|
@ -49,6 +49,7 @@ import google.registry.model.billing.BillingEvent;
|
||||||
import google.registry.model.billing.BillingEvent.Flag;
|
import google.registry.model.billing.BillingEvent.Flag;
|
||||||
import google.registry.model.billing.BillingEvent.Reason;
|
import google.registry.model.billing.BillingEvent.Reason;
|
||||||
import google.registry.model.billing.BillingEvent.Recurring;
|
import google.registry.model.billing.BillingEvent.Recurring;
|
||||||
|
import google.registry.model.billing.BillingEvent.RenewalPriceBehavior;
|
||||||
import google.registry.model.domain.Domain;
|
import google.registry.model.domain.Domain;
|
||||||
import google.registry.model.domain.DomainHistory;
|
import google.registry.model.domain.DomainHistory;
|
||||||
import google.registry.model.domain.GracePeriod;
|
import google.registry.model.domain.GracePeriod;
|
||||||
|
@ -67,6 +68,7 @@ import google.registry.model.transfer.DomainTransferData;
|
||||||
import google.registry.model.transfer.TransferStatus;
|
import google.registry.model.transfer.TransferStatus;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import org.joda.money.Money;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -147,6 +149,8 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
|
||||||
Recurring existingRecurring = tm().loadByKey(existingDomain.getAutorenewBillingEvent());
|
Recurring existingRecurring = tm().loadByKey(existingDomain.getAutorenewBillingEvent());
|
||||||
HistoryEntryId domainHistoryId = createHistoryEntryId(existingDomain);
|
HistoryEntryId domainHistoryId = createHistoryEntryId(existingDomain);
|
||||||
historyBuilder.setRevisionId(domainHistoryId.getRevisionId());
|
historyBuilder.setRevisionId(domainHistoryId.getRevisionId());
|
||||||
|
boolean hasPackageToken = existingDomain.getCurrentPackageToken().isPresent();
|
||||||
|
Money renewalPrice = hasPackageToken ? null : existingRecurring.getRenewalPrice().orElse(null);
|
||||||
Optional<BillingEvent.OneTime> billingEvent =
|
Optional<BillingEvent.OneTime> billingEvent =
|
||||||
transferData.getTransferPeriod().getValue() == 0
|
transferData.getTransferPeriod().getValue() == 0
|
||||||
? Optional.empty()
|
? Optional.empty()
|
||||||
|
@ -162,12 +166,16 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
|
||||||
Registry.get(tld),
|
Registry.get(tld),
|
||||||
targetId,
|
targetId,
|
||||||
transferData.getTransferRequestTime(),
|
transferData.getTransferRequestTime(),
|
||||||
existingRecurring)
|
// When removing a domain from a package it should return to the
|
||||||
|
// default recurring billing behavior so the existing recurring
|
||||||
|
// billing event should not be passed in.
|
||||||
|
hasPackageToken ? null : existingRecurring)
|
||||||
.getRenewCost())
|
.getRenewCost())
|
||||||
.setEventTime(now)
|
.setEventTime(now)
|
||||||
.setBillingTime(now.plus(Registry.get(tld).getTransferGracePeriodLength()))
|
.setBillingTime(now.plus(Registry.get(tld).getTransferGracePeriodLength()))
|
||||||
.setDomainHistoryId(domainHistoryId)
|
.setDomainHistoryId(domainHistoryId)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
ImmutableList.Builder<ImmutableObject> entitiesToSave = new ImmutableList.Builder<>();
|
ImmutableList.Builder<ImmutableObject> entitiesToSave = new ImmutableList.Builder<>();
|
||||||
// If we are within an autorenew grace period, cancel the autorenew billing event and don't
|
// If we are within an autorenew grace period, cancel the autorenew billing event and don't
|
||||||
// increase the registration time, since the transfer subsumes the autorenew's extra year.
|
// increase the registration time, since the transfer subsumes the autorenew's extra year.
|
||||||
|
@ -198,8 +206,11 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
|
||||||
.setTargetId(targetId)
|
.setTargetId(targetId)
|
||||||
.setRegistrarId(gainingRegistrarId)
|
.setRegistrarId(gainingRegistrarId)
|
||||||
.setEventTime(newExpirationTime)
|
.setEventTime(newExpirationTime)
|
||||||
.setRenewalPriceBehavior(existingRecurring.getRenewalPriceBehavior())
|
.setRenewalPriceBehavior(
|
||||||
.setRenewalPrice(existingRecurring.getRenewalPrice().orElse(null))
|
hasPackageToken
|
||||||
|
? RenewalPriceBehavior.DEFAULT
|
||||||
|
: existingRecurring.getRenewalPriceBehavior())
|
||||||
|
.setRenewalPrice(renewalPrice)
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setDomainHistoryId(domainHistoryId)
|
.setDomainHistoryId(domainHistoryId)
|
||||||
.build();
|
.build();
|
||||||
|
@ -243,7 +254,11 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
|
||||||
.orElseGet(ImmutableSet::of))
|
.orElseGet(ImmutableSet::of))
|
||||||
.setLastEppUpdateTime(now)
|
.setLastEppUpdateTime(now)
|
||||||
.setLastEppUpdateRegistrarId(registrarId)
|
.setLastEppUpdateRegistrarId(registrarId)
|
||||||
|
// Even if the existing domain had a package token, that package token should be removed
|
||||||
|
// on transfer
|
||||||
|
.setCurrentPackageToken(null)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Registry registry = Registry.get(existingDomain.getTld());
|
Registry registry = Registry.get(existingDomain.getTld());
|
||||||
DomainHistory domainHistory = buildDomainHistory(newDomain, registry, now, gainingRegistrarId);
|
DomainHistory domainHistory = buildDomainHistory(newDomain, registry, now, gainingRegistrarId);
|
||||||
// Create a poll message for the gaining client.
|
// Create a poll message for the gaining client.
|
||||||
|
|
|
@ -16,6 +16,8 @@ package google.registry.flows.domain;
|
||||||
|
|
||||||
import static com.google.common.collect.MoreCollectors.onlyElement;
|
import static com.google.common.collect.MoreCollectors.onlyElement;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static com.google.common.truth.Truth8.assertThat;
|
||||||
|
import static google.registry.model.domain.token.AllocationToken.TokenType.PACKAGE;
|
||||||
import static google.registry.model.domain.token.AllocationToken.TokenType.SINGLE_USE;
|
import static google.registry.model.domain.token.AllocationToken.TokenType.SINGLE_USE;
|
||||||
import static google.registry.model.domain.token.AllocationToken.TokenType.UNLIMITED_USE;
|
import static google.registry.model.domain.token.AllocationToken.TokenType.UNLIMITED_USE;
|
||||||
import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.NET_ADDS_4_YR;
|
import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.NET_ADDS_4_YR;
|
||||||
|
@ -374,11 +376,91 @@ class DomainTransferApproveFlowTest
|
||||||
dryRunFlowAssertResponse(loadFile("domain_transfer_approve_response.xml"));
|
dryRunFlowAssertResponse(loadFile("domain_transfer_approve_response.xml"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDryRun_PackageDomain() throws Exception {
|
||||||
|
AllocationToken allocationToken =
|
||||||
|
persistResource(
|
||||||
|
new AllocationToken.Builder()
|
||||||
|
.setToken("abc123")
|
||||||
|
.setTokenType(PACKAGE)
|
||||||
|
.setRenewalPriceBehavior(RenewalPriceBehavior.SPECIFIED)
|
||||||
|
.setAllowedRegistrarIds(ImmutableSet.of("TheRegistrar"))
|
||||||
|
.build());
|
||||||
|
domain = reloadResourceByForeignKey();
|
||||||
|
persistResource(
|
||||||
|
loadByKey(domain.getAutorenewBillingEvent())
|
||||||
|
.asBuilder()
|
||||||
|
.setRenewalPriceBehavior(RenewalPriceBehavior.SPECIFIED)
|
||||||
|
.setRenewalPrice(Money.of(USD, new BigDecimal("10.00")))
|
||||||
|
.build());
|
||||||
|
persistResource(
|
||||||
|
domain.asBuilder().setCurrentPackageToken(allocationToken.createVKey()).build());
|
||||||
|
clock.advanceOneMilli();
|
||||||
|
setEppInput("domain_transfer_approve_wildcard.xml", ImmutableMap.of("DOMAIN", "example.tld"));
|
||||||
|
dryRunFlowAssertResponse(loadFile("domain_transfer_approve_response.xml"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSuccess() throws Exception {
|
void testSuccess() throws Exception {
|
||||||
doSuccessfulTest("tld", "domain_transfer_approve.xml", "domain_transfer_approve_response.xml");
|
doSuccessfulTest("tld", "domain_transfer_approve.xml", "domain_transfer_approve_response.xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSuccess_removesPackageToken() throws Exception {
|
||||||
|
AllocationToken allocationToken =
|
||||||
|
persistResource(
|
||||||
|
new AllocationToken.Builder()
|
||||||
|
.setToken("abc123")
|
||||||
|
.setTokenType(PACKAGE)
|
||||||
|
.setRenewalPriceBehavior(RenewalPriceBehavior.SPECIFIED)
|
||||||
|
.setAllowedRegistrarIds(ImmutableSet.of("TheRegistrar"))
|
||||||
|
.build());
|
||||||
|
domain = reloadResourceByForeignKey();
|
||||||
|
persistResource(
|
||||||
|
loadByKey(domain.getAutorenewBillingEvent())
|
||||||
|
.asBuilder()
|
||||||
|
.setRenewalPriceBehavior(RenewalPriceBehavior.SPECIFIED)
|
||||||
|
.setRenewalPrice(Money.of(USD, new BigDecimal("10.00")))
|
||||||
|
.build());
|
||||||
|
persistResource(
|
||||||
|
domain.asBuilder().setCurrentPackageToken(allocationToken.createVKey()).build());
|
||||||
|
clock.advanceOneMilli();
|
||||||
|
setEppInput("domain_transfer_approve_wildcard.xml", ImmutableMap.of("DOMAIN", "example.tld"));
|
||||||
|
DateTime now = clock.nowUtc();
|
||||||
|
runFlowAssertResponse(loadFile("domain_transfer_approve_response.xml"));
|
||||||
|
domain = reloadResourceByForeignKey();
|
||||||
|
DomainHistory acceptHistory =
|
||||||
|
getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_APPROVE, DomainHistory.class);
|
||||||
|
assertBillingEventsForResource(
|
||||||
|
domain,
|
||||||
|
new BillingEvent.OneTime.Builder()
|
||||||
|
.setBillingTime(now.plusDays(5))
|
||||||
|
.setEventTime(now)
|
||||||
|
.setRegistrarId("NewRegistrar")
|
||||||
|
.setCost(Money.of(USD, new BigDecimal("11.00")))
|
||||||
|
.setDomainHistory(acceptHistory)
|
||||||
|
.setReason(Reason.TRANSFER)
|
||||||
|
.setPeriodYears(1)
|
||||||
|
.setTargetId("example.tld")
|
||||||
|
.build(),
|
||||||
|
getGainingClientAutorenewEvent()
|
||||||
|
.asBuilder()
|
||||||
|
.setRenewalPriceBehavior(RenewalPriceBehavior.DEFAULT)
|
||||||
|
.setRenewalPrice(null)
|
||||||
|
.setDomainHistory(acceptHistory)
|
||||||
|
.build(),
|
||||||
|
getLosingClientAutorenewEvent()
|
||||||
|
.asBuilder()
|
||||||
|
.setRecurrenceEndTime(now)
|
||||||
|
.setRenewalPriceBehavior(RenewalPriceBehavior.SPECIFIED)
|
||||||
|
.setRenewalPrice(Money.of(USD, new BigDecimal("10.00")))
|
||||||
|
.build());
|
||||||
|
assertThat(domain.getCurrentPackageToken()).isEmpty();
|
||||||
|
assertThat(domain.getCurrentSponsorRegistrarId()).isEqualTo("NewRegistrar");
|
||||||
|
assertThat(loadByKey(domain.getAutorenewBillingEvent()).getRenewalPriceBehavior())
|
||||||
|
.isEqualTo(RenewalPriceBehavior.DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSuccess_nonDefaultTransferGracePeriod() throws Exception {
|
void testSuccess_nonDefaultTransferGracePeriod() throws Exception {
|
||||||
// We have to set up a new domain in a different TLD so that the billing event will be persisted
|
// We have to set up a new domain in a different TLD so that the billing event will be persisted
|
||||||
|
|
Loading…
Add table
Reference in a new issue