Wire in domain transfer custom pricing and add a test

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=142593949
This commit is contained in:
mcilwain 2016-12-20 14:00:09 -08:00 committed by Ben McIlwain
parent f0d2f96c26
commit 720f03cc17
11 changed files with 196 additions and 110 deletions

View file

@ -32,7 +32,6 @@ import static google.registry.flows.domain.DomainFlowUtils.verifyUnitIsYears;
import static google.registry.model.domain.DomainResource.extendRegistrationWithCap; import static google.registry.model.domain.DomainResource.extendRegistrationWithCap;
import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PENDING; import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PENDING;
import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.pricing.PricingEngineProxy.getDomainRenewCost;
import static google.registry.util.DateTimeUtils.END_OF_TIME; import static google.registry.util.DateTimeUtils.END_OF_TIME;
import com.google.common.base.Optional; import com.google.common.base.Optional;
@ -45,6 +44,7 @@ import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.Superuser; import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.FlowModule.TargetId; import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.TransactionalFlow; import google.registry.flows.TransactionalFlow;
import google.registry.flows.domain.DomainPricingLogic.FeesAndCredits;
import google.registry.flows.exceptions.AlreadyPendingTransferException; import google.registry.flows.exceptions.AlreadyPendingTransferException;
import google.registry.flows.exceptions.ObjectAlreadySponsoredException; import google.registry.flows.exceptions.ObjectAlreadySponsoredException;
import google.registry.model.billing.BillingEvent; import google.registry.model.billing.BillingEvent;
@ -53,8 +53,6 @@ import google.registry.model.billing.BillingEvent.Reason;
import google.registry.model.domain.DomainCommand.Transfer; import google.registry.model.domain.DomainCommand.Transfer;
import google.registry.model.domain.DomainResource; import google.registry.model.domain.DomainResource;
import google.registry.model.domain.Period; import google.registry.model.domain.Period;
import google.registry.model.domain.fee.BaseFee.FeeType;
import google.registry.model.domain.fee.Fee;
import google.registry.model.domain.fee.FeeTransferCommandExtension; import google.registry.model.domain.fee.FeeTransferCommandExtension;
import google.registry.model.domain.fee.FeeTransformResponseExtension; import google.registry.model.domain.fee.FeeTransformResponseExtension;
import google.registry.model.domain.flags.FlagsTransferCommandExtension; import google.registry.model.domain.flags.FlagsTransferCommandExtension;
@ -125,6 +123,7 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
@Inject HistoryEntry.Builder historyBuilder; @Inject HistoryEntry.Builder historyBuilder;
@Inject Trid trid; @Inject Trid trid;
@Inject EppResponse.Builder responseBuilder; @Inject EppResponse.Builder responseBuilder;
@Inject DomainPricingLogic pricingLogic;
@Inject DomainTransferRequestFlow() {} @Inject DomainTransferRequestFlow() {}
@Override @Override
@ -142,12 +141,11 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
verifyTransferAllowed(existingDomain, period, now); verifyTransferAllowed(existingDomain, period, now);
String tld = existingDomain.getTld(); String tld = existingDomain.getTld();
Registry registry = Registry.get(tld); Registry registry = Registry.get(tld);
// The cost of the renewal implied by a transfer.
Money renewCost = getDomainRenewCost(targetId, now, years);
// An optional extension from the client specifying what they think the transfer should cost. // An optional extension from the client specifying what they think the transfer should cost.
FeeTransferCommandExtension feeTransfer = FeeTransferCommandExtension feeTransfer =
eppInput.getSingleExtension(FeeTransferCommandExtension.class); eppInput.getSingleExtension(FeeTransferCommandExtension.class);
validateFeeChallenge(targetId, tld, now, feeTransfer, renewCost); FeesAndCredits feesAndCredits = pricingLogic.getTransferPrice(registry, targetId, now, years);
validateFeeChallenge(targetId, tld, now, feeTransfer, feesAndCredits.getTotalCost());
HistoryEntry historyEntry = buildHistory(period, existingDomain, now); HistoryEntry historyEntry = buildHistory(period, existingDomain, now);
DateTime automaticTransferTime = now.plus(registry.getAutomaticTransferLength()); DateTime automaticTransferTime = now.plus(registry.getAutomaticTransferLength());
// The new expiration time if there is a server approval. // The new expiration time if there is a server approval.
@ -160,7 +158,7 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
serverApproveNewExpirationTime, serverApproveNewExpirationTime,
historyEntry, historyEntry,
existingDomain, existingDomain,
renewCost, feesAndCredits.getTotalCost(),
years, years,
now); now);
// Create the transfer data that represents the pending transfer. // Create the transfer data that represents the pending transfer.
@ -189,7 +187,7 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
return responseBuilder return responseBuilder
.setResultFromCode(SUCCESS_WITH_ACTION_PENDING) .setResultFromCode(SUCCESS_WITH_ACTION_PENDING)
.setResData(createResponse(period, existingDomain, newDomain, now)) .setResData(createResponse(period, existingDomain, newDomain, now))
.setExtensions(createResponseExtensions(renewCost, feeTransfer)) .setExtensions(createResponseExtensions(feesAndCredits, feeTransfer))
.build(); .build();
} }
@ -241,7 +239,7 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
DateTime serverApproveNewExpirationTime, DateTime serverApproveNewExpirationTime,
HistoryEntry historyEntry, HistoryEntry historyEntry,
DomainResource existingDomain, DomainResource existingDomain,
Money renewCost, Money transferCost,
int years, int years,
DateTime now) { DateTime now) {
// Create a TransferData for the server-approve case to use for the speculative poll messages. // Create a TransferData for the server-approve case to use for the speculative poll messages.
@ -252,7 +250,7 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
Registry registry = Registry.get(existingDomain.getTld()); Registry registry = Registry.get(existingDomain.getTld());
return new ImmutableSet.Builder<TransferServerApproveEntity>() return new ImmutableSet.Builder<TransferServerApproveEntity>()
.add(createTransferBillingEvent( .add(createTransferBillingEvent(
automaticTransferTime, historyEntry, registry, renewCost, years)) automaticTransferTime, historyEntry, registry, transferCost, years))
.addAll(createOptionalAutorenewCancellation( .addAll(createOptionalAutorenewCancellation(
automaticTransferTime, historyEntry, existingDomain) automaticTransferTime, historyEntry, existingDomain)
.asSet()) .asSet())
@ -271,13 +269,13 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
DateTime automaticTransferTime, DateTime automaticTransferTime,
HistoryEntry historyEntry, HistoryEntry historyEntry,
Registry registry, Registry registry,
Money renewCost, Money transferCost,
int years) { int years) {
return new BillingEvent.OneTime.Builder() return new BillingEvent.OneTime.Builder()
.setReason(Reason.TRANSFER) .setReason(Reason.TRANSFER)
.setTargetId(targetId) .setTargetId(targetId)
.setClientId(gainingClientId) .setClientId(gainingClientId)
.setCost(renewCost) .setCost(transferCost)
.setPeriodYears(years) .setPeriodYears(years)
.setEventTime(automaticTransferTime) .setEventTime(automaticTransferTime)
.setBillingTime(automaticTransferTime.plus(registry.getTransferGracePeriodLength())) .setBillingTime(automaticTransferTime.plus(registry.getTransferGracePeriodLength()))
@ -388,13 +386,14 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
targetId, newDomain.getTransferData(), approveNowExtendedRegistrationTime); targetId, newDomain.getTransferData(), approveNowExtendedRegistrationTime);
} }
private ImmutableList<FeeTransformResponseExtension> createResponseExtensions(Money renewCost, private static ImmutableList<FeeTransformResponseExtension> createResponseExtensions(
FeeTransferCommandExtension feeTransfer) { FeesAndCredits feesAndCredits, FeeTransferCommandExtension feeTransfer) {
return feeTransfer == null return feeTransfer == null
? ImmutableList.<FeeTransformResponseExtension>of() ? ImmutableList.<FeeTransformResponseExtension>of()
: ImmutableList.of(feeTransfer.createResponseBuilder() : ImmutableList.of(feeTransfer.createResponseBuilder()
.setCurrency(renewCost.getCurrencyUnit()) .setFees(feesAndCredits.getFees())
.setFees(ImmutableList.of(Fee.create(renewCost.getAmount(), FeeType.RENEW))) .setCredits(feesAndCredits.getCredits())
.setCurrency(feesAndCredits.getCurrency())
.build()); .build());
} }
} }

View file

@ -48,6 +48,14 @@ public abstract class BaseFee extends ImmutableObject {
EAP("Early Access Period, fee expires: %s"), EAP("Early Access Period, fee expires: %s"),
RENEW("renew"), RENEW("renew"),
RESTORE("restore"), RESTORE("restore"),
/**
* A transfer fee.
*
* <p>These are not used by the default system, in which the only fee associated with a transfer
* is the RENEW fee. These exist so that custom pricing logic can create a custom transfer fee
* if desired.
*/
TRANSFER("transfer"),
UPDATE("update"), UPDATE("update"),
CREDIT("%s credit"); CREDIT("%s credit");

View file

@ -42,27 +42,6 @@ public class TestDomainPricingCustomLogic extends DomainPricingCustomLogic {
super(eppInput, sessionMetadata); super(eppInput, sessionMetadata);
} }
private static BaseFee domainNameToFeeOrCredit(InternetDomainName domainName) {
// The second-level domain should be of the form "description-price", where description is the
// description string of the fee or credit, and price is the price (credit if negative, fee
// otherwise). To make sure this is a valid domain name, don't use any spaces, and limit prices
// to integers. Don't use a two-character description for credits, since it is illegal to have
// both the third and fourth characters of a domain name label be hyphens.
List<String> components =
Splitter.on('-')
.limit(2)
.splitToList(Iterables.getFirst(Splitter.on('.').split(domainName.toString()), ""));
checkArgument(components.size() == 2, "Domain name must be of the form description-price.tld");
int price = Integer.parseInt(components.get(1));
if (price < 0) {
return Credit.create(
new BigDecimal(price), FeeType.valueOf(Ascii.toUpperCase(components.get(0))));
} else {
return Fee.create(
new BigDecimal(price), FeeType.valueOf(Ascii.toUpperCase(components.get(0))));
}
}
@Override @Override
public FeesAndCredits customizeCreatePrice(CreatePriceParameters priceParameters) public FeesAndCredits customizeCreatePrice(CreatePriceParameters priceParameters)
throws EppException { throws EppException {
@ -85,53 +64,68 @@ public class TestDomainPricingCustomLogic extends DomainPricingCustomLogic {
@Override @Override
public FeesAndCredits customizeApplicationUpdatePrice( public FeesAndCredits customizeApplicationUpdatePrice(
ApplicationUpdatePriceParameters priceParameters) throws EppException { ApplicationUpdatePriceParameters priceParameters) throws EppException {
if (priceParameters return (priceParameters
.domainApplication() .domainApplication()
.getFullyQualifiedDomainName() .getFullyQualifiedDomainName()
.startsWith("non-free-update")) { .startsWith("non-free-update"))
FeesAndCredits feesAndCredits = priceParameters.feesAndCredits(); ? addCustomFee(
List<BaseFee> newFeesAndCredits = priceParameters.feesAndCredits(), Fee.create(BigDecimal.valueOf(100), FeeType.UPDATE))
new ImmutableList.Builder<BaseFee>() : priceParameters.feesAndCredits();
.addAll(feesAndCredits.getFeesAndCredits())
.add(Fee.create(BigDecimal.valueOf(100), FeeType.UPDATE))
.build();
return new FeesAndCredits(
feesAndCredits.getCurrency(), toArray(newFeesAndCredits, BaseFee.class));
} else {
return priceParameters.feesAndCredits();
}
} }
@Override @Override
public FeesAndCredits customizeRenewPrice(RenewPriceParameters priceParameters) public FeesAndCredits customizeRenewPrice(RenewPriceParameters priceParameters)
throws EppException { throws EppException {
if (priceParameters.domainName().toString().startsWith("costly-renew")) { return (priceParameters.domainName().toString().startsWith("costly-renew"))
FeesAndCredits feesAndCredits = priceParameters.feesAndCredits(); ? addCustomFee(
List<BaseFee> newFeesAndCredits = priceParameters.feesAndCredits(), Fee.create(BigDecimal.valueOf(100), FeeType.RENEW))
new ImmutableList.Builder<BaseFee>() : priceParameters.feesAndCredits();
.addAll(feesAndCredits.getFeesAndCredits())
.add(Fee.create(BigDecimal.valueOf(100), FeeType.RENEW))
.build();
return new FeesAndCredits(
feesAndCredits.getCurrency(), toArray(newFeesAndCredits, BaseFee.class));
} else {
return priceParameters.feesAndCredits();
} }
@Override
public FeesAndCredits customizeTransferPrice(TransferPriceParameters priceParameters)
throws EppException {
return (priceParameters.domainName().toString().startsWith("expensive"))
? addCustomFee(
priceParameters.feesAndCredits(), Fee.create(BigDecimal.valueOf(100), FeeType.TRANSFER))
: priceParameters.feesAndCredits();
} }
@Override @Override
public FeesAndCredits customizeUpdatePrice(UpdatePriceParameters priceParameters) { public FeesAndCredits customizeUpdatePrice(UpdatePriceParameters priceParameters) {
if (priceParameters.domainName().toString().startsWith("non-free-update")) { return (priceParameters.domainName().toString().startsWith("non-free-update"))
FeesAndCredits feesAndCredits = priceParameters.feesAndCredits(); ? addCustomFee(priceParameters.feesAndCredits(), Fee.create(TEN, FeeType.UPDATE))
: priceParameters.feesAndCredits();
}
private static FeesAndCredits addCustomFee(FeesAndCredits feesAndCredits, BaseFee customFee) {
List<BaseFee> newFeesAndCredits = List<BaseFee> newFeesAndCredits =
new ImmutableList.Builder<BaseFee>() new ImmutableList.Builder<BaseFee>()
.addAll(feesAndCredits.getFeesAndCredits()) .addAll(feesAndCredits.getFeesAndCredits())
.add(Fee.create(TEN, FeeType.UPDATE)) .add(customFee)
.build(); .build();
return new FeesAndCredits( return new FeesAndCredits(
feesAndCredits.getCurrency(), toArray(newFeesAndCredits, BaseFee.class)); feesAndCredits.getCurrency(), toArray(newFeesAndCredits, BaseFee.class));
}
private static BaseFee domainNameToFeeOrCredit(InternetDomainName domainName) {
// The second-level domain should be of the form "description-price", where description is the
// description string of the fee or credit, and price is the price (credit if negative, fee
// otherwise). To make sure this is a valid domain name, don't use any spaces, and limit prices
// to integers. Don't use a two-character description for credits, since it is illegal to have
// both the third and fourth characters of a domain name label be hyphens.
List<String> components =
Splitter.on('-')
.limit(2)
.splitToList(Iterables.getFirst(Splitter.on('.').split(domainName.toString()), ""));
checkArgument(components.size() == 2, "Domain name must be of the form description-price.tld");
int price = Integer.parseInt(components.get(1));
if (price < 0) {
return Credit.create(
new BigDecimal(price), FeeType.valueOf(Ascii.toUpperCase(components.get(0))));
} else { } else {
return priceParameters.feesAndCredits(); return Fee.create(
new BigDecimal(price), FeeType.valueOf(Ascii.toUpperCase(components.get(0))));
} }
} }
} }

View file

@ -94,7 +94,7 @@ public class DomainTransferApproveFlowTest
.build()); .build());
setClientIdForFlow("TheRegistrar"); setClientIdForFlow("TheRegistrar");
createTld("extra"); createTld("extra");
setupDomainWithPendingTransfer(); setupDomainWithPendingTransfer("example", "tld");
clock.advanceOneMilli(); clock.advanceOneMilli();
} }
@ -278,7 +278,7 @@ public class DomainTransferApproveFlowTest
.asBuilder() .asBuilder()
.setTransferGracePeriodLength(Duration.standardMinutes(10)) .setTransferGracePeriodLength(Duration.standardMinutes(10))
.build()); .build());
setupDomainWithPendingTransfer("net"); setupDomainWithPendingTransfer("example", "net");
doSuccessfulTest( doSuccessfulTest(
"net", "net",
"domain_transfer_approve_net.xml", "domain_transfer_approve_net.xml",

View file

@ -53,7 +53,7 @@ public class DomainTransferCancelFlowTest
public void setUp() throws Exception { public void setUp() throws Exception {
setEppInput("domain_transfer_cancel.xml"); setEppInput("domain_transfer_cancel.xml");
setClientIdForFlow("NewRegistrar"); setClientIdForFlow("NewRegistrar");
setupDomainWithPendingTransfer(); setupDomainWithPendingTransfer("example", "tld");
} }
private void doSuccessfulTest(String commandFilename, String expectedXmlFilename) private void doSuccessfulTest(String commandFilename, String expectedXmlFilename)

View file

@ -106,10 +106,6 @@ public class DomainTransferFlowTestCase<F extends Flow, R extends EppResource>
TRANSFER_REQUEST_TIME); TRANSFER_REQUEST_TIME);
} }
protected void setupDomain(String tld) throws Exception {
setupDomain("example", tld);
}
/** Adds a domain with no pending transfer on it. */ /** Adds a domain with no pending transfer on it. */
protected void setupDomain(String label, String tld) throws Exception { protected void setupDomain(String label, String tld) throws Exception {
createTld(tld); createTld(tld);
@ -230,14 +226,9 @@ public class DomainTransferFlowTestCase<F extends Flow, R extends EppResource>
.hasCurrentSponsorClientId("TheRegistrar"); .hasCurrentSponsorClientId("TheRegistrar");
} }
/** Adds a .tld domain that has a pending transfer on it from TheRegistrar to NewRegistrar. */
protected void setupDomainWithPendingTransfer() throws Exception {
setupDomainWithPendingTransfer("tld");
}
/** Adds a domain that has a pending transfer on it from TheRegistrar to NewRegistrar. */ /** Adds a domain that has a pending transfer on it from TheRegistrar to NewRegistrar. */
protected void setupDomainWithPendingTransfer(String tld) throws Exception { protected void setupDomainWithPendingTransfer(String label, String tld) throws Exception {
setupDomain(tld); setupDomain(label, tld);
domain = persistWithPendingTransfer(domain); domain = persistWithPendingTransfer(domain);
} }

View file

@ -42,7 +42,7 @@ public class DomainTransferQueryFlowTest
public void setUp() throws Exception { public void setUp() throws Exception {
setEppInput("domain_transfer_query.xml"); setEppInput("domain_transfer_query.xml");
setClientIdForFlow("NewRegistrar"); setClientIdForFlow("NewRegistrar");
setupDomainWithPendingTransfer(); setupDomainWithPendingTransfer("example", "tld");
} }
private void doSuccessfulTest( private void doSuccessfulTest(

View file

@ -55,7 +55,7 @@ public class DomainTransferRejectFlowTest
public void setUp() throws Exception { public void setUp() throws Exception {
setEppInput("domain_transfer_reject.xml"); setEppInput("domain_transfer_reject.xml");
setClientIdForFlow("TheRegistrar"); setClientIdForFlow("TheRegistrar");
setupDomainWithPendingTransfer(); setupDomainWithPendingTransfer("example", "tld");
clock.advanceOneMilli(); clock.advanceOneMilli();
} }

View file

@ -18,10 +18,10 @@ import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.testing.DatastoreHelper.assertBillingEvents; import static google.registry.testing.DatastoreHelper.assertBillingEvents;
import static google.registry.testing.DatastoreHelper.createTld; import static google.registry.testing.DatastoreHelper.createTld;
import static google.registry.testing.DatastoreHelper.deleteResource;
import static google.registry.testing.DatastoreHelper.getOnlyHistoryEntryOfType; import static google.registry.testing.DatastoreHelper.getOnlyHistoryEntryOfType;
import static google.registry.testing.DatastoreHelper.getOnlyPollMessage; import static google.registry.testing.DatastoreHelper.getOnlyPollMessage;
import static google.registry.testing.DatastoreHelper.getPollMessages; import static google.registry.testing.DatastoreHelper.getPollMessages;
import static google.registry.testing.DatastoreHelper.persistActiveContact;
import static google.registry.testing.DatastoreHelper.persistResource; import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.DomainResourceSubject.assertAboutDomains; import static google.registry.testing.DomainResourceSubject.assertAboutDomains;
import static google.registry.testing.GenericEppResourceSubject.assertAboutEppResources; import static google.registry.testing.GenericEppResourceSubject.assertAboutEppResources;
@ -33,6 +33,7 @@ import static org.joda.money.CurrencyUnit.EUR;
import static org.joda.money.CurrencyUnit.USD; import static org.joda.money.CurrencyUnit.USD;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.collect.FluentIterable; import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
@ -95,8 +96,6 @@ public class DomainTransferRequestFlowTest
public void setUp() throws Exception { public void setUp() throws Exception {
setEppInput("domain_transfer_request.xml"); setEppInput("domain_transfer_request.xml");
setClientIdForFlow("NewRegistrar"); setClientIdForFlow("NewRegistrar");
setupDomain("tld");
createTld("flags");
} }
private void assertTransferRequested(DomainResource domain) throws Exception { private void assertTransferRequested(DomainResource domain) throws Exception {
@ -107,7 +106,7 @@ public class DomainTransferRequestFlowTest
.hasTransferRequestClientTrid(getClientTrid()).and() .hasTransferRequestClientTrid(getClientTrid()).and()
.hasCurrentSponsorClientId("TheRegistrar").and() .hasCurrentSponsorClientId("TheRegistrar").and()
.hasPendingTransferExpirationTime( .hasPendingTransferExpirationTime(
clock.nowUtc().plus(Registry.get("tld").getAutomaticTransferLength())).and() clock.nowUtc().plus(Registry.get(domain.getTld()).getAutomaticTransferLength())).and()
.hasStatusValue(StatusValue.PENDING_TRANSFER); .hasStatusValue(StatusValue.PENDING_TRANSFER);
} }
@ -118,7 +117,8 @@ public class DomainTransferRequestFlowTest
} }
private void assertTransferApproved(DomainResource domain) { private void assertTransferApproved(DomainResource domain) {
DateTime afterAutoAck = clock.nowUtc().plus(Registry.get("tld").getAutomaticTransferLength()); DateTime afterAutoAck =
clock.nowUtc().plus(Registry.get(domain.getTld()).getAutomaticTransferLength());
assertAboutDomains().that(domain) assertAboutDomains().that(domain)
.hasTransferStatus(TransferStatus.SERVER_APPROVED).and() .hasTransferStatus(TransferStatus.SERVER_APPROVED).and()
.hasCurrentSponsorClientId("NewRegistrar").and() .hasCurrentSponsorClientId("NewRegistrar").and()
@ -128,7 +128,8 @@ public class DomainTransferRequestFlowTest
} }
private void assertTransferApproved(HostResource host) { private void assertTransferApproved(HostResource host) {
DateTime afterAutoAck = clock.nowUtc().plus(Registry.get("tld").getAutomaticTransferLength()); DateTime afterAutoAck =
clock.nowUtc().plus(Registry.get(domain.getTld()).getAutomaticTransferLength());
assertAboutHosts().that(host) assertAboutHosts().that(host)
.hasCurrentSponsorClientId("NewRegistrar").and() .hasCurrentSponsorClientId("NewRegistrar").and()
.hasLastTransferTime(afterAutoAck).and() .hasLastTransferTime(afterAutoAck).and()
@ -145,6 +146,7 @@ public class DomainTransferRequestFlowTest
String expectedXmlFilename, String expectedXmlFilename,
DateTime expectedExpirationTime, DateTime expectedExpirationTime,
Map<String, String> substitutions, Map<String, String> substitutions,
Optional<Money> transferCost,
BillingEvent.Cancellation.Builder... extraExpectedBillingEvents) throws Exception { BillingEvent.Cancellation.Builder... extraExpectedBillingEvents) throws Exception {
setEppInput(commandFilename, substitutions); setEppInput(commandFilename, substitutions);
ImmutableSet<GracePeriod> originalGracePeriods = domain.getGracePeriods(); ImmutableSet<GracePeriod> originalGracePeriods = domain.getGracePeriods();
@ -153,8 +155,8 @@ public class DomainTransferRequestFlowTest
// For all of the other transfer flow tests, 'now' corresponds to day 3 of the transfer, but // For all of the other transfer flow tests, 'now' corresponds to day 3 of the transfer, but
// for the request test we want that same 'now' to be the initial request time, so we shift // for the request test we want that same 'now' to be the initial request time, so we shift
// the transfer timeline 3 days later by adjusting the implicit transfer time here. // the transfer timeline 3 days later by adjusting the implicit transfer time here.
DateTime implicitTransferTime = Registry registry = Registry.get(domain.getTld());
clock.nowUtc().plus(Registry.get("tld").getAutomaticTransferLength()); DateTime implicitTransferTime = clock.nowUtc().plus(registry.getAutomaticTransferLength());
// Setup done; run the test. // Setup done; run the test.
assertTransactionalFlow(true); assertTransactionalFlow(true);
runFlowAssertResponse(readFile(expectedXmlFilename, substitutions)); runFlowAssertResponse(readFile(expectedXmlFilename, substitutions));
@ -183,10 +185,9 @@ public class DomainTransferRequestFlowTest
.setReason(Reason.TRANSFER) .setReason(Reason.TRANSFER)
.setTargetId(domain.getFullyQualifiedDomainName()) .setTargetId(domain.getFullyQualifiedDomainName())
.setEventTime(implicitTransferTime) .setEventTime(implicitTransferTime)
.setBillingTime( .setBillingTime(implicitTransferTime.plus(registry.getTransferGracePeriodLength()))
implicitTransferTime.plus(Registry.get("tld").getTransferGracePeriodLength()))
.setClientId("NewRegistrar") .setClientId("NewRegistrar")
.setCost(Money.of(USD, 11).multipliedBy(registrationYears)) .setCost(transferCost.or(Money.of(USD, 11).multipliedBy(registrationYears)))
.setPeriodYears(registrationYears) .setPeriodYears(registrationYears)
.setParent(historyEntryTransferRequest) .setParent(historyEntryTransferRequest)
.build(); .build();
@ -225,8 +226,8 @@ public class DomainTransferRequestFlowTest
GracePeriod.create( GracePeriod.create(
GracePeriodStatus.TRANSFER, GracePeriodStatus.TRANSFER,
clock.nowUtc() clock.nowUtc()
.plus(Registry.get("tld").getAutomaticTransferLength()) .plus(registry.getAutomaticTransferLength())
.plus(Registry.get("tld").getTransferGracePeriodLength()), .plus(registry.getTransferGracePeriodLength()),
"NewRegistrar", "NewRegistrar",
null), null),
transferBillingEvent)); transferBillingEvent));
@ -285,8 +286,8 @@ public class DomainTransferRequestFlowTest
.isEqualTo(expectedExpirationTime); .isEqualTo(expectedExpirationTime);
// And after the expected grace time, the grace period should be gone. // And after the expected grace time, the grace period should be gone.
DomainResource afterGracePeriod = domain.cloneProjectedAtTime( DomainResource afterGracePeriod = domain.cloneProjectedAtTime(
clock.nowUtc().plus(Registry.get("tld").getAutomaticTransferLength()).plus( clock.nowUtc().plus(registry.getAutomaticTransferLength()).plus(
Registry.get("tld").getTransferGracePeriodLength())); registry.getTransferGracePeriodLength()));
assertThat(afterGracePeriod.getGracePeriods()).isEmpty(); assertThat(afterGracePeriod.getGracePeriods()).isEmpty();
} }
@ -300,6 +301,7 @@ public class DomainTransferRequestFlowTest
expectedXmlFilename, expectedXmlFilename,
expectedExpirationTime, expectedExpirationTime,
ImmutableMap.<String, String>of(), ImmutableMap.<String, String>of(),
Optional.<Money>absent(),
extraExpectedBillingEvents); extraExpectedBillingEvents);
} }
@ -312,7 +314,8 @@ public class DomainTransferRequestFlowTest
commandFilename, commandFilename,
expectedXmlFilename, expectedXmlFilename,
domain.getRegistrationExpirationTime().plusYears(1), domain.getRegistrationExpirationTime().plusYears(1),
substitutions); substitutions,
Optional.<Money>absent());
} }
private void doSuccessfulTest(String commandFilename, String expectedXmlFilename) private void doSuccessfulTest(String commandFilename, String expectedXmlFilename)
@ -349,6 +352,7 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testDryRun() throws Exception { public void testDryRun() throws Exception {
setupDomain("example", "tld");
setEppInput("domain_transfer_request.xml"); setEppInput("domain_transfer_request.xml");
eppLoader.replaceAll("JD1234-REP", contact.getRepoId()); eppLoader.replaceAll("JD1234-REP", contact.getRepoId());
dryRunFlowAssertResponse(readFile("domain_transfer_request_response.xml")); dryRunFlowAssertResponse(readFile("domain_transfer_request_response.xml"));
@ -356,29 +360,34 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testSuccess() throws Exception { public void testSuccess() throws Exception {
setupDomain("example", "tld");
doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml"); doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml");
} }
@Test @Test
public void testSuccess_fee_v06() throws Exception { public void testSuccess_fee_v06() throws Exception {
setupDomain("example", "tld");
doSuccessfulTest( doSuccessfulTest(
"domain_transfer_request_fee.xml", "domain_transfer_request_response_fee.xml", FEE_06_MAP); "domain_transfer_request_fee.xml", "domain_transfer_request_response_fee.xml", FEE_06_MAP);
} }
@Test @Test
public void testSuccess_fee_v11() throws Exception { public void testSuccess_fee_v11() throws Exception {
setupDomain("example", "tld");
doSuccessfulTest( doSuccessfulTest(
"domain_transfer_request_fee.xml", "domain_transfer_request_response_fee.xml", FEE_11_MAP); "domain_transfer_request_fee.xml", "domain_transfer_request_response_fee.xml", FEE_11_MAP);
} }
@Test @Test
public void testSuccess_fee_v12() throws Exception { public void testSuccess_fee_v12() throws Exception {
setupDomain("example", "tld");
doSuccessfulTest( doSuccessfulTest(
"domain_transfer_request_fee.xml", "domain_transfer_request_response_fee.xml", FEE_12_MAP); "domain_transfer_request_fee.xml", "domain_transfer_request_response_fee.xml", FEE_12_MAP);
} }
@Test @Test
public void testSuccess_fee_withDefaultAttributes_v06() throws Exception { public void testSuccess_fee_withDefaultAttributes_v06() throws Exception {
setupDomain("example", "tld");
doSuccessfulTest( doSuccessfulTest(
"domain_transfer_request_fee_defaults.xml", "domain_transfer_request_fee_defaults.xml",
"domain_transfer_request_response_fee.xml", "domain_transfer_request_response_fee.xml",
@ -387,6 +396,7 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testSuccess_fee_withDefaultAttributes_v11() throws Exception { public void testSuccess_fee_withDefaultAttributes_v11() throws Exception {
setupDomain("example", "tld");
doSuccessfulTest( doSuccessfulTest(
"domain_transfer_request_fee_defaults.xml", "domain_transfer_request_fee_defaults.xml",
"domain_transfer_request_response_fee.xml", "domain_transfer_request_response_fee.xml",
@ -395,6 +405,7 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testSuccess_fee_withDefaultAttributes_v12() throws Exception { public void testSuccess_fee_withDefaultAttributes_v12() throws Exception {
setupDomain("example", "tld");
doSuccessfulTest( doSuccessfulTest(
"domain_transfer_request_fee_defaults.xml", "domain_transfer_request_fee_defaults.xml",
"domain_transfer_request_response_fee.xml", "domain_transfer_request_response_fee.xml",
@ -403,60 +414,70 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testFailure_refundableFee_v06() throws Exception { public void testFailure_refundableFee_v06() throws Exception {
setupDomain("example", "tld");
thrown.expect(UnsupportedFeeAttributeException.class); thrown.expect(UnsupportedFeeAttributeException.class);
doFailingTest("domain_transfer_request_fee_refundable.xml", FEE_06_MAP); doFailingTest("domain_transfer_request_fee_refundable.xml", FEE_06_MAP);
} }
@Test @Test
public void testFailure_refundableFee_v11() throws Exception { public void testFailure_refundableFee_v11() throws Exception {
setupDomain("example", "tld");
thrown.expect(UnsupportedFeeAttributeException.class); thrown.expect(UnsupportedFeeAttributeException.class);
doFailingTest("domain_transfer_request_fee_refundable.xml", FEE_11_MAP); doFailingTest("domain_transfer_request_fee_refundable.xml", FEE_11_MAP);
} }
@Test @Test
public void testFailure_refundableFee_v12() throws Exception { public void testFailure_refundableFee_v12() throws Exception {
setupDomain("example", "tld");
thrown.expect(UnsupportedFeeAttributeException.class); thrown.expect(UnsupportedFeeAttributeException.class);
doFailingTest("domain_transfer_request_fee_refundable.xml", FEE_12_MAP); doFailingTest("domain_transfer_request_fee_refundable.xml", FEE_12_MAP);
} }
@Test @Test
public void testFailure_gracePeriodFee_v06() throws Exception { public void testFailure_gracePeriodFee_v06() throws Exception {
setupDomain("example", "tld");
thrown.expect(UnsupportedFeeAttributeException.class); thrown.expect(UnsupportedFeeAttributeException.class);
doFailingTest("domain_transfer_request_fee_grace_period.xml", FEE_06_MAP); doFailingTest("domain_transfer_request_fee_grace_period.xml", FEE_06_MAP);
} }
@Test @Test
public void testFailure_gracePeriodFee_v11() throws Exception { public void testFailure_gracePeriodFee_v11() throws Exception {
setupDomain("example", "tld");
thrown.expect(UnsupportedFeeAttributeException.class); thrown.expect(UnsupportedFeeAttributeException.class);
doFailingTest("domain_transfer_request_fee_grace_period.xml", FEE_11_MAP); doFailingTest("domain_transfer_request_fee_grace_period.xml", FEE_11_MAP);
} }
@Test @Test
public void testFailure_gracePeriodFee_v12() throws Exception { public void testFailure_gracePeriodFee_v12() throws Exception {
setupDomain("example", "tld");
thrown.expect(UnsupportedFeeAttributeException.class); thrown.expect(UnsupportedFeeAttributeException.class);
doFailingTest("domain_transfer_request_fee_grace_period.xml", FEE_12_MAP); doFailingTest("domain_transfer_request_fee_grace_period.xml", FEE_12_MAP);
} }
@Test @Test
public void testFailure_appliedFee_v06() throws Exception { public void testFailure_appliedFee_v06() throws Exception {
setupDomain("example", "tld");
thrown.expect(UnsupportedFeeAttributeException.class); thrown.expect(UnsupportedFeeAttributeException.class);
doFailingTest("domain_transfer_request_fee_applied.xml", FEE_06_MAP); doFailingTest("domain_transfer_request_fee_applied.xml", FEE_06_MAP);
} }
@Test @Test
public void testFailure_appliedFee_v11() throws Exception { public void testFailure_appliedFee_v11() throws Exception {
setupDomain("example", "tld");
thrown.expect(UnsupportedFeeAttributeException.class); thrown.expect(UnsupportedFeeAttributeException.class);
doFailingTest("domain_transfer_request_fee_applied.xml", FEE_11_MAP); doFailingTest("domain_transfer_request_fee_applied.xml", FEE_11_MAP);
} }
@Test @Test
public void testFailure_appliedFee_v12() throws Exception { public void testFailure_appliedFee_v12() throws Exception {
setupDomain("example", "tld");
thrown.expect(UnsupportedFeeAttributeException.class); thrown.expect(UnsupportedFeeAttributeException.class);
doFailingTest("domain_transfer_request_fee_applied.xml", FEE_12_MAP); doFailingTest("domain_transfer_request_fee_applied.xml", FEE_12_MAP);
} }
@Test @Test
public void testSuccess_nonDefaultAutomaticTransferLength() throws Exception { public void testSuccess_nonDefaultAutomaticTransferLength() throws Exception {
setupDomain("example", "tld");
persistResource( persistResource(
Registry.get("tld") Registry.get("tld")
.asBuilder() .asBuilder()
@ -469,6 +490,7 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testSuccess_nonDefaultTransferGracePeriod() throws Exception { public void testSuccess_nonDefaultTransferGracePeriod() throws Exception {
setupDomain("example", "tld");
persistResource( persistResource(
Registry.get("tld") Registry.get("tld")
.asBuilder() .asBuilder()
@ -479,12 +501,14 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testSuccess_missingPeriod() throws Exception { public void testSuccess_missingPeriod() throws Exception {
setupDomain("example", "tld");
doSuccessfulTest("domain_transfer_request_missing_period.xml", doSuccessfulTest("domain_transfer_request_missing_period.xml",
"domain_transfer_request_response.xml"); "domain_transfer_request_response.xml");
} }
@Test @Test
public void testSuccess_cappedExpiration() throws Exception { public void testSuccess_cappedExpiration() throws Exception {
setupDomain("example", "tld");
// The current expiration is in 15 months, so requesting 10 years would give 11 years 3 months, // The current expiration is in 15 months, so requesting 10 years would give 11 years 3 months,
// were it not that we cap at 10 years. (MAX_REGISTRATION_YEARS == 10 and is unlikely to ever // were it not that we cap at 10 years. (MAX_REGISTRATION_YEARS == 10 and is unlikely to ever
// change; we just use a constant for readability.) // change; we just use a constant for readability.)
@ -497,13 +521,31 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testSuccess_domainAuthInfo() throws Exception { public void testSuccess_domainAuthInfo() throws Exception {
setupDomain("example", "tld");
doSuccessfulTest( doSuccessfulTest(
"domain_transfer_request_domain_authinfo.xml", "domain_transfer_request_domain_authinfo.xml",
"domain_transfer_request_response.xml"); "domain_transfer_request_response.xml");
} }
@Test
public void testSuccess_customLogicFee() throws Exception {
setupDomain("expensive-domain", "foo");
clock.advanceOneMilli();
doSuccessfulTest(
"domain_transfer_request_wildcard.xml",
"domain_transfer_request_response_wildcard.xml",
domain.getRegistrationExpirationTime().plusYears(3),
new ImmutableMap.Builder<String, String>()
.put("DOMAIN", "expensive-domain.foo")
.put("YEARS", "3")
.put("EXDATE", "2004-09-08T22:00:00.0Z")
.build(),
Optional.of(Money.of(USD, 133)));
}
@Test @Test
public void testFailure_notAuthorizedForTld() throws Exception { public void testFailure_notAuthorizedForTld() throws Exception {
setupDomain("example", "tld");
persistResource( persistResource(
Registrar.loadByClientId("NewRegistrar") Registrar.loadByClientId("NewRegistrar")
.asBuilder() .asBuilder()
@ -515,6 +557,7 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testSuccess_autorenewBeforeAutomaticTransfer() throws Exception { public void testSuccess_autorenewBeforeAutomaticTransfer() throws Exception {
setupDomain("example", "tld");
DomainResource oldResource = persistResource(reloadResourceByForeignKey().asBuilder() DomainResource oldResource = persistResource(reloadResourceByForeignKey().asBuilder()
.setRegistrationExpirationTime(clock.nowUtc().plusDays(1).plus(1)) .setRegistrationExpirationTime(clock.nowUtc().plusDays(1).plus(1))
.build()); .build());
@ -559,6 +602,7 @@ public class DomainTransferRequestFlowTest
} }
private void runWrongCurrencyTest(Map<String, String> substitutions) throws Exception { private void runWrongCurrencyTest(Map<String, String> substitutions) throws Exception {
setupDomain("example", "tld");
persistResource( persistResource(
Registry.get("tld") Registry.get("tld")
.asBuilder() .asBuilder()
@ -575,33 +619,39 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testFailure_wrongCurrency_v06() throws Exception { public void testFailure_wrongCurrency_v06() throws Exception {
setupDomain("example", "tld");
runWrongCurrencyTest(FEE_06_MAP); runWrongCurrencyTest(FEE_06_MAP);
} }
@Test @Test
public void testFailure_wrongCurrency_v11() throws Exception { public void testFailure_wrongCurrency_v11() throws Exception {
setupDomain("example", "tld");
runWrongCurrencyTest(FEE_11_MAP); runWrongCurrencyTest(FEE_11_MAP);
} }
@Test @Test
public void testFailure_wrongCurrency_v12() throws Exception { public void testFailure_wrongCurrency_v12() throws Exception {
setupDomain("example", "tld");
runWrongCurrencyTest(FEE_12_MAP); runWrongCurrencyTest(FEE_12_MAP);
} }
@Test @Test
public void testFailure_feeGivenInWrongScale_v06() throws Exception { public void testFailure_feeGivenInWrongScale_v06() throws Exception {
setupDomain("example", "tld");
thrown.expect(CurrencyValueScaleException.class); thrown.expect(CurrencyValueScaleException.class);
doFailingTest("domain_transfer_request_fee_bad_scale.xml", FEE_06_MAP); doFailingTest("domain_transfer_request_fee_bad_scale.xml", FEE_06_MAP);
} }
@Test @Test
public void testFailure_feeGivenInWrongScale_v11() throws Exception { public void testFailure_feeGivenInWrongScale_v11() throws Exception {
setupDomain("example", "tld");
thrown.expect(CurrencyValueScaleException.class); thrown.expect(CurrencyValueScaleException.class);
doFailingTest("domain_transfer_request_fee_bad_scale.xml", FEE_11_MAP); doFailingTest("domain_transfer_request_fee_bad_scale.xml", FEE_11_MAP);
} }
@Test @Test
public void testFailure_feeGivenInWrongScale_v12() throws Exception { public void testFailure_feeGivenInWrongScale_v12() throws Exception {
setupDomain("example", "tld");
thrown.expect(CurrencyValueScaleException.class); thrown.expect(CurrencyValueScaleException.class);
doFailingTest("domain_transfer_request_fee_bad_scale.xml", FEE_12_MAP); doFailingTest("domain_transfer_request_fee_bad_scale.xml", FEE_12_MAP);
} }
@ -619,16 +669,19 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testFailure_wrongFeeAmount_v06() throws Exception { public void testFailure_wrongFeeAmount_v06() throws Exception {
setupDomain("example", "tld");
runWrongFeeAmountTest(FEE_06_MAP); runWrongFeeAmountTest(FEE_06_MAP);
} }
@Test @Test
public void testFailure_wrongFeeAmount_v11() throws Exception { public void testFailure_wrongFeeAmount_v11() throws Exception {
setupDomain("example", "tld");
runWrongFeeAmountTest(FEE_11_MAP); runWrongFeeAmountTest(FEE_11_MAP);
} }
@Test @Test
public void testFailure_wrongFeeAmount_v12() throws Exception { public void testFailure_wrongFeeAmount_v12() throws Exception {
setupDomain("example", "tld");
runWrongFeeAmountTest(FEE_12_MAP); runWrongFeeAmountTest(FEE_12_MAP);
} }
@ -651,12 +704,14 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testFailure_noAuthInfo() throws Exception { public void testFailure_noAuthInfo() throws Exception {
setupDomain("example", "tld");
thrown.expect(MissingTransferRequestAuthInfoException.class); thrown.expect(MissingTransferRequestAuthInfoException.class);
doFailingTest("domain_transfer_request_no_authinfo.xml"); doFailingTest("domain_transfer_request_no_authinfo.xml");
} }
@Test @Test
public void testFailure_badContactPassword() throws Exception { public void testFailure_badContactPassword() throws Exception {
setupDomain("example", "tld");
// Change the contact's password so it does not match the password in the file. // Change the contact's password so it does not match the password in the file.
contact = persistResource( contact = persistResource(
contact.asBuilder() contact.asBuilder()
@ -668,6 +723,7 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testFailure_badContactRepoId() throws Exception { public void testFailure_badContactRepoId() throws Exception {
setupDomain("example", "tld");
// Set the contact to a different ROID, but don't persist it; this is just so the substitution // Set the contact to a different ROID, but don't persist it; this is just so the substitution
// code above will write the wrong ROID into the file. // code above will write the wrong ROID into the file.
contact = contact.asBuilder().setRepoId("DEADBEEF_TLD-ROID").build(); contact = contact.asBuilder().setRepoId("DEADBEEF_TLD-ROID").build();
@ -677,36 +733,42 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testSuccess_clientApproved() throws Exception { public void testSuccess_clientApproved() throws Exception {
setupDomain("example", "tld");
changeTransferStatus(TransferStatus.CLIENT_APPROVED); changeTransferStatus(TransferStatus.CLIENT_APPROVED);
doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml"); doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml");
} }
@Test @Test
public void testSuccess_clientRejected() throws Exception { public void testSuccess_clientRejected() throws Exception {
setupDomain("example", "tld");
changeTransferStatus(TransferStatus.CLIENT_REJECTED); changeTransferStatus(TransferStatus.CLIENT_REJECTED);
doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml"); doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml");
} }
@Test @Test
public void testSuccess_clientCancelled() throws Exception { public void testSuccess_clientCancelled() throws Exception {
setupDomain("example", "tld");
changeTransferStatus(TransferStatus.CLIENT_CANCELLED); changeTransferStatus(TransferStatus.CLIENT_CANCELLED);
doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml"); doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml");
} }
@Test @Test
public void testSuccess_serverApproved() throws Exception { public void testSuccess_serverApproved() throws Exception {
setupDomain("example", "tld");
changeTransferStatus(TransferStatus.SERVER_APPROVED); changeTransferStatus(TransferStatus.SERVER_APPROVED);
doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml"); doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml");
} }
@Test @Test
public void testSuccess_serverCancelled() throws Exception { public void testSuccess_serverCancelled() throws Exception {
setupDomain("example", "tld");
changeTransferStatus(TransferStatus.SERVER_CANCELLED); changeTransferStatus(TransferStatus.SERVER_CANCELLED);
doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml"); doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml");
} }
@Test @Test
public void testFailure_pending() throws Exception { public void testFailure_pending() throws Exception {
setupDomain("example", "tld");
domain = persistResource(domain.asBuilder() domain = persistResource(domain.asBuilder()
.setTransferData(domain.getTransferData().asBuilder() .setTransferData(domain.getTransferData().asBuilder()
.setTransferStatus(TransferStatus.PENDING) .setTransferStatus(TransferStatus.PENDING)
@ -719,6 +781,7 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testFailure_badDomainPassword() throws Exception { public void testFailure_badDomainPassword() throws Exception {
setupDomain("example", "tld");
// Change the domain's password so it does not match the password in the file. // Change the domain's password so it does not match the password in the file.
domain = persistResource(domain.asBuilder() domain = persistResource(domain.asBuilder()
.setAuthInfo(DomainAuthInfo.create(PasswordAuth.create("badpassword"))) .setAuthInfo(DomainAuthInfo.create(PasswordAuth.create("badpassword")))
@ -729,6 +792,7 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testFailure_sponsoringClient() throws Exception { public void testFailure_sponsoringClient() throws Exception {
setupDomain("example", "tld");
setClientIdForFlow("TheRegistrar"); setClientIdForFlow("TheRegistrar");
thrown.expect(ObjectAlreadySponsoredException.class); thrown.expect(ObjectAlreadySponsoredException.class);
doFailingTest("domain_transfer_request.xml"); doFailingTest("domain_transfer_request.xml");
@ -736,6 +800,7 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testFailure_deletedDomain() throws Exception { public void testFailure_deletedDomain() throws Exception {
setupDomain("example", "tld");
domain = persistResource( domain = persistResource(
domain.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build()); domain.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
thrown.expect( thrown.expect(
@ -746,7 +811,10 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testFailure_invalidDomain() throws Exception { public void testFailure_invalidDomain() throws Exception {
setEppInput("domain_transfer_request_wildcard.xml", ImmutableMap.of("DOMAIN", "--invalid")); setupDomain("example", "tld");
setEppInput(
"domain_transfer_request_wildcard.xml",
ImmutableMap.of("YEARS", "1", "DOMAIN", "--invalid", "EXDATE", "2002-09-08T22:00:00.0Z"));
eppLoader.replaceAll("JD1234-REP", contact.getRepoId()); eppLoader.replaceAll("JD1234-REP", contact.getRepoId());
assertTransactionalFlow(true); assertTransactionalFlow(true);
thrown.expect(ResourceDoesNotExistException.class, "(--invalid)"); thrown.expect(ResourceDoesNotExistException.class, "(--invalid)");
@ -755,21 +823,24 @@ public class DomainTransferRequestFlowTest
@Test @Test
public void testFailure_nonexistentDomain() throws Exception { public void testFailure_nonexistentDomain() throws Exception {
deleteResource(domain); createTld("tld");
contact = persistActiveContact("jd1234");
thrown.expect( thrown.expect(
ResourceDoesNotExistException.class, ResourceDoesNotExistException.class,
String.format("(%s)", getUniqueIdFromCommand())); String.format("(%s)", "example.tld"));
doFailingTest("domain_transfer_request.xml"); doFailingTest("domain_transfer_request.xml");
} }
@Test @Test
public void testFailure_periodInMonths() throws Exception { public void testFailure_periodInMonths() throws Exception {
setupDomain("example", "tld");
thrown.expect(BadPeriodUnitException.class); thrown.expect(BadPeriodUnitException.class);
doFailingTest("domain_transfer_request_months.xml"); doFailingTest("domain_transfer_request_months.xml");
} }
@Test @Test
public void testFailure_pendingDelete() throws Exception { public void testFailure_pendingDelete() throws Exception {
setupDomain("example", "tld");
domain = persistResource( domain = persistResource(
domain.asBuilder().addStatusValue(StatusValue.PENDING_DELETE).build()); domain.asBuilder().addStatusValue(StatusValue.PENDING_DELETE).build());
thrown.expect(ResourceStatusProhibitsOperationException.class); thrown.expect(ResourceStatusProhibitsOperationException.class);

View file

@ -0,0 +1,23 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<response>
<result code="1001">
<msg>Command completed successfully; action pending</msg>
</result>
<resData>
<domain:trnData
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>%DOMAIN%</domain:name>
<domain:trStatus>pending</domain:trStatus>
<domain:reID>NewRegistrar</domain:reID>
<domain:reDate>2000-06-09T22:00:00.0Z</domain:reDate>
<domain:acID>TheRegistrar</domain:acID>
<domain:acDate>2000-06-14T22:00:00.0Z</domain:acDate>
<domain:exDate>%EXDATE%</domain:exDate>
</domain:trnData>
</resData>
<trID>
<clTRID>ABC-12345</clTRID>
<svTRID>server-trid</svTRID>
</trID>
</response>
</epp>

View file

@ -4,7 +4,7 @@
<domain:transfer <domain:transfer
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0"> xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>%DOMAIN%</domain:name> <domain:name>%DOMAIN%</domain:name>
<domain:period unit="y">1</domain:period> <domain:period unit="y">%YEARS%</domain:period>
<domain:authInfo> <domain:authInfo>
<domain:pw roid="JD1234-REP">2fooBAR</domain:pw> <domain:pw roid="JD1234-REP">2fooBAR</domain:pw>
</domain:authInfo> </domain:authInfo>