mirror of
https://github.com/google/nomulus.git
synced 2025-05-13 07:57:13 +02:00
Add the ability to require premium fee acking for a registrar
When enabled for a registrar, all EPP operations on premium domains that have costs (e.g. creates, renews, transfers) will fail unless the EPP fee extension is used to explicitly ack the amount of fee as part of the EPP transaction. This ack is required regardless of whether premium fee acking is required at the registry level. No data migration is necessary since false is the desired default for this new attribute. This CL also contains some slight refactoring of static utility methods used to perform fee verification; there was short-circuiting at call-sites in two places when what was really needed was two methods, one implementing additional functionality on top of the other, and calling the inner method in the places where short-circuiting had previously been necessary. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=184229363
This commit is contained in:
parent
6bcd40f18a
commit
98a61b8181
20 changed files with 264 additions and 119 deletions
|
@ -234,7 +234,7 @@ public final class DomainApplicationCreateFlow implements TransactionalFlow {
|
||||||
}
|
}
|
||||||
Optional<FeeCreateCommandExtension> feeCreate =
|
Optional<FeeCreateCommandExtension> feeCreate =
|
||||||
eppInput.getSingleExtension(FeeCreateCommandExtension.class);
|
eppInput.getSingleExtension(FeeCreateCommandExtension.class);
|
||||||
validateFeeChallenge(targetId, tld, now, feeCreate, feesAndCredits);
|
validateFeeChallenge(targetId, tld, clientId, now, feeCreate, feesAndCredits);
|
||||||
Optional<SecDnsCreateExtension> secDnsCreate =
|
Optional<SecDnsCreateExtension> secDnsCreate =
|
||||||
validateSecDnsExtension(eppInput.getSingleExtension(SecDnsCreateExtension.class));
|
validateSecDnsExtension(eppInput.getSingleExtension(SecDnsCreateExtension.class));
|
||||||
flowCustomLogic.afterValidation(
|
flowCustomLogic.afterValidation(
|
||||||
|
|
|
@ -30,7 +30,7 @@ import static google.registry.flows.domain.DomainFlowUtils.cloneAndLinkReference
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.updateDsData;
|
import static google.registry.flows.domain.DomainFlowUtils.updateDsData;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateContactsHaveTypes;
|
import static google.registry.flows.domain.DomainFlowUtils.validateContactsHaveTypes;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateDsData;
|
import static google.registry.flows.domain.DomainFlowUtils.validateDsData;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
|
import static google.registry.flows.domain.DomainFlowUtils.validateFeesAckedIfPresent;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateNameserversAllowedOnDomain;
|
import static google.registry.flows.domain.DomainFlowUtils.validateNameserversAllowedOnDomain;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateNameserversAllowedOnTld;
|
import static google.registry.flows.domain.DomainFlowUtils.validateNameserversAllowedOnTld;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateNameserversCountForTld;
|
import static google.registry.flows.domain.DomainFlowUtils.validateNameserversCountForTld;
|
||||||
|
@ -57,7 +57,6 @@ 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.annotations.ReportingSpec;
|
import google.registry.flows.annotations.ReportingSpec;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.FeesRequiredForNonFreeOperationException;
|
|
||||||
import google.registry.model.ImmutableObject;
|
import google.registry.model.ImmutableObject;
|
||||||
import google.registry.model.domain.DomainApplication;
|
import google.registry.model.domain.DomainApplication;
|
||||||
import google.registry.model.domain.DomainCommand.Update;
|
import google.registry.model.domain.DomainCommand.Update;
|
||||||
|
@ -191,15 +190,7 @@ public class DomainApplicationUpdateFlow implements TransactionalFlow {
|
||||||
pricingLogic.getApplicationUpdatePrice(registry, existingApplication, now);
|
pricingLogic.getApplicationUpdatePrice(registry, existingApplication, now);
|
||||||
Optional<FeeUpdateCommandExtension> feeUpdate =
|
Optional<FeeUpdateCommandExtension> feeUpdate =
|
||||||
eppInput.getSingleExtension(FeeUpdateCommandExtension.class);
|
eppInput.getSingleExtension(FeeUpdateCommandExtension.class);
|
||||||
// If the fee extension is present, validate it (even if the cost is zero, to check for price
|
validateFeesAckedIfPresent(feeUpdate, feesAndCredits);
|
||||||
// mismatches). Don't rely on the the validateFeeChallenge check for feeUpdate nullness, because
|
|
||||||
// it throws an error if the name is premium, and we don't want to do that here.
|
|
||||||
if (feeUpdate.isPresent()) {
|
|
||||||
validateFeeChallenge(targetId, tld, now, feeUpdate, feesAndCredits);
|
|
||||||
} else if (!feesAndCredits.getTotalCost().isZero()) {
|
|
||||||
// If it's not present but the cost is not zero, throw an exception.
|
|
||||||
throw new FeesRequiredForNonFreeOperationException(feesAndCredits.getTotalCost());
|
|
||||||
}
|
|
||||||
verifyNotInPendingDelete(
|
verifyNotInPendingDelete(
|
||||||
add.getContacts(),
|
add.getContacts(),
|
||||||
command.getInnerChange().getRegistrant(),
|
command.getInnerChange().getRegistrant(),
|
||||||
|
|
|
@ -271,7 +271,7 @@ public class DomainCreateFlow implements TransactionalFlow {
|
||||||
Optional<FeeCreateCommandExtension> feeCreate =
|
Optional<FeeCreateCommandExtension> feeCreate =
|
||||||
eppInput.getSingleExtension(FeeCreateCommandExtension.class);
|
eppInput.getSingleExtension(FeeCreateCommandExtension.class);
|
||||||
FeesAndCredits feesAndCredits = pricingLogic.getCreatePrice(registry, targetId, now, years);
|
FeesAndCredits feesAndCredits = pricingLogic.getCreatePrice(registry, targetId, now, years);
|
||||||
validateFeeChallenge(targetId, registry.getTldStr(), now, feeCreate, feesAndCredits);
|
validateFeeChallenge(targetId, registry.getTldStr(), clientId, now, feeCreate, feesAndCredits);
|
||||||
Optional<SecDnsCreateExtension> secDnsCreate =
|
Optional<SecDnsCreateExtension> secDnsCreate =
|
||||||
validateSecDnsExtension(eppInput.getSingleExtension(SecDnsCreateExtension.class));
|
validateSecDnsExtension(eppInput.getSingleExtension(SecDnsCreateExtension.class));
|
||||||
String repoId = createDomainRepoId(ObjectifyService.allocateId(), registry.getTldStr());
|
String repoId = createDomainRepoId(ObjectifyService.allocateId(), registry.getTldStr());
|
||||||
|
|
|
@ -613,20 +613,44 @@ public class DomainFlowUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that fees are acked and match if they are required (typically for premium domains).
|
||||||
|
*
|
||||||
|
* <p>This is used by domain operations that have an implicit cost, e.g. domain create or renew
|
||||||
|
* (both of which add one or more years' worth of registration). Depending on registry and/or
|
||||||
|
* registrar settings, explicit price acking using the fee extension may be required for premium
|
||||||
|
* domain names.
|
||||||
|
*/
|
||||||
public static void validateFeeChallenge(
|
public static void validateFeeChallenge(
|
||||||
String domainName,
|
String domainName,
|
||||||
String tld,
|
String tld,
|
||||||
|
String clientId,
|
||||||
DateTime priceTime,
|
DateTime priceTime,
|
||||||
final Optional<? extends FeeTransformCommandExtension> feeCommand,
|
final Optional<? extends FeeTransformCommandExtension> feeCommand,
|
||||||
FeesAndCredits feesAndCredits)
|
FeesAndCredits feesAndCredits)
|
||||||
throws EppException {
|
throws EppException {
|
||||||
|
|
||||||
Registry registry = Registry.get(tld);
|
Registry registry = Registry.get(tld);
|
||||||
if (registry.getPremiumPriceAckRequired()
|
Registrar registrar = Registrar.loadByClientIdCached(clientId).get();
|
||||||
&& isDomainPremium(domainName, priceTime)
|
boolean premiumAckRequired =
|
||||||
&& !feeCommand.isPresent()) {
|
registry.getPremiumPriceAckRequired() || registrar.getPremiumPriceAckRequired();
|
||||||
|
if (premiumAckRequired && isDomainPremium(domainName, priceTime) && !feeCommand.isPresent()) {
|
||||||
throw new FeesRequiredForPremiumNameException();
|
throw new FeesRequiredForPremiumNameException();
|
||||||
}
|
}
|
||||||
|
validateFeesAckedIfPresent(feeCommand, feesAndCredits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that non-zero fees are acked (i.e. they are specified and the amount matches).
|
||||||
|
*
|
||||||
|
* <p>This is used directly by update operations, i.e. those that otherwise don't have implicit
|
||||||
|
* costs, and is also used as a helper method to validate if fees are required for operations that
|
||||||
|
* do have implicit costs, e.g. creates and renews.
|
||||||
|
*/
|
||||||
|
public static void validateFeesAckedIfPresent(
|
||||||
|
final Optional<? extends FeeTransformCommandExtension> feeCommand,
|
||||||
|
FeesAndCredits feesAndCredits)
|
||||||
|
throws EppException {
|
||||||
// Check for the case where a fee command extension was required but not provided.
|
// Check for the case where a fee command extension was required but not provided.
|
||||||
// This only happens when the total fees are non-zero and include custom fees requiring the
|
// This only happens when the total fees are non-zero and include custom fees requiring the
|
||||||
// extension.
|
// extension.
|
||||||
|
@ -657,7 +681,7 @@ public class DomainFlowUtils {
|
||||||
total = total.add(credit.getCost());
|
total = total.add(credit.getCost());
|
||||||
}
|
}
|
||||||
|
|
||||||
Money feeTotal = null;
|
Money feeTotal;
|
||||||
try {
|
try {
|
||||||
feeTotal = Money.of(feeCommand.get().getCurrency(), total);
|
feeTotal = Money.of(feeCommand.get().getCurrency(), total);
|
||||||
} catch (ArithmeticException e) {
|
} catch (ArithmeticException e) {
|
||||||
|
|
|
@ -146,7 +146,8 @@ public final class DomainRenewFlow implements TransactionalFlow {
|
||||||
eppInput.getSingleExtension(FeeRenewCommandExtension.class);
|
eppInput.getSingleExtension(FeeRenewCommandExtension.class);
|
||||||
FeesAndCredits feesAndCredits =
|
FeesAndCredits feesAndCredits =
|
||||||
pricingLogic.getRenewPrice(Registry.get(existingDomain.getTld()), targetId, now, years);
|
pricingLogic.getRenewPrice(Registry.get(existingDomain.getTld()), targetId, now, years);
|
||||||
validateFeeChallenge(targetId, existingDomain.getTld(), now, feeRenew, feesAndCredits);
|
validateFeeChallenge(
|
||||||
|
targetId, existingDomain.getTld(), clientId, now, feeRenew, feesAndCredits);
|
||||||
flowCustomLogic.afterValidation(
|
flowCustomLogic.afterValidation(
|
||||||
AfterValidationParameters.newBuilder()
|
AfterValidationParameters.newBuilder()
|
||||||
.setExistingDomain(existingDomain)
|
.setExistingDomain(existingDomain)
|
||||||
|
|
|
@ -204,7 +204,8 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
|
||||||
if (!existingDomain.getGracePeriodStatuses().contains(GracePeriodStatus.REDEMPTION)) {
|
if (!existingDomain.getGracePeriodStatuses().contains(GracePeriodStatus.REDEMPTION)) {
|
||||||
throw new DomainNotEligibleForRestoreException();
|
throw new DomainNotEligibleForRestoreException();
|
||||||
}
|
}
|
||||||
validateFeeChallenge(targetId, existingDomain.getTld(), now, feeUpdate, feesAndCredits);
|
validateFeeChallenge(
|
||||||
|
targetId, existingDomain.getTld(), clientId, now, feeUpdate, feesAndCredits);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImmutableSet<BillingEvent.OneTime> createRestoreAndRenewBillingEvents(
|
private ImmutableSet<BillingEvent.OneTime> createRestoreAndRenewBillingEvents(
|
||||||
|
|
|
@ -162,7 +162,7 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
|
||||||
? Optional.empty()
|
? Optional.empty()
|
||||||
: Optional.of(pricingLogic.getTransferPrice(registry, targetId, now));
|
: Optional.of(pricingLogic.getTransferPrice(registry, targetId, now));
|
||||||
if (feesAndCredits.isPresent()) {
|
if (feesAndCredits.isPresent()) {
|
||||||
validateFeeChallenge(targetId, tld, now, feeTransfer, feesAndCredits.get());
|
validateFeeChallenge(targetId, tld, gainingClientId, now, feeTransfer, feesAndCredits.get());
|
||||||
}
|
}
|
||||||
HistoryEntry historyEntry = buildHistoryEntry(existingDomain, registry, now, period);
|
HistoryEntry historyEntry = buildHistoryEntry(existingDomain, registry, now, period);
|
||||||
DateTime automaticTransferTime =
|
DateTime automaticTransferTime =
|
||||||
|
|
|
@ -31,7 +31,7 @@ import static google.registry.flows.domain.DomainFlowUtils.updateDsData;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateContactsHaveTypes;
|
import static google.registry.flows.domain.DomainFlowUtils.validateContactsHaveTypes;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateDomainAllowedOnCreateRestrictedTld;
|
import static google.registry.flows.domain.DomainFlowUtils.validateDomainAllowedOnCreateRestrictedTld;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateDsData;
|
import static google.registry.flows.domain.DomainFlowUtils.validateDsData;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
|
import static google.registry.flows.domain.DomainFlowUtils.validateFeesAckedIfPresent;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateNameserversAllowedOnDomain;
|
import static google.registry.flows.domain.DomainFlowUtils.validateNameserversAllowedOnDomain;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateNameserversAllowedOnTld;
|
import static google.registry.flows.domain.DomainFlowUtils.validateNameserversAllowedOnTld;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateNameserversCountForTld;
|
import static google.registry.flows.domain.DomainFlowUtils.validateNameserversCountForTld;
|
||||||
|
@ -59,7 +59,6 @@ import google.registry.flows.custom.DomainUpdateFlowCustomLogic;
|
||||||
import google.registry.flows.custom.DomainUpdateFlowCustomLogic.AfterValidationParameters;
|
import google.registry.flows.custom.DomainUpdateFlowCustomLogic.AfterValidationParameters;
|
||||||
import google.registry.flows.custom.DomainUpdateFlowCustomLogic.BeforeSaveParameters;
|
import google.registry.flows.custom.DomainUpdateFlowCustomLogic.BeforeSaveParameters;
|
||||||
import google.registry.flows.custom.EntityChanges;
|
import google.registry.flows.custom.EntityChanges;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.FeesRequiredForNonFreeOperationException;
|
|
||||||
import google.registry.model.ImmutableObject;
|
import google.registry.model.ImmutableObject;
|
||||||
import google.registry.model.billing.BillingEvent;
|
import google.registry.model.billing.BillingEvent;
|
||||||
import google.registry.model.billing.BillingEvent.Reason;
|
import google.registry.model.billing.BillingEvent.Reason;
|
||||||
|
@ -223,16 +222,8 @@ public final class DomainUpdateFlow implements TransactionalFlow {
|
||||||
Registry registry = Registry.get(tld);
|
Registry registry = Registry.get(tld);
|
||||||
Optional<FeeUpdateCommandExtension> feeUpdate =
|
Optional<FeeUpdateCommandExtension> feeUpdate =
|
||||||
eppInput.getSingleExtension(FeeUpdateCommandExtension.class);
|
eppInput.getSingleExtension(FeeUpdateCommandExtension.class);
|
||||||
// If the fee extension is present, validate it (even if the cost is zero, to check for price
|
|
||||||
// mismatches). Don't rely on the the validateFeeChallenge check for feeUpdate nullness, because
|
|
||||||
// it throws an error if the name is premium, and we don't want to do that here.
|
|
||||||
FeesAndCredits feesAndCredits = pricingLogic.getUpdatePrice(registry, targetId, now);
|
FeesAndCredits feesAndCredits = pricingLogic.getUpdatePrice(registry, targetId, now);
|
||||||
if (feeUpdate.isPresent()) {
|
validateFeesAckedIfPresent(feeUpdate, feesAndCredits);
|
||||||
validateFeeChallenge(targetId, existingDomain.getTld(), now, feeUpdate, feesAndCredits);
|
|
||||||
} else if (!feesAndCredits.getTotalCost().isZero()) {
|
|
||||||
// If it's not present but the cost is not zero, throw an exception.
|
|
||||||
throw new FeesRequiredForNonFreeOperationException(feesAndCredits.getTotalCost());
|
|
||||||
}
|
|
||||||
verifyNotInPendingDelete(
|
verifyNotInPendingDelete(
|
||||||
add.getContacts(),
|
add.getContacts(),
|
||||||
command.getInnerChange().getRegistrant(),
|
command.getInnerChange().getRegistrant(),
|
||||||
|
|
|
@ -412,6 +412,13 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
|
||||||
*/
|
*/
|
||||||
BillingMethod billingMethod;
|
BillingMethod billingMethod;
|
||||||
|
|
||||||
|
/** Whether the registrar must acknowledge the price to register non-standard-priced domains. */
|
||||||
|
boolean premiumPriceAckRequired;
|
||||||
|
|
||||||
|
public boolean getPremiumPriceAckRequired() {
|
||||||
|
return premiumPriceAckRequired;
|
||||||
|
}
|
||||||
|
|
||||||
@NonFinalForTesting
|
@NonFinalForTesting
|
||||||
private static Supplier<byte[]> saltSupplier =
|
private static Supplier<byte[]> saltSupplier =
|
||||||
() -> {
|
() -> {
|
||||||
|
@ -864,6 +871,11 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder setPremiumPriceAckRequired(boolean premiumPriceAckRequired) {
|
||||||
|
getInstance().premiumPriceAckRequired = premiumPriceAckRequired;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/** Build the registrar, nullifying empty fields. */
|
/** Build the registrar, nullifying empty fields. */
|
||||||
@Override
|
@Override
|
||||||
public Registrar build() {
|
public Registrar build() {
|
||||||
|
|
|
@ -318,7 +318,7 @@ public class Registry extends ImmutableObject implements Buildable {
|
||||||
/** Whether the pull queue that writes to authoritative DNS is paused for this TLD. */
|
/** Whether the pull queue that writes to authoritative DNS is paused for this TLD. */
|
||||||
boolean dnsPaused = DEFAULT_DNS_PAUSED;
|
boolean dnsPaused = DEFAULT_DNS_PAUSED;
|
||||||
|
|
||||||
/** Whether the price must be acknowledged to register premiun names on this TLD. */
|
/** Whether the price must be acknowledged to register premium names on this TLD. */
|
||||||
boolean premiumPriceAckRequired = true;
|
boolean premiumPriceAckRequired = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -259,6 +259,13 @@ abstract class CreateOrUpdateRegistrarCommand extends MutatingCommand {
|
||||||
description = "Hostname of registrar WHOIS server. (Default: whois.nic.google)")
|
description = "Hostname of registrar WHOIS server. (Default: whois.nic.google)")
|
||||||
String whoisServer;
|
String whoisServer;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Parameter(
|
||||||
|
names = "--premium_price_ack_required",
|
||||||
|
description = "Whether operations on premium domains require explicit ack of prices",
|
||||||
|
arity = 1)
|
||||||
|
private Boolean premiumPriceAckRequired;
|
||||||
|
|
||||||
/** Returns the existing registrar (for update) or null (for creates). */
|
/** Returns the existing registrar (for update) or null (for creates). */
|
||||||
@Nullable
|
@Nullable
|
||||||
abstract Registrar getOldRegistrar(String clientId);
|
abstract Registrar getOldRegistrar(String clientId);
|
||||||
|
@ -389,21 +396,12 @@ abstract class CreateOrUpdateRegistrarCommand extends MutatingCommand {
|
||||||
.setCountryCode(countryCode)
|
.setCountryCode(countryCode)
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
if (blockPremiumNames != null) {
|
Optional.ofNullable(blockPremiumNames).ifPresent(builder::setBlockPremiumNames);
|
||||||
builder.setBlockPremiumNames(blockPremiumNames);
|
Optional.ofNullable(contactsRequireSyncing).ifPresent(builder::setContactsRequireSyncing);
|
||||||
}
|
Optional.ofNullable(phonePasscode).ifPresent(builder::setPhonePasscode);
|
||||||
if (contactsRequireSyncing != null) {
|
Optional.ofNullable(icannReferralEmail).ifPresent(builder::setIcannReferralEmail);
|
||||||
builder.setContactsRequireSyncing(contactsRequireSyncing);
|
Optional.ofNullable(whoisServer).ifPresent(builder::setWhoisServer);
|
||||||
}
|
Optional.ofNullable(premiumPriceAckRequired).ifPresent(builder::setPremiumPriceAckRequired);
|
||||||
if (phonePasscode != null) {
|
|
||||||
builder.setPhonePasscode(phonePasscode);
|
|
||||||
}
|
|
||||||
if (icannReferralEmail != null) {
|
|
||||||
builder.setIcannReferralEmail(icannReferralEmail);
|
|
||||||
}
|
|
||||||
if (whoisServer != null) {
|
|
||||||
builder.setWhoisServer(whoisServer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the registrarName is being set, verify that it is either null or it normalizes uniquely.
|
// If the registrarName is being set, verify that it is either null or it normalizes uniquely.
|
||||||
String oldRegistrarName = (oldRegistrar == null) ? null : oldRegistrar.getRegistrarName();
|
String oldRegistrarName = (oldRegistrar == null) ? null : oldRegistrar.getRegistrarName();
|
||||||
|
|
|
@ -433,7 +433,8 @@ public class DomainApplicationCreateFlowTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFailure_landrushFeeNotProvidedOnPremiumName() throws Exception {
|
public void testFailure_landrushFeeNotProvidedOnPremiumName_whenRegistryRequiresFeeAcking()
|
||||||
|
throws Exception {
|
||||||
createTld("example", TldState.SUNRUSH);
|
createTld("example", TldState.SUNRUSH);
|
||||||
setEppInput("domain_create_landrush_premium.xml");
|
setEppInput("domain_create_landrush_premium.xml");
|
||||||
persistContactsAndHosts();
|
persistContactsAndHosts();
|
||||||
|
@ -442,6 +443,20 @@ public class DomainApplicationCreateFlowTest
|
||||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFailure_landrushFeeNotProvidedOnPremiumName_whenRegistrarRequiresFeeAcking()
|
||||||
|
throws Exception {
|
||||||
|
createTld("example", TldState.SUNRUSH);
|
||||||
|
persistResource(Registry.get("example").asBuilder().setPremiumPriceAckRequired(false).build());
|
||||||
|
persistResource(
|
||||||
|
loadRegistrar("TheRegistrar").asBuilder().setPremiumPriceAckRequired(true).build());
|
||||||
|
setEppInput("domain_create_landrush_premium.xml");
|
||||||
|
persistContactsAndHosts();
|
||||||
|
clock.advanceOneMilli();
|
||||||
|
EppException thrown = expectThrows(FeesRequiredForPremiumNameException.class, this::runFlow);
|
||||||
|
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_landrushWithClaimsInSunrush() throws Exception {
|
public void testSuccess_landrushWithClaimsInSunrush() throws Exception {
|
||||||
createTld("tld", TldState.SUNRUSH);
|
createTld("tld", TldState.SUNRUSH);
|
||||||
|
|
|
@ -1453,8 +1453,33 @@ public class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFailure_feeNotProvidedOnPremiumName() throws Exception {
|
public void testFailure_premiumNotAcked_byRegistryRequiringAcking() throws Exception {
|
||||||
createTld("example");
|
createTld("example");
|
||||||
|
assertThat(Registry.get("example").getPremiumPriceAckRequired()).isTrue();
|
||||||
|
setEppInput("domain_create_premium.xml");
|
||||||
|
persistContactsAndHosts("net");
|
||||||
|
EppException thrown = expectThrows(FeesRequiredForPremiumNameException.class, this::runFlow);
|
||||||
|
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFailure_premiumNotAcked_byRegistrarRequiringAcking() throws Exception {
|
||||||
|
createTld("example");
|
||||||
|
persistResource(Registry.get("example").asBuilder().setPremiumPriceAckRequired(false).build());
|
||||||
|
persistResource(
|
||||||
|
loadRegistrar("TheRegistrar").asBuilder().setPremiumPriceAckRequired(true).build());
|
||||||
|
setEppInput("domain_create_premium.xml");
|
||||||
|
persistContactsAndHosts("net");
|
||||||
|
EppException thrown = expectThrows(FeesRequiredForPremiumNameException.class, this::runFlow);
|
||||||
|
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFailure_premiumNotAcked_whenRegistrarAndRegistryRequireAcking() throws Exception {
|
||||||
|
createTld("example");
|
||||||
|
persistResource(Registry.get("example").asBuilder().setPremiumPriceAckRequired(true).build());
|
||||||
|
persistResource(
|
||||||
|
loadRegistrar("TheRegistrar").asBuilder().setPremiumPriceAckRequired(true).build());
|
||||||
setEppInput("domain_create_premium.xml");
|
setEppInput("domain_create_premium.xml");
|
||||||
persistContactsAndHosts("net");
|
persistContactsAndHosts("net");
|
||||||
EppException thrown = expectThrows(FeesRequiredForPremiumNameException.class, this::runFlow);
|
EppException thrown = expectThrows(FeesRequiredForPremiumNameException.class, this::runFlow);
|
||||||
|
|
|
@ -666,7 +666,7 @@ public class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, D
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFailure_feeNotProvidedOnPremiumName() throws Exception {
|
public void testFailure_registryRequiresAcking_feeNotProvidedOnPremiumName() throws Exception {
|
||||||
createTld("example");
|
createTld("example");
|
||||||
persistResource(Registry.get("example").asBuilder().setPremiumPriceAckRequired(true).build());
|
persistResource(Registry.get("example").asBuilder().setPremiumPriceAckRequired(true).build());
|
||||||
setEppInput("domain_renew_premium.xml");
|
setEppInput("domain_renew_premium.xml");
|
||||||
|
@ -675,6 +675,18 @@ public class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, D
|
||||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFailure_registrarRequiresAcking_feeNotProvidedOnPremiumName() throws Exception {
|
||||||
|
createTld("example");
|
||||||
|
persistResource(Registry.get("example").asBuilder().setPremiumPriceAckRequired(false).build());
|
||||||
|
persistResource(
|
||||||
|
loadRegistrar("TheRegistrar").asBuilder().setPremiumPriceAckRequired(true).build());
|
||||||
|
setEppInput("domain_renew_premium.xml");
|
||||||
|
persistDomain();
|
||||||
|
EppException thrown = expectThrows(FeesRequiredForPremiumNameException.class, this::runFlow);
|
||||||
|
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIcannActivityReportField_getsLogged() throws Exception {
|
public void testIcannActivityReportField_getsLogged() throws Exception {
|
||||||
persistDomain();
|
persistDomain();
|
||||||
|
|
|
@ -559,7 +559,7 @@ public class DomainRestoreRequestFlowTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFailure_feeNotProvidedOnPremiumName() throws Exception {
|
public void testFailure_premiumNotAcked_whenRegistryRequiresFeeAcking() throws Exception {
|
||||||
createTld("example");
|
createTld("example");
|
||||||
setEppInput("domain_update_restore_request_premium.xml");
|
setEppInput("domain_update_restore_request_premium.xml");
|
||||||
persistPendingDeleteDomain();
|
persistPendingDeleteDomain();
|
||||||
|
@ -567,6 +567,18 @@ public class DomainRestoreRequestFlowTest
|
||||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFailure_premiumNotAcked_whenRegistrarRequiresFeeAcking() throws Exception {
|
||||||
|
createTld("example");
|
||||||
|
persistResource(Registry.get("example").asBuilder().setPremiumPriceAckRequired(false).build());
|
||||||
|
persistResource(
|
||||||
|
loadRegistrar("TheRegistrar").asBuilder().setPremiumPriceAckRequired(true).build());
|
||||||
|
setEppInput("domain_update_restore_request_premium.xml");
|
||||||
|
persistPendingDeleteDomain();
|
||||||
|
EppException thrown = expectThrows(FeesRequiredForPremiumNameException.class, this::runFlow);
|
||||||
|
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIcannActivityReportField_getsLogged() throws Exception {
|
public void testIcannActivityReportField_getsLogged() throws Exception {
|
||||||
persistPendingDeleteDomain();
|
persistPendingDeleteDomain();
|
||||||
|
|
|
@ -198,64 +198,6 @@ public class DomainTransferRequestFlowTest
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs a successful test. The extraExpectedBillingEvents parameter consists of cancellation
|
|
||||||
* billing event builders that have had all of their attributes set except for the parent history
|
|
||||||
* entry, which is filled in during the execution of this method.
|
|
||||||
*/
|
|
||||||
private void doSuccessfulTest(
|
|
||||||
String commandFilename,
|
|
||||||
String expectedXmlFilename,
|
|
||||||
DateTime expectedExpirationTime,
|
|
||||||
Map<String, String> substitutions,
|
|
||||||
Optional<Money> transferCost,
|
|
||||||
BillingEvent.Cancellation.Builder... extraExpectedBillingEvents)
|
|
||||||
throws Exception {
|
|
||||||
setEppInput(commandFilename, substitutions);
|
|
||||||
ImmutableSet<GracePeriod> originalGracePeriods = domain.getGracePeriods();
|
|
||||||
// Replace the ROID in the xml file with the one generated in our test.
|
|
||||||
eppLoader.replaceAll("JD1234-REP", contact.getRepoId());
|
|
||||||
// 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
|
|
||||||
// the transfer timeline 3 days later by adjusting the implicit transfer time here.
|
|
||||||
Registry registry = Registry.get(domain.getTld());
|
|
||||||
DateTime implicitTransferTime = clock.nowUtc().plus(registry.getAutomaticTransferLength());
|
|
||||||
// Setup done; run the test.
|
|
||||||
assertTransactionalFlow(true);
|
|
||||||
runFlowAssertResponse(loadFile(expectedXmlFilename, substitutions));
|
|
||||||
// Transfer should have been requested.
|
|
||||||
domain = reloadResourceByForeignKey();
|
|
||||||
// Verify that HistoryEntry was created.
|
|
||||||
assertAboutDomains()
|
|
||||||
.that(domain)
|
|
||||||
.hasOneHistoryEntryEachOfTypes(DOMAIN_CREATE, DOMAIN_TRANSFER_REQUEST);
|
|
||||||
final HistoryEntry historyEntryTransferRequest =
|
|
||||||
getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_REQUEST);
|
|
||||||
assertAboutHistoryEntries()
|
|
||||||
.that(historyEntryTransferRequest)
|
|
||||||
.hasPeriodYears(1)
|
|
||||||
.and()
|
|
||||||
.hasOtherClientId("TheRegistrar");
|
|
||||||
// Verify correct fields were set.
|
|
||||||
assertTransferRequested(
|
|
||||||
domain, implicitTransferTime, Period.create(1, Unit.YEARS), expectedExpirationTime);
|
|
||||||
|
|
||||||
subordinateHost = reloadResourceAndCloneAtTime(subordinateHost, clock.nowUtc());
|
|
||||||
assertAboutHosts().that(subordinateHost).hasNoHistoryEntries();
|
|
||||||
|
|
||||||
assertHistoryEntriesContainBillingEventsAndGracePeriods(
|
|
||||||
expectedExpirationTime,
|
|
||||||
implicitTransferTime,
|
|
||||||
transferCost,
|
|
||||||
originalGracePeriods,
|
|
||||||
/* expectTransferBillingEvent = */ true,
|
|
||||||
extraExpectedBillingEvents);
|
|
||||||
|
|
||||||
assertPollMessagesEmitted(expectedExpirationTime, implicitTransferTime);
|
|
||||||
assertAboutDomainAfterAutomaticTransfer(
|
|
||||||
expectedExpirationTime, implicitTransferTime, Period.create(1, Unit.YEARS));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Implements the missing Optional.stream function that is added in Java 9. */
|
/** Implements the missing Optional.stream function that is added in Java 9. */
|
||||||
private static <T> Stream<T> optionalToStream(Optional<T> optional) {
|
private static <T> Stream<T> optionalToStream(Optional<T> optional) {
|
||||||
return optional.map(Stream::of).orElseGet(Stream::empty);
|
return optional.map(Stream::of).orElseGet(Stream::empty);
|
||||||
|
@ -484,6 +426,64 @@ public class DomainTransferRequestFlowTest
|
||||||
assertThat(afterGracePeriod.getGracePeriods()).isEmpty();
|
assertThat(afterGracePeriod.getGracePeriods()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs a successful test. The extraExpectedBillingEvents parameter consists of cancellation
|
||||||
|
* billing event builders that have had all of their attributes set except for the parent history
|
||||||
|
* entry, which is filled in during the execution of this method.
|
||||||
|
*/
|
||||||
|
private void doSuccessfulTest(
|
||||||
|
String commandFilename,
|
||||||
|
String expectedXmlFilename,
|
||||||
|
DateTime expectedExpirationTime,
|
||||||
|
Map<String, String> substitutions,
|
||||||
|
Optional<Money> transferCost,
|
||||||
|
BillingEvent.Cancellation.Builder... extraExpectedBillingEvents)
|
||||||
|
throws Exception {
|
||||||
|
setEppInput(commandFilename, substitutions);
|
||||||
|
ImmutableSet<GracePeriod> originalGracePeriods = domain.getGracePeriods();
|
||||||
|
// Replace the ROID in the xml file with the one generated in our test.
|
||||||
|
eppLoader.replaceAll("JD1234-REP", contact.getRepoId());
|
||||||
|
// 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
|
||||||
|
// the transfer timeline 3 days later by adjusting the implicit transfer time here.
|
||||||
|
Registry registry = Registry.get(domain.getTld());
|
||||||
|
DateTime implicitTransferTime = clock.nowUtc().plus(registry.getAutomaticTransferLength());
|
||||||
|
// Setup done; run the test.
|
||||||
|
assertTransactionalFlow(true);
|
||||||
|
runFlowAssertResponse(loadFile(expectedXmlFilename, substitutions));
|
||||||
|
// Transfer should have been requested.
|
||||||
|
domain = reloadResourceByForeignKey();
|
||||||
|
// Verify that HistoryEntry was created.
|
||||||
|
assertAboutDomains()
|
||||||
|
.that(domain)
|
||||||
|
.hasOneHistoryEntryEachOfTypes(DOMAIN_CREATE, DOMAIN_TRANSFER_REQUEST);
|
||||||
|
final HistoryEntry historyEntryTransferRequest =
|
||||||
|
getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_REQUEST);
|
||||||
|
assertAboutHistoryEntries()
|
||||||
|
.that(historyEntryTransferRequest)
|
||||||
|
.hasPeriodYears(1)
|
||||||
|
.and()
|
||||||
|
.hasOtherClientId("TheRegistrar");
|
||||||
|
// Verify correct fields were set.
|
||||||
|
assertTransferRequested(
|
||||||
|
domain, implicitTransferTime, Period.create(1, Unit.YEARS), expectedExpirationTime);
|
||||||
|
|
||||||
|
subordinateHost = reloadResourceAndCloneAtTime(subordinateHost, clock.nowUtc());
|
||||||
|
assertAboutHosts().that(subordinateHost).hasNoHistoryEntries();
|
||||||
|
|
||||||
|
assertHistoryEntriesContainBillingEventsAndGracePeriods(
|
||||||
|
expectedExpirationTime,
|
||||||
|
implicitTransferTime,
|
||||||
|
transferCost,
|
||||||
|
originalGracePeriods,
|
||||||
|
/* expectTransferBillingEvent = */ true,
|
||||||
|
extraExpectedBillingEvents);
|
||||||
|
|
||||||
|
assertPollMessagesEmitted(expectedExpirationTime, implicitTransferTime);
|
||||||
|
assertAboutDomainAfterAutomaticTransfer(
|
||||||
|
expectedExpirationTime, implicitTransferTime, Period.create(1, Unit.YEARS));
|
||||||
|
}
|
||||||
|
|
||||||
private void doSuccessfulTest(
|
private void doSuccessfulTest(
|
||||||
String commandFilename,
|
String commandFilename,
|
||||||
String expectedXmlFilename,
|
String expectedXmlFilename,
|
||||||
|
@ -1202,7 +1202,7 @@ public class DomainTransferRequestFlowTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFailure_feeNotProvidedOnPremiumName() throws Exception {
|
public void testFailure_registryRequiresAcking_feeNotProvidedOnPremiumName() throws Exception {
|
||||||
setupDomain("rich", "example");
|
setupDomain("rich", "example");
|
||||||
EppException thrown =
|
EppException thrown =
|
||||||
expectThrows(
|
expectThrows(
|
||||||
|
@ -1211,6 +1211,20 @@ public class DomainTransferRequestFlowTest
|
||||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFailure_registrarRequiresAcking_feeNotProvidedOnPremiumName() throws Exception {
|
||||||
|
setupDomain("rich", "example");
|
||||||
|
persistResource(Registry.get("example").asBuilder().setPremiumPriceAckRequired(false).build());
|
||||||
|
persistResource(
|
||||||
|
loadRegistrar("NewRegistrar").asBuilder().setPremiumPriceAckRequired(true).build());
|
||||||
|
clock.advanceOneMilli();
|
||||||
|
EppException thrown =
|
||||||
|
expectThrows(
|
||||||
|
FeesRequiredForPremiumNameException.class,
|
||||||
|
() -> doFailingTest("domain_transfer_request_premium.xml"));
|
||||||
|
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFailure_noAuthInfo() throws Exception {
|
public void testFailure_noAuthInfo() throws Exception {
|
||||||
setupDomain("example", "tld");
|
setupDomain("example", "tld");
|
||||||
|
|
|
@ -97,6 +97,7 @@ public class RegistrarTest extends EntityTestCase {
|
||||||
.setBillingAccountMap(
|
.setBillingAccountMap(
|
||||||
ImmutableMap.of(CurrencyUnit.USD, "abc123", CurrencyUnit.JPY, "789xyz"))
|
ImmutableMap.of(CurrencyUnit.USD, "abc123", CurrencyUnit.JPY, "789xyz"))
|
||||||
.setPhonePasscode("01234")
|
.setPhonePasscode("01234")
|
||||||
|
.setPremiumPriceAckRequired(true)
|
||||||
.build());
|
.build());
|
||||||
persistResource(registrar);
|
persistResource(registrar);
|
||||||
abuseAdminContact =
|
abuseAdminContact =
|
||||||
|
|
|
@ -587,6 +587,7 @@ class google.registry.model.registrar.Registrar {
|
||||||
@Parent com.googlecode.objectify.Key<google.registry.model.common.EntityGroupRoot> parent;
|
@Parent com.googlecode.objectify.Key<google.registry.model.common.EntityGroupRoot> parent;
|
||||||
boolean blockPremiumNames;
|
boolean blockPremiumNames;
|
||||||
boolean contactsRequireSyncing;
|
boolean contactsRequireSyncing;
|
||||||
|
boolean premiumPriceAckRequired;
|
||||||
google.registry.model.CreateAutoTimestamp creationTime;
|
google.registry.model.CreateAutoTimestamp creationTime;
|
||||||
google.registry.model.UpdateAutoTimestamp lastUpdateTime;
|
google.registry.model.UpdateAutoTimestamp lastUpdateTime;
|
||||||
google.registry.model.registrar.Registrar$BillingMethod billingMethod;
|
google.registry.model.registrar.Registrar$BillingMethod billingMethod;
|
||||||
|
|
|
@ -91,6 +91,7 @@ public class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarC
|
||||||
assertThat(registrar.getCreationTime()).isIn(Range.closed(before, after));
|
assertThat(registrar.getCreationTime()).isIn(Range.closed(before, after));
|
||||||
assertThat(registrar.getLastUpdateTime()).isEqualTo(registrar.getCreationTime());
|
assertThat(registrar.getLastUpdateTime()).isEqualTo(registrar.getCreationTime());
|
||||||
assertThat(registrar.getBlockPremiumNames()).isFalse();
|
assertThat(registrar.getBlockPremiumNames()).isFalse();
|
||||||
|
assertThat(registrar.getPremiumPriceAckRequired()).isFalse();
|
||||||
|
|
||||||
verify(connection).send(
|
verify(connection).send(
|
||||||
eq("/_dr/admin/createGroups"),
|
eq("/_dr/admin/createGroups"),
|
||||||
|
@ -766,6 +767,28 @@ public class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarC
|
||||||
assertThat(registrar.get().getFaxNumber()).isEqualTo("+1.2125556342");
|
assertThat(registrar.get().getFaxNumber()).isEqualTo("+1.2125556342");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSuccess_premiumPriceAckRequired() throws Exception {
|
||||||
|
runCommandForced(
|
||||||
|
"--name=blobio",
|
||||||
|
"--password=some_password",
|
||||||
|
"--registrar_type=REAL",
|
||||||
|
"--iana_id=8",
|
||||||
|
"--passcode=01234",
|
||||||
|
"--icann_referral_email=foo@bar.test",
|
||||||
|
"--street=\"123 Fake St\"",
|
||||||
|
"--city Fakington",
|
||||||
|
"--state MA",
|
||||||
|
"--zip 00351",
|
||||||
|
"--cc US",
|
||||||
|
"--premium_price_ack_required=true",
|
||||||
|
"clientz");
|
||||||
|
|
||||||
|
Optional<Registrar> registrar = Registrar.loadByClientId("clientz");
|
||||||
|
assertThat(registrar).isPresent();
|
||||||
|
assertThat(registrar.get().getPremiumPriceAckRequired()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFailure_missingRegistrarType() throws Exception {
|
public void testFailure_missingRegistrarType() throws Exception {
|
||||||
IllegalArgumentException thrown =
|
IllegalArgumentException thrown =
|
||||||
|
|
|
@ -314,31 +314,55 @@ public class UpdateRegistrarCommandTest extends CommandTestCase<UpdateRegistrarC
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_blockPremiumNames() throws Exception {
|
public void testSuccess_blockPremiumNames() throws Exception {
|
||||||
assertThat(loadRegistrar("NewRegistrar").getBlockPremiumNames()).isFalse();
|
assertThat(loadRegistrar("NewRegistrar").getBlockPremiumNames()).isFalse();
|
||||||
runCommand("--block_premium=true", "--force", "NewRegistrar");
|
runCommandForced("--block_premium=true", "NewRegistrar");
|
||||||
assertThat(loadRegistrar("NewRegistrar").getBlockPremiumNames()).isTrue();
|
assertThat(loadRegistrar("NewRegistrar").getBlockPremiumNames()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_resetBlockPremiumNames() throws Exception {
|
public void testSuccess_resetBlockPremiumNames() throws Exception {
|
||||||
persistResource(loadRegistrar("NewRegistrar").asBuilder().setBlockPremiumNames(true).build());
|
persistResource(loadRegistrar("NewRegistrar").asBuilder().setBlockPremiumNames(true).build());
|
||||||
runCommand("--block_premium=false", "--force", "NewRegistrar");
|
runCommandForced("--block_premium=false", "NewRegistrar");
|
||||||
assertThat(loadRegistrar("NewRegistrar").getBlockPremiumNames()).isFalse();
|
assertThat(loadRegistrar("NewRegistrar").getBlockPremiumNames()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_blockPremiumNamesUnspecified() throws Exception {
|
public void testSuccess_premiumPriceAckRequired() throws Exception {
|
||||||
persistResource(loadRegistrar("NewRegistrar").asBuilder().setBlockPremiumNames(true).build());
|
assertThat(loadRegistrar("NewRegistrar").getPremiumPriceAckRequired()).isFalse();
|
||||||
// Make some unrelated change where we don't specify "--block_premium".
|
runCommandForced("--premium_price_ack_required=true", "NewRegistrar");
|
||||||
runCommand("--billing_id=12345", "--force", "NewRegistrar");
|
assertThat(loadRegistrar("NewRegistrar").getPremiumPriceAckRequired()).isTrue();
|
||||||
// Make sure the field didn't get reset back to false.
|
}
|
||||||
assertThat(loadRegistrar("NewRegistrar").getBlockPremiumNames()).isTrue();
|
|
||||||
|
@Test
|
||||||
|
public void testSuccess_resetPremiumPriceAckRequired() throws Exception {
|
||||||
|
persistResource(
|
||||||
|
loadRegistrar("NewRegistrar").asBuilder().setPremiumPriceAckRequired(true).build());
|
||||||
|
runCommandForced("--premium_price_ack_required=false", "NewRegistrar");
|
||||||
|
assertThat(loadRegistrar("NewRegistrar").getPremiumPriceAckRequired()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSuccess_unspecifiedBooleansArentChanged() throws Exception {
|
||||||
|
persistResource(
|
||||||
|
loadRegistrar("NewRegistrar")
|
||||||
|
.asBuilder()
|
||||||
|
.setBlockPremiumNames(true)
|
||||||
|
.setPremiumPriceAckRequired(true)
|
||||||
|
.setContactsRequireSyncing(true)
|
||||||
|
.build());
|
||||||
|
// Make some unrelated change where we don't specify the flags for the booleans.
|
||||||
|
runCommandForced("--billing_id=12345", "NewRegistrar");
|
||||||
|
// Make sure that the boolean fields didn't get reset back to false.
|
||||||
|
Registrar reloadedRegistrar = loadRegistrar("NewRegistrar");
|
||||||
|
assertThat(reloadedRegistrar.getBlockPremiumNames()).isTrue();
|
||||||
|
assertThat(reloadedRegistrar.getPremiumPriceAckRequired()).isTrue();
|
||||||
|
assertThat(reloadedRegistrar.getContactsRequireSyncing()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_updateMultiple() throws Exception {
|
public void testSuccess_updateMultiple() throws Exception {
|
||||||
assertThat(loadRegistrar("TheRegistrar").getState()).isEqualTo(State.ACTIVE);
|
assertThat(loadRegistrar("TheRegistrar").getState()).isEqualTo(State.ACTIVE);
|
||||||
assertThat(loadRegistrar("NewRegistrar").getState()).isEqualTo(State.ACTIVE);
|
assertThat(loadRegistrar("NewRegistrar").getState()).isEqualTo(State.ACTIVE);
|
||||||
runCommand("--registrar_state=SUSPENDED", "--force", "TheRegistrar", "NewRegistrar");
|
runCommandForced("--registrar_state=SUSPENDED", "TheRegistrar", "NewRegistrar");
|
||||||
assertThat(loadRegistrar("TheRegistrar").getState()).isEqualTo(State.SUSPENDED);
|
assertThat(loadRegistrar("TheRegistrar").getState()).isEqualTo(State.SUSPENDED);
|
||||||
assertThat(loadRegistrar("NewRegistrar").getState()).isEqualTo(State.SUSPENDED);
|
assertThat(loadRegistrar("NewRegistrar").getState()).isEqualTo(State.SUSPENDED);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue