mirror of
https://github.com/google/nomulus.git
synced 2025-07-06 11:13:35 +02:00
Add support for a domain transfer request superuser EPP extension
Allow superusers to change the transfer period to zero years and allow superusers to change the automatic transfer length. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=167598314
This commit is contained in:
parent
263aea3b2a
commit
2e4b63bb79
28 changed files with 1018 additions and 124 deletions
|
@ -50,11 +50,14 @@ import google.registry.flows.exceptions.NotPendingTransferException;
|
|||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.billing.BillingEvent.Cancellation;
|
||||
import google.registry.model.billing.BillingEvent.Cancellation.Builder;
|
||||
import google.registry.model.billing.BillingEvent.OneTime;
|
||||
import google.registry.model.billing.BillingEvent.Reason;
|
||||
import google.registry.model.contact.ContactAuthInfo;
|
||||
import google.registry.model.domain.DomainAuthInfo;
|
||||
import google.registry.model.domain.DomainResource;
|
||||
import google.registry.model.domain.GracePeriod;
|
||||
import google.registry.model.domain.Period;
|
||||
import google.registry.model.domain.Period.Unit;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
|
@ -64,6 +67,7 @@ import google.registry.model.poll.PollMessage;
|
|||
import google.registry.model.registry.Registry;
|
||||
import google.registry.model.reporting.DomainTransactionRecord;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.transfer.TransferData;
|
||||
import google.registry.model.transfer.TransferResponse.DomainTransferResponse;
|
||||
import google.registry.model.transfer.TransferStatus;
|
||||
import org.joda.money.Money;
|
||||
|
@ -128,6 +132,20 @@ public class DomainTransferApproveFlowTest
|
|||
DateTime expectedExpirationTime,
|
||||
int expectedYearsToCharge,
|
||||
BillingEvent.Cancellation.Builder... expectedCancellationBillingEvents) throws Exception {
|
||||
runSuccessfulFlowWithAssertions(
|
||||
tld,
|
||||
commandFilename,
|
||||
expectedXmlFilename,
|
||||
expectedExpirationTime);
|
||||
assertHistoryEntriesContainBillingEventsAndGracePeriods(
|
||||
tld, expectedYearsToCharge, expectedCancellationBillingEvents);
|
||||
}
|
||||
|
||||
private void runSuccessfulFlowWithAssertions(
|
||||
String tld,
|
||||
String commandFilename,
|
||||
String expectedXmlFilename,
|
||||
DateTime expectedExpirationTime) throws Exception {
|
||||
setEppLoader(commandFilename);
|
||||
Registry registry = Registry.get(tld);
|
||||
// Make sure the implicit billing event is there; it will be deleted by the flow.
|
||||
|
@ -157,46 +175,6 @@ public class DomainTransferApproveFlowTest
|
|||
assertAboutDomains().that(domain).hasRegistrationExpirationTime(expectedExpirationTime);
|
||||
assertThat(ofy().load().key(domain.getAutorenewBillingEvent()).now().getEventTime())
|
||||
.isEqualTo(expectedExpirationTime);
|
||||
// We expect three billing events: one for the transfer, a closed autorenew for the losing
|
||||
// client and an open autorenew for the gaining client that begins at the new expiration time.
|
||||
BillingEvent.OneTime transferBillingEvent = new BillingEvent.OneTime.Builder()
|
||||
.setReason(Reason.TRANSFER)
|
||||
.setTargetId(domain.getFullyQualifiedDomainName())
|
||||
.setEventTime(clock.nowUtc())
|
||||
.setBillingTime(clock.nowUtc().plus(registry.getTransferGracePeriodLength()))
|
||||
.setClientId("NewRegistrar")
|
||||
.setCost(Money.of(USD, 11).multipliedBy(expectedYearsToCharge))
|
||||
.setPeriodYears(expectedYearsToCharge)
|
||||
.setParent(historyEntryTransferApproved)
|
||||
.build();
|
||||
assertBillingEventsForResource(
|
||||
domain,
|
||||
FluentIterable.from(expectedCancellationBillingEvents)
|
||||
.transform(new Function<BillingEvent.Cancellation.Builder, BillingEvent>() {
|
||||
@Override
|
||||
public Cancellation apply(Builder builder) {
|
||||
return builder.setParent(historyEntryTransferApproved).build();
|
||||
}})
|
||||
.append(
|
||||
transferBillingEvent,
|
||||
getLosingClientAutorenewEvent().asBuilder()
|
||||
.setRecurrenceEndTime(clock.nowUtc())
|
||||
.build(),
|
||||
getGainingClientAutorenewEvent().asBuilder()
|
||||
.setEventTime(domain.getRegistrationExpirationTime())
|
||||
.setParent(historyEntryTransferApproved)
|
||||
.build())
|
||||
.toArray(BillingEvent.class));
|
||||
// There should be a grace period for the new transfer billing event.
|
||||
assertGracePeriods(
|
||||
domain.getGracePeriods(),
|
||||
ImmutableMap.of(
|
||||
GracePeriod.create(
|
||||
GracePeriodStatus.TRANSFER,
|
||||
clock.nowUtc().plus(registry.getTransferGracePeriodLength()),
|
||||
"NewRegistrar",
|
||||
null),
|
||||
transferBillingEvent));
|
||||
// The poll message (in the future) to the losing registrar for implicit ack should be gone.
|
||||
assertThat(getPollMessages(domain, "TheRegistrar", clock.nowUtc().plusMonths(1))).isEmpty();
|
||||
|
||||
|
@ -236,6 +214,97 @@ public class DomainTransferApproveFlowTest
|
|||
.getGracePeriods()).isEmpty();
|
||||
}
|
||||
|
||||
private void assertHistoryEntriesContainBillingEventsAndGracePeriods(
|
||||
String tld,
|
||||
int expectedYearsToCharge,
|
||||
BillingEvent.Cancellation.Builder... expectedCancellationBillingEvents)
|
||||
throws Exception {
|
||||
Registry registry = Registry.get(tld);
|
||||
domain = reloadResourceByForeignKey();
|
||||
final HistoryEntry historyEntryTransferApproved =
|
||||
getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_APPROVE);
|
||||
// We expect three billing events: one for the transfer, a closed autorenew for the losing
|
||||
// client and an open autorenew for the gaining client that begins at the new expiration time.
|
||||
OneTime transferBillingEvent =
|
||||
new BillingEvent.OneTime.Builder()
|
||||
.setReason(Reason.TRANSFER)
|
||||
.setTargetId(domain.getFullyQualifiedDomainName())
|
||||
.setEventTime(clock.nowUtc())
|
||||
.setBillingTime(clock.nowUtc().plus(registry.getTransferGracePeriodLength()))
|
||||
.setClientId("NewRegistrar")
|
||||
.setCost(Money.of(USD, 11).multipliedBy(expectedYearsToCharge))
|
||||
.setPeriodYears(expectedYearsToCharge)
|
||||
.setParent(historyEntryTransferApproved)
|
||||
.build();
|
||||
assertBillingEventsForResource(
|
||||
domain,
|
||||
FluentIterable.from(expectedCancellationBillingEvents)
|
||||
.transform(
|
||||
new Function<BillingEvent.Cancellation.Builder, BillingEvent>() {
|
||||
@Override
|
||||
public Cancellation apply(Builder builder) {
|
||||
return builder.setParent(historyEntryTransferApproved).build();
|
||||
}
|
||||
})
|
||||
.append(
|
||||
transferBillingEvent,
|
||||
getLosingClientAutorenewEvent()
|
||||
.asBuilder()
|
||||
.setRecurrenceEndTime(clock.nowUtc())
|
||||
.build(),
|
||||
getGainingClientAutorenewEvent()
|
||||
.asBuilder()
|
||||
.setEventTime(domain.getRegistrationExpirationTime())
|
||||
.setParent(historyEntryTransferApproved)
|
||||
.build())
|
||||
.toArray(BillingEvent.class));
|
||||
// There should be a grace period for the new transfer billing event.
|
||||
assertGracePeriods(
|
||||
domain.getGracePeriods(),
|
||||
ImmutableMap.of(
|
||||
GracePeriod.create(
|
||||
GracePeriodStatus.TRANSFER,
|
||||
clock.nowUtc().plus(registry.getTransferGracePeriodLength()),
|
||||
"NewRegistrar",
|
||||
null),
|
||||
transferBillingEvent));
|
||||
}
|
||||
|
||||
private void assertHistoryEntriesDoNotContainTransferBillingEventsOrGracePeriods(
|
||||
BillingEvent.Cancellation.Builder... expectedCancellationBillingEvents)
|
||||
throws Exception {
|
||||
domain = reloadResourceByForeignKey();
|
||||
final HistoryEntry historyEntryTransferApproved =
|
||||
getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_APPROVE);
|
||||
// We expect two billing events: a closed autorenew for the losing client and an open autorenew
|
||||
// for the gaining client that begins at the new expiration time.
|
||||
assertBillingEventsForResource(
|
||||
domain,
|
||||
FluentIterable.from(expectedCancellationBillingEvents)
|
||||
.transform(
|
||||
new Function<BillingEvent.Cancellation.Builder, BillingEvent>() {
|
||||
@Override
|
||||
public Cancellation apply(Builder builder) {
|
||||
return builder.setParent(historyEntryTransferApproved).build();
|
||||
}
|
||||
})
|
||||
.append(
|
||||
getLosingClientAutorenewEvent()
|
||||
.asBuilder()
|
||||
.setRecurrenceEndTime(clock.nowUtc())
|
||||
.build(),
|
||||
getGainingClientAutorenewEvent()
|
||||
.asBuilder()
|
||||
.setEventTime(domain.getRegistrationExpirationTime())
|
||||
.setParent(historyEntryTransferApproved)
|
||||
.build())
|
||||
.toArray(BillingEvent.class));
|
||||
// There should be no grace period.
|
||||
assertGracePeriods(
|
||||
domain.getGracePeriods(),
|
||||
ImmutableMap.of());
|
||||
}
|
||||
|
||||
private void doSuccessfulTest(String tld, String commandFilename, String expectedXmlFilename)
|
||||
throws Exception {
|
||||
clock.advanceOneMilli();
|
||||
|
@ -503,4 +572,23 @@ public class DomainTransferApproveFlowTest
|
|||
"tld", clock.nowUtc().plusDays(3), TRANSFER_SUCCESSFUL, 1));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_superuserExtension_transferPeriodZero() throws Exception {
|
||||
DomainResource domain = reloadResourceByForeignKey();
|
||||
TransferData.Builder transferDataBuilder = domain.getTransferData().asBuilder();
|
||||
persistResource(
|
||||
domain
|
||||
.asBuilder()
|
||||
.setTransferData(
|
||||
transferDataBuilder.setTransferPeriod(Period.create(0, Unit.YEARS)).build())
|
||||
.build());
|
||||
clock.advanceOneMilli();
|
||||
runSuccessfulFlowWithAssertions(
|
||||
"tld",
|
||||
"domain_transfer_approve.xml",
|
||||
"domain_transfer_approve_response_zero_period.xml",
|
||||
domain.getRegistrationExpirationTime().plusYears(0));
|
||||
assertHistoryEntriesDoNotContainTransferBillingEventsOrGracePeriods();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue