diff --git a/docs/flows.md b/docs/flows.md index a3ba50d14..45f2fd8ef 100644 --- a/docs/flows.md +++ b/docs/flows.md @@ -576,6 +576,7 @@ information about the domain. * The requested fees cannot be provided in the requested currency. * Fee checks for command phases and subphases are not supported. * Restores always renew a domain for one year. + * Transfers always renew a domain for one year. ## DomainDeleteFlow @@ -712,6 +713,7 @@ information. * Domain labels cannot begin with a dash. * Restores always renew a domain for one year. * Domain labels cannot end with a dash. + * Transfers always renew a domain for one year. * Unknown fee command name. * By server policy, fee check names must be listed in the availability check. diff --git a/java/google/registry/flows/custom/DomainPricingCustomLogic.java b/java/google/registry/flows/custom/DomainPricingCustomLogic.java index f30c580e9..44285bfd1 100644 --- a/java/google/registry/flows/custom/DomainPricingCustomLogic.java +++ b/java/google/registry/flows/custom/DomainPricingCustomLogic.java @@ -229,8 +229,6 @@ public class DomainPricingCustomLogic extends BaseFlowCustomLogic { public abstract DateTime asOfDate(); - public abstract int years(); - public static Builder newBuilder() { return new AutoValue_DomainPricingCustomLogic_TransferPriceParameters.Builder(); } @@ -247,8 +245,6 @@ public class DomainPricingCustomLogic extends BaseFlowCustomLogic { public abstract Builder setAsOfDate(DateTime asOfDate); - public abstract Builder setYears(int years); - public abstract TransferPriceParameters build(); } } diff --git a/java/google/registry/flows/domain/DomainCheckFlow.java b/java/google/registry/flows/domain/DomainCheckFlow.java index 5f85cc1ec..fceb9c9a7 100644 --- a/java/google/registry/flows/domain/DomainCheckFlow.java +++ b/java/google/registry/flows/domain/DomainCheckFlow.java @@ -90,6 +90,7 @@ import org.joda.time.DateTime; * @error {@link DomainFlowUtils.RestoresAreAlwaysForOneYearException} * @error {@link DomainFlowUtils.TldDoesNotExistException} * @error {@link DomainFlowUtils.TrailingDashException} + * @error {@link DomainFlowUtils.TransfersAreAlwaysForOneYearException} * @error {@link DomainFlowUtils.UnknownFeeCommandException} * @error {@link OnlyCheckedNamesCanBeFeeCheckedException} */ diff --git a/java/google/registry/flows/domain/DomainFlowUtils.java b/java/google/registry/flows/domain/DomainFlowUtils.java index 1705c9c49..1ddfebc9c 100644 --- a/java/google/registry/flows/domain/DomainFlowUtils.java +++ b/java/google/registry/flows/domain/DomainFlowUtils.java @@ -540,8 +540,11 @@ public class DomainFlowUtils { fees = pricingLogic.getRestorePrice(registry, domainNameString, now).getFees(); break; case TRANSFER: + if (years != 1) { + throw new TransfersAreAlwaysForOneYearException(); + } builder.setAvailIfSupported(true); - fees = pricingLogic.getTransferPrice(registry, domainNameString, now, years).getFees(); + fees = pricingLogic.getTransferPrice(registry, domainNameString, now).getFees(); break; case UPDATE: builder.setAvailIfSupported(true); @@ -1113,6 +1116,13 @@ public class DomainFlowUtils { } } + /** Transfers always renew a domain for one year. */ + static class TransfersAreAlwaysForOneYearException extends ParameterValuePolicyErrorException { + TransfersAreAlwaysForOneYearException() { + super("Transfers always renew a domain for one year"); + } + } + /** Requested domain is reserved. */ static class DomainReservedException extends StatusProhibitsOperationException { public DomainReservedException(String domainName) { diff --git a/java/google/registry/flows/domain/DomainInfoFlow.java b/java/google/registry/flows/domain/DomainInfoFlow.java index 55d2f5b1d..e431f001b 100644 --- a/java/google/registry/flows/domain/DomainInfoFlow.java +++ b/java/google/registry/flows/domain/DomainInfoFlow.java @@ -66,6 +66,7 @@ import org.joda.time.DateTime; * @error {@link DomainFlowUtils.CurrencyUnitMismatchException} * @error {@link DomainFlowUtils.FeeChecksDontSupportPhasesException} * @error {@link DomainFlowUtils.RestoresAreAlwaysForOneYearException} + * @error {@link DomainFlowUtils.TransfersAreAlwaysForOneYearException} */ public final class DomainInfoFlow implements Flow { diff --git a/java/google/registry/flows/domain/DomainPricingLogic.java b/java/google/registry/flows/domain/DomainPricingLogic.java index fad65ff11..b8c607175 100644 --- a/java/google/registry/flows/domain/DomainPricingLogic.java +++ b/java/google/registry/flows/domain/DomainPricingLogic.java @@ -110,7 +110,6 @@ public final class DomainPricingLogic { } /** Returns a new restore price for the pricer. */ - @SuppressWarnings("unused") public FeesAndCredits getRestorePrice(Registry registry, String domainName, DateTime date) throws EppException { FeesAndCredits feesAndCredits = @@ -131,13 +130,9 @@ public final class DomainPricingLogic { } /** Returns a new transfer price for the pricer. */ - public FeesAndCredits getTransferPrice( - Registry registry, - String domainName, - DateTime transferDate, - int years) + public FeesAndCredits getTransferPrice(Registry registry, String domainName, DateTime date) throws EppException { - Money renewCost = getDomainRenewCost(domainName, transferDate, years); + Money renewCost = getDomainRenewCost(domainName, date, 1); return customLogic.customizeTransferPrice( TransferPriceParameters.newBuilder() .setFeesAndCredits( @@ -147,8 +142,7 @@ public final class DomainPricingLogic { .build()) .setRegistry(registry) .setDomainName(InternetDomainName.from(domainName)) - .setAsOfDate(transferDate) - .setYears(years) + .setAsOfDate(date) .build()); } diff --git a/java/google/registry/flows/domain/DomainTransferRequestFlow.java b/java/google/registry/flows/domain/DomainTransferRequestFlow.java index a1ff6ab77..9af6d26b9 100644 --- a/java/google/registry/flows/domain/DomainTransferRequestFlow.java +++ b/java/google/registry/flows/domain/DomainTransferRequestFlow.java @@ -137,7 +137,7 @@ public final class DomainTransferRequestFlow implements TransactionalFlow { // An optional extension from the client specifying what they think the transfer should cost. FeeTransferCommandExtension feeTransfer = eppInput.getSingleExtension(FeeTransferCommandExtension.class); - FeesAndCredits feesAndCredits = pricingLogic.getTransferPrice(registry, targetId, now, years); + FeesAndCredits feesAndCredits = pricingLogic.getTransferPrice(registry, targetId, now); validateFeeChallenge(targetId, tld, now, feeTransfer, feesAndCredits); HistoryEntry historyEntry = buildHistory(period, existingDomain, now); DateTime automaticTransferTime = now.plus(registry.getAutomaticTransferLength()); diff --git a/javatests/google/registry/flows/domain/DomainCheckFlowTest.java b/javatests/google/registry/flows/domain/DomainCheckFlowTest.java index b89ff0a8c..c02e556bf 100644 --- a/javatests/google/registry/flows/domain/DomainCheckFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainCheckFlowTest.java @@ -47,6 +47,7 @@ import google.registry.flows.domain.DomainFlowUtils.NotAuthorizedForTldException import google.registry.flows.domain.DomainFlowUtils.RestoresAreAlwaysForOneYearException; import google.registry.flows.domain.DomainFlowUtils.TldDoesNotExistException; import google.registry.flows.domain.DomainFlowUtils.TrailingDashException; +import google.registry.flows.domain.DomainFlowUtils.TransfersAreAlwaysForOneYearException; import google.registry.flows.domain.DomainFlowUtils.UnknownFeeCommandException; import google.registry.flows.exceptions.TooManyResourceChecksException; import google.registry.model.domain.DomainResource; @@ -767,6 +768,27 @@ public class DomainCheckFlowTest runFlow(); } + @Test + public void testFeeExtension_multiyearTransfer_v06() throws Exception { + setEppInput("domain_check_fee_multiyear_transfer_v06.xml"); + thrown.expect(TransfersAreAlwaysForOneYearException.class); + runFlow(); + } + + @Test + public void testFeeExtension_multiyearTransfer_v11() throws Exception { + setEppInput("domain_check_fee_multiyear_transfer_v11.xml"); + thrown.expect(TransfersAreAlwaysForOneYearException.class); + runFlow(); + } + + @Test + public void testFeeExtension_multiyearTransfer_v12() throws Exception { + setEppInput("domain_check_fee_multiyear_transfer_v12.xml"); + thrown.expect(TransfersAreAlwaysForOneYearException.class); + runFlow(); + } + @Test public void testFeeExtension_unknownCommand_v06() throws Exception { setEppInput("domain_check_fee_unknown_command_v06.xml"); diff --git a/javatests/google/registry/flows/domain/DomainInfoFlowTest.java b/javatests/google/registry/flows/domain/DomainInfoFlowTest.java index adbba7d5c..71bea32a0 100644 --- a/javatests/google/registry/flows/domain/DomainInfoFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainInfoFlowTest.java @@ -43,6 +43,7 @@ import google.registry.flows.domain.DomainFlowUtils.BadPeriodUnitException; import google.registry.flows.domain.DomainFlowUtils.CurrencyUnitMismatchException; import google.registry.flows.domain.DomainFlowUtils.FeeChecksDontSupportPhasesException; import google.registry.flows.domain.DomainFlowUtils.RestoresAreAlwaysForOneYearException; +import google.registry.flows.domain.DomainFlowUtils.TransfersAreAlwaysForOneYearException; import google.registry.model.billing.BillingEvent.Recurring; import google.registry.model.contact.ContactAuthInfo; import google.registry.model.contact.ContactResource; @@ -625,6 +626,15 @@ public class DomainInfoFlowTest extends ResourceFlowTestCase + + + + example1.tld + + + + + custom + + + + example1.tld + transfer + 2 + + + + ABC-12345 + + diff --git a/javatests/google/registry/flows/domain/testdata/domain_check_fee_multiyear_transfer_v11.xml b/javatests/google/registry/flows/domain/testdata/domain_check_fee_multiyear_transfer_v11.xml new file mode 100644 index 000000000..2ce816e4e --- /dev/null +++ b/javatests/google/registry/flows/domain/testdata/domain_check_fee_multiyear_transfer_v11.xml @@ -0,0 +1,19 @@ + + + + + example1.tld + + + + + custom + + + transfer + 2 + + + ABC-12345 + + diff --git a/javatests/google/registry/flows/domain/testdata/domain_check_fee_multiyear_transfer_v12.xml b/javatests/google/registry/flows/domain/testdata/domain_check_fee_multiyear_transfer_v12.xml new file mode 100644 index 000000000..8bc0b4601 --- /dev/null +++ b/javatests/google/registry/flows/domain/testdata/domain_check_fee_multiyear_transfer_v12.xml @@ -0,0 +1,20 @@ + + + + + example1.tld + + + + + custom + + + + 2 + + + + ABC-12345 + + diff --git a/javatests/google/registry/flows/domain/testdata/domain_info_fee_multiyear_transfer.xml b/javatests/google/registry/flows/domain/testdata/domain_info_fee_multiyear_transfer.xml new file mode 100644 index 000000000..fc7538fd1 --- /dev/null +++ b/javatests/google/registry/flows/domain/testdata/domain_info_fee_multiyear_transfer.xml @@ -0,0 +1,18 @@ + + + + + example.tld + + + + + USD + transfer + 2 + + + ABC-12345 + + diff --git a/javatests/google/registry/flows/domain/testdata/domain_info_fee_transfer.xml b/javatests/google/registry/flows/domain/testdata/domain_info_fee_transfer.xml index fc7538fd1..d68f8a3fa 100644 --- a/javatests/google/registry/flows/domain/testdata/domain_info_fee_transfer.xml +++ b/javatests/google/registry/flows/domain/testdata/domain_info_fee_transfer.xml @@ -10,7 +10,7 @@ USD transfer - 2 + 1 ABC-12345 diff --git a/javatests/google/registry/flows/domain/testdata/domain_info_fee_transfer_response.xml b/javatests/google/registry/flows/domain/testdata/domain_info_fee_transfer_response.xml index 4304b4bbe..731c7ce21 100644 --- a/javatests/google/registry/flows/domain/testdata/domain_info_fee_transfer_response.xml +++ b/javatests/google/registry/flows/domain/testdata/domain_info_fee_transfer_response.xml @@ -34,8 +34,8 @@ USD transfer - 2 - 22.00 + 1 + 11.00