mirror of
https://github.com/google/nomulus
synced 2026-01-16 02:33:16 +00:00
Compare commits
6 Commits
proxy-2026
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c187c92ae4 | ||
|
|
22ca4e3f2b | ||
|
|
f27136458a | ||
|
|
d8e647316e | ||
|
|
d6e0a7b979 | ||
|
|
5725eb95e0 |
@@ -98,8 +98,8 @@ PRESUBMITS = {
|
||||
"File did not include the license header.",
|
||||
|
||||
# Files must end in a newline
|
||||
PresubmitCheck(r".*\n$", ("java", "js", "soy", "sql", "py", "sh", "gradle", "ts"),
|
||||
{"node_modules/"}, REQUIRED):
|
||||
PresubmitCheck(r".*\n$", ("java", "js", "soy", "sql", "py", "sh", "gradle", "ts", "xml"),
|
||||
{"node_modules/", ".idea"}, REQUIRED):
|
||||
"Source files must end in a newline.",
|
||||
|
||||
# System.(out|err).println should only appear in tools/ or load-testing/
|
||||
|
||||
@@ -322,4 +322,15 @@
|
||||
<service>bsa</service>
|
||||
<schedule>23 8,20 * * *</schedule>
|
||||
</task>
|
||||
|
||||
<task>
|
||||
<url><![CDATA[/_dr/task/triggerMosApiServiceState]]></url>
|
||||
<name>triggerMosApiServiceState</name>
|
||||
<description>
|
||||
Fetches the service state from MosAPI and triggers the metrics status for all TLDs.
|
||||
</description>
|
||||
<!-- Runs every 5 minutes. -->
|
||||
<schedule>*/5 * * * *</schedule>
|
||||
</task>
|
||||
|
||||
</entries>
|
||||
|
||||
@@ -194,27 +194,24 @@ public final class ResourceFlowUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/** Check that the same values aren't being added and removed in an update command. */
|
||||
public static <T> void checkSameValuesNotAddedAndRemoved(
|
||||
ImmutableSet<T> fieldsToAdd, ImmutableSet<T> fieldsToRemove)
|
||||
throws AddRemoveSameValueException {
|
||||
/**
|
||||
* Verifies the adds and removes on a resource.
|
||||
*
|
||||
* <p>This throws an exception in three different situations: if the same value is being both
|
||||
* added and removed, if a value is being added that is already present, or if a value is being
|
||||
* removed that isn't present.
|
||||
*/
|
||||
public static <T> void verifyAddsAndRemoves(
|
||||
ImmutableSet<T> existingFields, ImmutableSet<T> fieldsToAdd, ImmutableSet<T> fieldsToRemove)
|
||||
throws AddRemoveSameValueException,
|
||||
AddExistingValueException,
|
||||
RemoveNonexistentValueException {
|
||||
if (!intersection(fieldsToAdd, fieldsToRemove).isEmpty()) {
|
||||
throw new AddRemoveSameValueException();
|
||||
}
|
||||
}
|
||||
|
||||
/** Check that we aren't adding a value that is already present. */
|
||||
public static <T> void checkExistingValueNotAdded(
|
||||
ImmutableSet<T> fieldsToAdd, ImmutableSet<T> existingFields)
|
||||
throws AddExistingValueException {
|
||||
if (!intersection(fieldsToAdd, existingFields).isEmpty()) {
|
||||
throw new AddExistingValueException();
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> void checkNonexistentValueNotRemoved(
|
||||
ImmutableSet<T> fieldsToRemove, ImmutableSet<T> existingFields)
|
||||
throws RemoveNonexistentValueException {
|
||||
if (intersection(fieldsToRemove, existingFields).size() != fieldsToRemove.size()) {
|
||||
throw new RemoveNonexistentValueException();
|
||||
}
|
||||
|
||||
@@ -976,23 +976,21 @@ public class DomainFlowUtils {
|
||||
throw new UrgentAttributeNotSupportedException();
|
||||
}
|
||||
// There must be at least one of add/rem/chg, and chg isn't actually supported.
|
||||
if (secDnsUpdate.getChange() != null) {
|
||||
if (secDnsUpdate.getChange().isPresent()) {
|
||||
// The only thing you can change is maxSigLife, and we don't support that at all.
|
||||
throw new MaxSigLifeChangeNotSupportedException();
|
||||
}
|
||||
Add add = secDnsUpdate.getAdd();
|
||||
Remove remove = secDnsUpdate.getRemove();
|
||||
if (add == null && remove == null) {
|
||||
Optional<Add> add = secDnsUpdate.getAdd();
|
||||
Optional<Remove> remove = secDnsUpdate.getRemove();
|
||||
if (add.isEmpty() && remove.isEmpty()) {
|
||||
throw new EmptySecDnsUpdateException();
|
||||
}
|
||||
if (remove != null && Boolean.FALSE.equals(remove.getAll())) {
|
||||
if (remove.isPresent() && Boolean.FALSE.equals(remove.get().getAll())) {
|
||||
throw new SecDnsAllUsageException(); // Explicit all=false is meaningless.
|
||||
}
|
||||
Set<DomainDsData> toAdd = (add == null) ? ImmutableSet.of() : add.getDsData();
|
||||
Set<DomainDsData> toAdd = add.map(Add::getDsData).orElse(ImmutableSet.of());
|
||||
Set<DomainDsData> toRemove =
|
||||
(remove == null)
|
||||
? ImmutableSet.of()
|
||||
: (remove.getAll() == null) ? remove.getDsData() : oldDsData;
|
||||
remove.map(r -> (r.getAll() == null) ? r.getDsData() : oldDsData).orElse(ImmutableSet.of());
|
||||
// RFC 5910 specifies that removes are processed before adds.
|
||||
return ImmutableSet.copyOf(union(difference(oldDsData, toRemove), toAdd));
|
||||
}
|
||||
|
||||
@@ -21,10 +21,8 @@ import static com.google.common.collect.Sets.union;
|
||||
import static google.registry.dns.DnsUtils.requestDomainDnsRefresh;
|
||||
import static google.registry.flows.FlowUtils.persistEntityChanges;
|
||||
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
|
||||
import static google.registry.flows.ResourceFlowUtils.checkExistingValueNotAdded;
|
||||
import static google.registry.flows.ResourceFlowUtils.checkNonexistentValueNotRemoved;
|
||||
import static google.registry.flows.ResourceFlowUtils.checkSameValuesNotAddedAndRemoved;
|
||||
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
|
||||
import static google.registry.flows.ResourceFlowUtils.verifyAddsAndRemoves;
|
||||
import static google.registry.flows.ResourceFlowUtils.verifyAllStatusesAreClientSettable;
|
||||
import static google.registry.flows.ResourceFlowUtils.verifyNoDisallowedStatuses;
|
||||
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
|
||||
@@ -77,6 +75,8 @@ import google.registry.model.domain.fee.FeeUpdateCommandExtension;
|
||||
import google.registry.model.domain.metadata.MetadataExtension;
|
||||
import google.registry.model.domain.secdns.DomainDsData;
|
||||
import google.registry.model.domain.secdns.SecDnsUpdateExtension;
|
||||
import google.registry.model.domain.secdns.SecDnsUpdateExtension.Add;
|
||||
import google.registry.model.domain.secdns.SecDnsUpdateExtension.Remove;
|
||||
import google.registry.model.domain.superuser.DomainUpdateSuperuserExtension;
|
||||
import google.registry.model.eppcommon.AuthInfo;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
@@ -247,14 +247,19 @@ public final class DomainUpdateFlow implements MutatingFlow {
|
||||
private Domain performUpdate(Update command, Domain domain, DateTime now) throws EppException {
|
||||
AddRemove add = command.getInnerAdd();
|
||||
AddRemove remove = command.getInnerRemove();
|
||||
checkSameValuesNotAddedAndRemoved(add.getNameservers(), remove.getNameservers());
|
||||
checkSameValuesNotAddedAndRemoved(add.getContacts(), remove.getContacts());
|
||||
checkSameValuesNotAddedAndRemoved(add.getStatusValues(), remove.getStatusValues());
|
||||
checkExistingValueNotAdded(add.getNameservers(), domain.getNameservers());
|
||||
checkNonexistentValueNotRemoved(remove.getNameservers(), domain.getNameservers());
|
||||
Change change = command.getInnerChange();
|
||||
Optional<SecDnsUpdateExtension> secDnsUpdate =
|
||||
eppInput.getSingleExtension(SecDnsUpdateExtension.class);
|
||||
verifyAddsAndRemoves(domain.getNameservers(), add.getNameservers(), remove.getNameservers());
|
||||
verifyAddsAndRemoves(domain.getContacts(), add.getContacts(), remove.getContacts());
|
||||
verifyAddsAndRemoves(domain.getStatusValues(), add.getStatusValues(), remove.getStatusValues());
|
||||
if (secDnsUpdate.isPresent()) {
|
||||
SecDnsUpdateExtension ext = secDnsUpdate.get();
|
||||
verifyAddsAndRemoves(
|
||||
domain.getDsData(),
|
||||
ext.getAdd().map(Add::getDsData).orElse(ImmutableSet.of()),
|
||||
ext.getRemove().map(Remove::getDsData).orElse(ImmutableSet.of()));
|
||||
}
|
||||
Change change = command.getInnerChange();
|
||||
|
||||
// We have to verify no duplicate contacts _before_ constructing the domain because it is
|
||||
// illegal to construct a domain with duplicate contacts.
|
||||
|
||||
@@ -17,6 +17,7 @@ package google.registry.flows.host;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateFirstLabel;
|
||||
import static google.registry.model.EppResourceUtils.isActive;
|
||||
import static google.registry.model.tld.Tlds.findTldForName;
|
||||
import static google.registry.util.DomainNameUtils.canonicalizeHostname;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
@@ -34,7 +35,6 @@ import google.registry.flows.EppException.StatusProhibitsOperationException;
|
||||
import google.registry.model.ForeignKeyUtils;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.util.Idn;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Optional;
|
||||
import org.joda.time.DateTime;
|
||||
@@ -57,7 +57,7 @@ public class HostFlowUtils {
|
||||
throw new HostNameNotLowerCaseException(hostNameLowerCase);
|
||||
}
|
||||
try {
|
||||
String hostNamePunyCoded = Idn.toASCII(name);
|
||||
String hostNamePunyCoded = canonicalizeHostname(name);
|
||||
if (!name.equals(hostNamePunyCoded)) {
|
||||
throw new HostNameNotPunyCodedException(hostNamePunyCoded);
|
||||
}
|
||||
|
||||
@@ -20,10 +20,8 @@ import static google.registry.dns.DnsUtils.requestHostDnsRefresh;
|
||||
import static google.registry.dns.RefreshDnsOnHostRenameAction.PARAM_HOST_KEY;
|
||||
import static google.registry.dns.RefreshDnsOnHostRenameAction.QUEUE_HOST_RENAME;
|
||||
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
|
||||
import static google.registry.flows.ResourceFlowUtils.checkExistingValueNotAdded;
|
||||
import static google.registry.flows.ResourceFlowUtils.checkNonexistentValueNotRemoved;
|
||||
import static google.registry.flows.ResourceFlowUtils.checkSameValuesNotAddedAndRemoved;
|
||||
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
|
||||
import static google.registry.flows.ResourceFlowUtils.verifyAddsAndRemoves;
|
||||
import static google.registry.flows.ResourceFlowUtils.verifyAllStatusesAreClientSettable;
|
||||
import static google.registry.flows.ResourceFlowUtils.verifyNoDisallowedStatuses;
|
||||
import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership;
|
||||
@@ -161,10 +159,10 @@ public final class HostUpdateFlow implements MutatingFlow {
|
||||
}
|
||||
AddRemove add = command.getInnerAdd();
|
||||
AddRemove remove = command.getInnerRemove();
|
||||
checkSameValuesNotAddedAndRemoved(add.getStatusValues(), remove.getStatusValues());
|
||||
checkSameValuesNotAddedAndRemoved(add.getInetAddresses(), remove.getInetAddresses());
|
||||
checkExistingValueNotAdded(add.getInetAddresses(), existingHost.getInetAddresses());
|
||||
checkNonexistentValueNotRemoved(remove.getInetAddresses(), existingHost.getInetAddresses());
|
||||
verifyAddsAndRemoves(
|
||||
existingHost.getStatusValues(), add.getStatusValues(), remove.getStatusValues());
|
||||
verifyAddsAndRemoves(
|
||||
existingHost.getInetAddresses(), add.getInetAddresses(), remove.getInetAddresses());
|
||||
HostFlowUtils.validateInetAddresses(add.getInetAddresses());
|
||||
VKey<Domain> newSuperordinateDomainKey =
|
||||
newSuperordinateDomain.map(Domain::createVKey).orElse(null);
|
||||
|
||||
@@ -31,7 +31,7 @@ import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
@Access(AccessType.FIELD)
|
||||
public abstract class DomainDsDataBase extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
@XmlTransient @Transient String domainRepoId;
|
||||
@XmlTransient @Transient @Insignificant String domainRepoId;
|
||||
|
||||
/** The identifier for this particular key in the domain. */
|
||||
@Transient int keyTag;
|
||||
|
||||
@@ -24,6 +24,7 @@ import jakarta.xml.bind.annotation.XmlElement;
|
||||
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||
import jakarta.xml.bind.annotation.XmlTransient;
|
||||
import jakarta.xml.bind.annotation.XmlType;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/** The EPP secDNS extension that may be present on domain update commands. */
|
||||
@@ -55,16 +56,16 @@ public class SecDnsUpdateExtension extends ImmutableObject implements CommandExt
|
||||
return urgent;
|
||||
}
|
||||
|
||||
public Remove getRemove() {
|
||||
return remove;
|
||||
public Optional<Remove> getRemove() {
|
||||
return Optional.ofNullable(remove);
|
||||
}
|
||||
|
||||
public Add getAdd() {
|
||||
return add;
|
||||
public Optional<Add> getAdd() {
|
||||
return Optional.ofNullable(add);
|
||||
}
|
||||
|
||||
public Change getChange() {
|
||||
return change;
|
||||
public Optional<Change> getChange() {
|
||||
return Optional.ofNullable(change);
|
||||
}
|
||||
|
||||
@XmlTransient
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableSet;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.eppinput.EppInput;
|
||||
import google.registry.model.eppoutput.EppOutput;
|
||||
import google.registry.util.NonFinalForTesting;
|
||||
import google.registry.util.RegistryEnvironment;
|
||||
import google.registry.xml.ValidationMode;
|
||||
import google.registry.xml.XmlException;
|
||||
@@ -60,20 +61,35 @@ public class EppXmlTransformer {
|
||||
// XML schemas that should not be used in production (yet)
|
||||
private static final ImmutableSet<String> NON_PROD_SCHEMAS = ImmutableSet.of("fee-std-v1.xsd");
|
||||
|
||||
private static final XmlTransformer INPUT_TRANSFORMER =
|
||||
// XML schemas that should only be used in production (for backcompat)
|
||||
private static final ImmutableSet<String> ONLY_PROD_SCHEMAS =
|
||||
ImmutableSet.of("fee06.xsd", "fee11.xsd", "fee12.xsd");
|
||||
|
||||
// TODO(gbrodman): make this final when we can actually remove the old fee extensions and aren't
|
||||
// relying on switching by environment
|
||||
@NonFinalForTesting
|
||||
private static XmlTransformer INPUT_TRANSFORMER =
|
||||
new XmlTransformer(getSchemas(), EppInput.class);
|
||||
|
||||
private static final XmlTransformer OUTPUT_TRANSFORMER =
|
||||
// TODO(gbrodman): make this final when we can actually remove the old fee extensions and aren't
|
||||
// relying on switching by environment
|
||||
@NonFinalForTesting
|
||||
private static XmlTransformer OUTPUT_TRANSFORMER =
|
||||
new XmlTransformer(getSchemas(), EppOutput.class);
|
||||
|
||||
@VisibleForTesting
|
||||
public static ImmutableList<String> getSchemas() {
|
||||
if (RegistryEnvironment.get().equals(RegistryEnvironment.PRODUCTION)) {
|
||||
return ALL_SCHEMAS.stream()
|
||||
.filter(s -> !NON_PROD_SCHEMAS.contains(s))
|
||||
.collect(toImmutableList());
|
||||
}
|
||||
return ALL_SCHEMAS;
|
||||
ImmutableSet<String> schemasToSkip =
|
||||
RegistryEnvironment.get().equals(RegistryEnvironment.PRODUCTION)
|
||||
? NON_PROD_SCHEMAS
|
||||
: ONLY_PROD_SCHEMAS;
|
||||
return ALL_SCHEMAS.stream().filter(s -> !schemasToSkip.contains(s)).collect(toImmutableList());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static void reloadTransformers() {
|
||||
INPUT_TRANSFORMER = new XmlTransformer(getSchemas(), EppInput.class);
|
||||
OUTPUT_TRANSFORMER = new XmlTransformer(getSchemas(), EppOutput.class);
|
||||
}
|
||||
|
||||
public static void validateOutput(String xml) throws XmlException {
|
||||
|
||||
@@ -17,6 +17,7 @@ package google.registry.model.eppcommon;
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.common.collect.Maps.uniqueIndex;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import google.registry.model.domain.fee06.FeeCheckCommandExtensionV06;
|
||||
@@ -33,6 +34,7 @@ import google.registry.model.domain.rgp.RgpUpdateExtension;
|
||||
import google.registry.model.domain.secdns.SecDnsCreateExtension;
|
||||
import google.registry.model.eppinput.EppInput.CommandExtension;
|
||||
import google.registry.model.eppoutput.EppResponse.ResponseExtension;
|
||||
import google.registry.util.NonFinalForTesting;
|
||||
import google.registry.util.RegistryEnvironment;
|
||||
import jakarta.xml.bind.annotation.XmlSchema;
|
||||
import java.util.EnumSet;
|
||||
@@ -44,10 +46,7 @@ public class ProtocolDefinition {
|
||||
public static final String LANGUAGE = "en";
|
||||
|
||||
public static final ImmutableSet<String> SUPPORTED_OBJECT_SERVICES =
|
||||
ImmutableSet.of(
|
||||
"urn:ietf:params:xml:ns:host-1.0",
|
||||
"urn:ietf:params:xml:ns:domain-1.0",
|
||||
"urn:ietf:params:xml:ns:contact-1.0");
|
||||
ImmutableSet.of("urn:ietf:params:xml:ns:host-1.0", "urn:ietf:params:xml:ns:domain-1.0");
|
||||
|
||||
/** Enum representing which environments should have which service extensions enabled. */
|
||||
private enum ServiceExtensionVisibility {
|
||||
@@ -65,15 +64,15 @@ public class ProtocolDefinition {
|
||||
FEE_0_6(
|
||||
FeeCheckCommandExtensionV06.class,
|
||||
FeeCheckResponseExtensionV06.class,
|
||||
ServiceExtensionVisibility.ALL),
|
||||
ServiceExtensionVisibility.ONLY_IN_PRODUCTION),
|
||||
FEE_0_11(
|
||||
FeeCheckCommandExtensionV11.class,
|
||||
FeeCheckResponseExtensionV11.class,
|
||||
ServiceExtensionVisibility.ALL),
|
||||
ServiceExtensionVisibility.ONLY_IN_PRODUCTION),
|
||||
FEE_0_12(
|
||||
FeeCheckCommandExtensionV12.class,
|
||||
FeeCheckResponseExtensionV12.class,
|
||||
ServiceExtensionVisibility.ALL),
|
||||
ServiceExtensionVisibility.ONLY_IN_PRODUCTION),
|
||||
FEE_1_00(
|
||||
FeeCheckCommandExtensionStdV1.class,
|
||||
FeeCheckResponseExtensionStdV1.class,
|
||||
@@ -112,7 +111,7 @@ public class ProtocolDefinition {
|
||||
return clazz.getPackage().getAnnotation(XmlSchema.class).namespace();
|
||||
}
|
||||
|
||||
private boolean isVisible() {
|
||||
public boolean isVisible() {
|
||||
return switch (visibility) {
|
||||
case ALL -> true;
|
||||
case ONLY_IN_PRODUCTION -> RegistryEnvironment.get().equals(RegistryEnvironment.PRODUCTION);
|
||||
@@ -137,14 +136,25 @@ public class ProtocolDefinition {
|
||||
}
|
||||
|
||||
/** A set of all the visible extension URIs. */
|
||||
private static final ImmutableSet<String> visibleServiceExtensionUris =
|
||||
EnumSet.allOf(ServiceExtension.class).stream()
|
||||
.filter(ServiceExtension::isVisible)
|
||||
.map(ServiceExtension::getUri)
|
||||
.collect(toImmutableSet());
|
||||
// TODO(gbrodman): make this final when we can actually remove the old fee extensions and aren't
|
||||
// relying on switching by environment
|
||||
@NonFinalForTesting private static ImmutableSet<String> visibleServiceExtensionUris;
|
||||
|
||||
static {
|
||||
reloadServiceExtensionUris();
|
||||
}
|
||||
|
||||
/** Return the set of all visible service extension URIs. */
|
||||
public static ImmutableSet<String> getVisibleServiceExtensionUris() {
|
||||
return visibleServiceExtensionUris;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static void reloadServiceExtensionUris() {
|
||||
visibleServiceExtensionUris =
|
||||
EnumSet.allOf(ServiceExtension.class).stream()
|
||||
.filter(ServiceExtension::isVisible)
|
||||
.map(ServiceExtension::getUri)
|
||||
.collect(toImmutableSet());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,6 +143,7 @@ public class MosApiStateService {
|
||||
|
||||
if (!allStates.isEmpty()) {
|
||||
try {
|
||||
logger.atInfo().log("Triggering MoSAPI status to cloud monitoring for all TLDs.");
|
||||
mosApiMetrics.recordStates(allStates);
|
||||
} catch (Exception e) {
|
||||
logger.atSevere().withCause(e).log("Failed to submit MoSAPI metrics batch.");
|
||||
|
||||
@@ -48,6 +48,7 @@ public class TriggerServiceStateAction implements Runnable {
|
||||
public void run() {
|
||||
response.setContentType(MediaType.PLAIN_TEXT_UTF_8);
|
||||
try {
|
||||
logger.atInfo().log("Beginning to trigger MoSAPI metrics for all TLDs.");
|
||||
stateService.triggerMetricsForAllServiceStateSummaries();
|
||||
response.setStatus(200);
|
||||
response.setPayload("MoSAPI metrics triggered successfully for all TLDs.");
|
||||
|
||||
@@ -135,28 +135,6 @@ public abstract class FlowTestCase<F extends Flow> {
|
||||
return TestDataHelper.loadFile(getClass(), filename, substitutions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an input or response EPP message with draft fee extension v12 to std v1.
|
||||
*
|
||||
* <p>There is no practical changes between draft v12 and the v1 standard. This method allows us
|
||||
* to reuse v12 test data.
|
||||
*/
|
||||
protected String loadFeeV12FileAsStdV1(String filename) {
|
||||
String content = loadFile(filename);
|
||||
return content.replace("urn:ietf:params:xml:ns:fee-0.12", "urn:ietf:params:xml:ns:epp:fee-1.0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an input or response EPP message with draft fee extension v12 to std v1.
|
||||
*
|
||||
* <p>There is no practical changes between draft v12 and the v1 standard. This method allows us
|
||||
* to reuse v12 test data.
|
||||
*/
|
||||
protected String loadFeeV12FileAsStdV1(String filename, Map<String, String> substitutions) {
|
||||
String content = loadFile(filename, substitutions);
|
||||
return content.replace("urn:ietf:params:xml:ns:fee-0.12", "urn:ietf:params:xml:ns:epp:fee-1.0");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getClientTrid() throws Exception {
|
||||
return eppLoader.getEpp().getCommandWrapper().getClTrid().orElse(null);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -209,6 +209,10 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
private static final String ENCODED_SMD =
|
||||
TmchData.readEncodedSignedMark(TmchTestData.loadFile(SMD_FILE_PATH)).getEncodedData();
|
||||
|
||||
private static final ImmutableMap<String, String> FEE_STD_1_0_MAP =
|
||||
ImmutableMap.of(
|
||||
"FEE_VERSION", "epp:fee-1.0", "FEE_NS", "fee1_00", "CURRENCY", "USD", "FEE", "15.00");
|
||||
|
||||
private AllocationToken allocationToken;
|
||||
|
||||
DomainCreateFlowTest() {
|
||||
@@ -640,132 +644,44 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v06() throws Exception {
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.6", "CURRENCY", "USD"));
|
||||
void testSuccess_fee_std_v1() throws Exception {
|
||||
setEppInput("domain_create_fee.xml", FEE_STD_1_0_MAP);
|
||||
persistContactsAndHosts();
|
||||
doSuccessfulTest(
|
||||
"tld",
|
||||
"domain_create_response_fee.xml",
|
||||
ImmutableMap.of("FEE_VERSION", "0.6", "FEE", "24.00"));
|
||||
ImmutableMap.of("FEE_VERSION", "epp:fee-1.0", "FEE", "24.00"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v11() throws Exception {
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.11", "CURRENCY", "USD"));
|
||||
void testSuccess_fee_withDefaultAttributes_std_v1() throws Exception {
|
||||
setEppInput("domain_create_fee_defaults.xml", FEE_STD_1_0_MAP);
|
||||
persistContactsAndHosts();
|
||||
doSuccessfulTest(
|
||||
"tld",
|
||||
"domain_create_response_fee.xml",
|
||||
ImmutableMap.of("FEE_VERSION", "0.11", "FEE", "24.00"));
|
||||
ImmutableMap.of("FEE_VERSION", "epp:fee-1.0", "FEE", "24.00"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v12() throws Exception {
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.12", "CURRENCY", "USD"));
|
||||
persistContactsAndHosts();
|
||||
doSuccessfulTest(
|
||||
"tld",
|
||||
"domain_create_response_fee.xml",
|
||||
ImmutableMap.of("FEE_VERSION", "0.12", "FEE", "24.00"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v06() throws Exception {
|
||||
setEppInput("domain_create_fee_defaults.xml", ImmutableMap.of("FEE_VERSION", "0.6"));
|
||||
persistContactsAndHosts();
|
||||
doSuccessfulTest(
|
||||
"tld",
|
||||
"domain_create_response_fee.xml",
|
||||
ImmutableMap.of("FEE_VERSION", "0.6", "FEE", "24.00"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v11() throws Exception {
|
||||
setEppInput("domain_create_fee_defaults.xml", ImmutableMap.of("FEE_VERSION", "0.11"));
|
||||
persistContactsAndHosts();
|
||||
doSuccessfulTest(
|
||||
"tld",
|
||||
"domain_create_response_fee.xml",
|
||||
ImmutableMap.of("FEE_VERSION", "0.11", "FEE", "24.00"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v12() throws Exception {
|
||||
setEppInput("domain_create_fee_defaults.xml", ImmutableMap.of("FEE_VERSION", "0.12"));
|
||||
persistContactsAndHosts();
|
||||
doSuccessfulTest(
|
||||
"tld",
|
||||
"domain_create_response_fee.xml",
|
||||
ImmutableMap.of("FEE_VERSION", "0.12", "FEE", "24.00"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v06() {
|
||||
setEppInput("domain_create_fee_refundable.xml", ImmutableMap.of("FEE_VERSION", "0.6"));
|
||||
void testFailure_refundableFee_std_v1() {
|
||||
setEppInput("domain_create_fee_refundable.xml", FEE_STD_1_0_MAP);
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v11() {
|
||||
setEppInput("domain_create_fee_refundable.xml", ImmutableMap.of("FEE_VERSION", "0.11"));
|
||||
void testFailure_gracePeriodFee_std_v1() {
|
||||
setEppInput("domain_create_fee_grace_period.xml", FEE_STD_1_0_MAP);
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v12() {
|
||||
setEppInput("domain_create_fee_refundable.xml", ImmutableMap.of("FEE_VERSION", "0.12"));
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v06() {
|
||||
setEppInput("domain_create_fee_grace_period.xml", ImmutableMap.of("FEE_VERSION", "0.6"));
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v11() {
|
||||
setEppInput("domain_create_fee_grace_period.xml", ImmutableMap.of("FEE_VERSION", "0.11"));
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v12() {
|
||||
setEppInput("domain_create_fee_grace_period.xml", ImmutableMap.of("FEE_VERSION", "0.12"));
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v06() {
|
||||
setEppInput("domain_create_fee_applied.xml", ImmutableMap.of("FEE_VERSION", "0.6"));
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v11() {
|
||||
setEppInput("domain_create_fee_applied.xml", ImmutableMap.of("FEE_VERSION", "0.11"));
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v12() {
|
||||
setEppInput("domain_create_fee_applied.xml", ImmutableMap.of("FEE_VERSION", "0.12"));
|
||||
void testFailure_appliedFee_std_v1() {
|
||||
setEppInput("domain_create_fee_applied.xml", FEE_STD_1_0_MAP);
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
@@ -796,9 +712,9 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_premiumAndEap() throws Exception {
|
||||
void testSuccess_premiumAndEap_std_v1() throws Exception {
|
||||
createTld("example");
|
||||
setEppInput("domain_create_premium_eap.xml");
|
||||
setEppInput("domain_create_premium_eap.xml", FEE_STD_1_0_MAP);
|
||||
persistContactsAndHosts("net");
|
||||
persistResource(
|
||||
Tld.get("example")
|
||||
@@ -816,8 +732,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
runFlowAssertResponse(
|
||||
CommitMode.LIVE,
|
||||
UserPrivileges.NORMAL,
|
||||
loadFile(
|
||||
"domain_create_response_premium_eap.xml", ImmutableMap.of("DOMAIN", "rich.example")));
|
||||
loadFile("domain_create_response_premium_eap.xml", FEE_STD_1_0_MAP));
|
||||
assertSuccessfulCreate("example", ImmutableSet.of(), 200);
|
||||
assertNoLordn();
|
||||
}
|
||||
@@ -1047,8 +962,8 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v06() {
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.6", "CURRENCY", "USD"));
|
||||
void testFailure_wrongFeeAmount_std_v1() {
|
||||
setEppInput("domain_create_fee.xml", FEE_STD_1_0_MAP);
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
@@ -1061,7 +976,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_wrongFeeAmountTooHigh_defaultToken_v06() throws Exception {
|
||||
void testSuccess_wrongFeeAmountTooHigh_defaultToken_std_v1() throws Exception {
|
||||
setupDefaultTokenWithDiscount();
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
@@ -1069,65 +984,14 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
.setCreateBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 8)))
|
||||
.build());
|
||||
// Expects fee of $24
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.6", "CURRENCY", "USD"));
|
||||
persistContactsAndHosts();
|
||||
// $15 is 50% off the first year registration ($8) and 0% 0ff the 2nd year (renewal at $11)
|
||||
runFlowAssertResponse(
|
||||
loadFile(
|
||||
"domain_create_response_fee.xml",
|
||||
ImmutableMap.of("FEE_VERSION", "0.6", "FEE", "15.00")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmountTooLow_defaultToken_v06() throws Exception {
|
||||
setupDefaultTokenWithDiscount();
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setCreateBillingCostTransitions(
|
||||
ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 100)))
|
||||
.build());
|
||||
// Expects fee of $24
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.6", "CURRENCY", "USD"));
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v11() {
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.11", "CURRENCY", "USD"));
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setCreateBillingCostTransitions(
|
||||
ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 20)))
|
||||
.build());
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_wrongFeeAmountTooHigh_defaultToken_v11() throws Exception {
|
||||
setupDefaultTokenWithDiscount();
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setCreateBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 8)))
|
||||
.build());
|
||||
// Expects fee of $24
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.11", "CURRENCY", "USD"));
|
||||
setEppInput("domain_create_fee.xml", FEE_STD_1_0_MAP);
|
||||
persistContactsAndHosts();
|
||||
// $12 is equal to 50% off the first year registration and 0% 0ff the 2nd year
|
||||
runFlowAssertResponse(
|
||||
loadFile(
|
||||
"domain_create_response_fee.xml",
|
||||
ImmutableMap.of("FEE_VERSION", "0.11", "FEE", "15.00")));
|
||||
runFlowAssertResponse(loadFile("domain_create_response_fee.xml", FEE_STD_1_0_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmountTooLow_defaultToken_v11() throws Exception {
|
||||
void testFailure_wrongFeeAmountTooLow_defaultToken_std_v1() throws Exception {
|
||||
setupDefaultTokenWithDiscount();
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
@@ -1136,79 +1000,16 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 100)))
|
||||
.build());
|
||||
// Expects fee of $24
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.11", "CURRENCY", "USD"));
|
||||
setEppInput("domain_create_fee.xml", FEE_STD_1_0_MAP);
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v12() {
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.12", "CURRENCY", "USD"));
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setCreateBillingCostTransitions(
|
||||
ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 20)))
|
||||
.build());
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_wrongFeeAmountTooHigh_defaultToken_v12() throws Exception {
|
||||
setupDefaultTokenWithDiscount();
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setCreateBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 8)))
|
||||
.build());
|
||||
// Expects fee of $24
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.12", "CURRENCY", "USD"));
|
||||
persistContactsAndHosts();
|
||||
// $12 is equal to 50% off the first year registration and 0% 0ff the 2nd year
|
||||
runFlowAssertResponse(
|
||||
loadFile(
|
||||
"domain_create_response_fee.xml",
|
||||
ImmutableMap.of("FEE_VERSION", "0.12", "FEE", "15.00")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmountTooLow_defaultToken_v12() throws Exception {
|
||||
setupDefaultTokenWithDiscount();
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setCreateBillingCostTransitions(
|
||||
ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 100)))
|
||||
.build());
|
||||
// Expects fee of $24
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.12", "CURRENCY", "USD"));
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v06() {
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.6", "CURRENCY", "EUR"));
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(CurrencyUnitMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v11() {
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.11", "CURRENCY", "EUR"));
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(CurrencyUnitMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v12() {
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.12", "CURRENCY", "EUR"));
|
||||
void testFailure_wrongCurrency_std_v1() {
|
||||
setEppInput(
|
||||
"domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "epp:fee-1.0", "CURRENCY", "EUR"));
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(CurrencyUnitMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
@@ -1216,7 +1017,8 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
|
||||
@Test
|
||||
void testFailure_unknownCurrency() {
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.12", "CURRENCY", "BAD"));
|
||||
setEppInput(
|
||||
"domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "epp:fee-1.0", "CURRENCY", "BAD"));
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(UnknownCurrencyEppException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
@@ -1580,7 +1382,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_allocationToken_multiYearDiscount_worksForPremiums() throws Exception {
|
||||
void testSuccess_allocationToken_multiYearDiscount_worksForPremiums_std_v1() throws Exception {
|
||||
createTld("example");
|
||||
persistContactsAndHosts();
|
||||
persistResource(
|
||||
@@ -1601,11 +1403,17 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
clock.advanceOneMilli();
|
||||
setEppInput(
|
||||
"domain_create_premium_allocationtoken.xml",
|
||||
ImmutableMap.of("YEARS", "3", "FEE", "104.00"));
|
||||
ImmutableMap.of("FEE_VERSION", "epp:fee-1.0", "YEARS", "3", "FEE", "104.00"));
|
||||
runFlowAssertResponse(
|
||||
loadFile(
|
||||
"domain_create_response_premium.xml",
|
||||
ImmutableMap.of("EXDATE", "2002-04-03T22:00:00.0Z", "FEE", "104.00")));
|
||||
ImmutableMap.of(
|
||||
"FEE_VERSION",
|
||||
"epp:fee-1.0",
|
||||
"EXDATE",
|
||||
"2002-04-03T22:00:00.0Z",
|
||||
"FEE",
|
||||
"104.00")));
|
||||
BillingEvent billingEvent =
|
||||
Iterables.getOnlyElement(DatabaseHelper.loadAllOf(BillingEvent.class));
|
||||
assertThat(billingEvent.getTargetId()).isEqualTo("rich.example");
|
||||
@@ -1614,7 +1422,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_allocationToken_singleYearDiscount_worksForPremiums() throws Exception {
|
||||
void testSuccess_allocationToken_singleYearDiscount_worksForPremiums_std_v1() throws Exception {
|
||||
createTld("example");
|
||||
persistContactsAndHosts();
|
||||
persistResource(
|
||||
@@ -1634,11 +1442,17 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
clock.advanceOneMilli();
|
||||
setEppInput(
|
||||
"domain_create_premium_allocationtoken.xml",
|
||||
ImmutableMap.of("YEARS", "3", "FEE", "204.44"));
|
||||
ImmutableMap.of("FEE_VERSION", "epp:fee-1.0", "YEARS", "3", "FEE", "204.44"));
|
||||
runFlowAssertResponse(
|
||||
loadFile(
|
||||
"domain_create_response_premium.xml",
|
||||
ImmutableMap.of("EXDATE", "2002-04-03T22:00:00.0Z", "FEE", "204.44")));
|
||||
ImmutableMap.of(
|
||||
"FEE_VERSION",
|
||||
"epp:fee-1.0",
|
||||
"EXDATE",
|
||||
"2002-04-03T22:00:00.0Z",
|
||||
"FEE",
|
||||
"204.44")));
|
||||
BillingEvent billingEvent =
|
||||
Iterables.getOnlyElement(DatabaseHelper.loadAllOf(BillingEvent.class));
|
||||
assertThat(billingEvent.getTargetId()).isEqualTo("rich.example");
|
||||
@@ -1797,7 +1611,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_doesNotApplyNonPremiumDefaultTokenToPremiumName() throws Exception {
|
||||
void testSuccess_doesNotApplyNonPremiumDefaultTokenToPremiumName_std_v1() throws Exception {
|
||||
persistContactsAndHosts();
|
||||
createTld("example");
|
||||
persistResource(
|
||||
@@ -1805,11 +1619,17 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
.asBuilder()
|
||||
.setAllowedTlds(ImmutableSet.of("example"))
|
||||
.build());
|
||||
setEppInput("domain_create_premium.xml");
|
||||
setEppInput("domain_create_premium.xml", FEE_STD_1_0_MAP);
|
||||
runFlowAssertResponse(
|
||||
loadFile(
|
||||
"domain_create_response_premium.xml",
|
||||
ImmutableMap.of("EXDATE", "2001-04-03T22:00:00.0Z", "FEE", "200.00")));
|
||||
ImmutableMap.of(
|
||||
"FEE_VERSION",
|
||||
"epp:fee-1.0",
|
||||
"EXDATE",
|
||||
"2001-04-03T22:00:00.0Z",
|
||||
"FEE",
|
||||
"200.00")));
|
||||
assertSuccessfulCreate("example", ImmutableSet.of(), 200);
|
||||
}
|
||||
|
||||
@@ -1995,9 +1815,9 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_superuserOverridesPremiumNameBlock() throws Exception {
|
||||
void testSuccess_superuserOverridesPremiumNameBlock_std_v1() throws Exception {
|
||||
createTld("example");
|
||||
setEppInput("domain_create_premium.xml");
|
||||
setEppInput("domain_create_premium.xml", FEE_STD_1_0_MAP);
|
||||
persistContactsAndHosts("net");
|
||||
// Modify the Registrar to block premium names.
|
||||
persistResource(loadRegistrar("TheRegistrar").asBuilder().setBlockPremiumNames(true).build());
|
||||
@@ -2006,7 +1826,13 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
SUPERUSER,
|
||||
loadFile(
|
||||
"domain_create_response_premium.xml",
|
||||
ImmutableMap.of("EXDATE", "2001-04-03T22:00:00.0Z", "FEE", "200.00")));
|
||||
ImmutableMap.of(
|
||||
"FEE_VERSION",
|
||||
"epp:fee-1.0",
|
||||
"EXDATE",
|
||||
"2001-04-03T22:00:00.0Z",
|
||||
"FEE",
|
||||
"200.00")));
|
||||
assertSuccessfulCreate("example", ImmutableSet.of(), 200);
|
||||
}
|
||||
|
||||
@@ -2137,9 +1963,9 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_premiumBlocked() {
|
||||
void testFailure_premiumBlocked_std_v1() {
|
||||
createTld("example");
|
||||
setEppInput("domain_create_premium.xml");
|
||||
setEppInput("domain_create_premium.xml", FEE_STD_1_0_MAP);
|
||||
persistContactsAndHosts("net");
|
||||
// Modify the Registrar to block premium names.
|
||||
persistResource(loadRegistrar("TheRegistrar").asBuilder().setBlockPremiumNames(true).build());
|
||||
@@ -2157,60 +1983,20 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_omitFeeExtensionOnLogin_v06() {
|
||||
void testFailure_omitFeeExtensionOnLogin_std_v1() {
|
||||
for (String uri : FEE_EXTENSION_URIS) {
|
||||
removeServiceExtensionUri(uri);
|
||||
}
|
||||
createTld("net");
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.6", "CURRENCY", "USD"));
|
||||
setEppInput("domain_create_fee.xml", FEE_STD_1_0_MAP);
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(UndeclaredServiceExtensionException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_omitFeeExtensionOnLogin_v11() {
|
||||
for (String uri : FEE_EXTENSION_URIS) {
|
||||
removeServiceExtensionUri(uri);
|
||||
}
|
||||
createTld("net");
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.11", "CURRENCY", "USD"));
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(UndeclaredServiceExtensionException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_omitFeeExtensionOnLogin_v12() {
|
||||
for (String uri : FEE_EXTENSION_URIS) {
|
||||
removeServiceExtensionUri(uri);
|
||||
}
|
||||
createTld("net");
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.12", "CURRENCY", "USD"));
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(UndeclaredServiceExtensionException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v06() {
|
||||
setEppInput("domain_create_fee_bad_scale.xml", ImmutableMap.of("FEE_VERSION", "0.6"));
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(CurrencyValueScaleException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v11() {
|
||||
setEppInput("domain_create_fee_bad_scale.xml", ImmutableMap.of("FEE_VERSION", "0.11"));
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(CurrencyValueScaleException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v12() {
|
||||
setEppInput("domain_create_fee_bad_scale.xml", ImmutableMap.of("FEE_VERSION", "0.12"));
|
||||
void testFailure_feeGivenInWrongScale_std_v1() {
|
||||
setEppInput("domain_create_fee_bad_scale.xml", FEE_STD_1_0_MAP);
|
||||
persistContactsAndHosts();
|
||||
EppException thrown = assertThrows(CurrencyValueScaleException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
@@ -2699,8 +2485,8 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_eapFee_combined() {
|
||||
setEppInput("domain_create_eap_combined_fee.xml", ImmutableMap.of("FEE_VERSION", "0.6"));
|
||||
void testFailure_eapFee_combined_std_v1() {
|
||||
setEppInput("domain_create_eap_combined_fee.xml", FEE_STD_1_0_MAP);
|
||||
persistContactsAndHosts();
|
||||
setEapForTld("tld");
|
||||
EppException thrown = assertThrows(FeeDescriptionParseException.class, this::runFlow);
|
||||
@@ -2709,12 +2495,12 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_eapFee_description_swapped() {
|
||||
void testFailure_eapFee_description_swapped_std_v1() {
|
||||
setEppInput(
|
||||
"domain_create_eap_fee.xml",
|
||||
ImmutableMap.of(
|
||||
"FEE_VERSION",
|
||||
"0.6",
|
||||
"epp:fee-1.0",
|
||||
"DESCRIPTION_1",
|
||||
"Early Access Period",
|
||||
"DESCRIPTION_2",
|
||||
@@ -2727,11 +2513,11 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_eapFee_totalAmountNotMatched() {
|
||||
void testFailure_eapFee_totalAmountNotMatched_std_v1() {
|
||||
setEppInput(
|
||||
"domain_create_extra_fees.xml",
|
||||
new ImmutableMap.Builder<String, String>()
|
||||
.put("FEE_VERSION", "0.6")
|
||||
.put("FEE_VERSION", "epp:fee-1.0")
|
||||
.put("DESCRIPTION_1", "create")
|
||||
.put("FEE_1", "24")
|
||||
.put("DESCRIPTION_2", "Early Access Period")
|
||||
@@ -2747,11 +2533,11 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_eapFee_multipleEAPfees_doNotAddToExpectedValue() {
|
||||
void testSuccess_eapFee_multipleEAPfees_doNotAddToExpectedValue_std_v1() {
|
||||
setEppInput(
|
||||
"domain_create_extra_fees.xml",
|
||||
new ImmutableMap.Builder<String, String>()
|
||||
.put("FEE_VERSION", "0.6")
|
||||
.put("FEE_VERSION", "epp:fee-1.0")
|
||||
.put("DESCRIPTION_1", "create")
|
||||
.put("FEE_1", "24")
|
||||
.put("DESCRIPTION_2", "Early Access Period")
|
||||
@@ -2767,11 +2553,11 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_eapFee_multipleEAPfees_addToExpectedValue() throws Exception {
|
||||
void testSuccess_eapFee_multipleEAPfees_addToExpectedValue_std_v1() throws Exception {
|
||||
setEppInput(
|
||||
"domain_create_extra_fees.xml",
|
||||
new ImmutableMap.Builder<String, String>()
|
||||
.put("FEE_VERSION", "0.6")
|
||||
.put("FEE_VERSION", "epp:fee-1.0")
|
||||
.put("DESCRIPTION_1", "create")
|
||||
.put("FEE_1", "24")
|
||||
.put("DESCRIPTION_2", "Early Access Period")
|
||||
@@ -2781,33 +2567,36 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
.build());
|
||||
persistContactsAndHosts();
|
||||
setEapForTld("tld");
|
||||
doSuccessfulTest(
|
||||
"tld", "domain_create_response_eap_fee.xml", ImmutableMap.of("FEE_VERSION", "0.6"));
|
||||
doSuccessfulTest("tld", "domain_create_response_eap_fee.xml", FEE_STD_1_0_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_eapFee_fullDescription_includingArbitraryExpiryTime() throws Exception {
|
||||
void testSuccess_eapFee_fullDescription_includingArbitraryExpiryTime_std_v1() throws Exception {
|
||||
setEppInput(
|
||||
"domain_create_eap_fee.xml",
|
||||
ImmutableMap.of(
|
||||
"FEE_VERSION",
|
||||
"0.6",
|
||||
"epp:fee-1.0",
|
||||
"DESCRIPTION_1",
|
||||
"create",
|
||||
"DESCRIPTION_2",
|
||||
"Early Access Period, fee expires: 2022-03-01T00:00:00.000Z"));
|
||||
persistContactsAndHosts();
|
||||
setEapForTld("tld");
|
||||
doSuccessfulTest(
|
||||
"tld", "domain_create_response_eap_fee.xml", ImmutableMap.of("FEE_VERSION", "0.6"));
|
||||
doSuccessfulTest("tld", "domain_create_response_eap_fee.xml", FEE_STD_1_0_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_eapFee_description_multipleMatch() {
|
||||
void testFailure_eapFee_description_multipleMatch_std_v1() {
|
||||
setEppInput(
|
||||
"domain_create_eap_fee.xml",
|
||||
ImmutableMap.of(
|
||||
"FEE_VERSION", "0.6", "DESCRIPTION_1", "create", "DESCRIPTION_2", "renew transfer"));
|
||||
"FEE_VERSION",
|
||||
"epp:fee-1.0",
|
||||
"DESCRIPTION_1",
|
||||
"create",
|
||||
"DESCRIPTION_2",
|
||||
"renew transfer"));
|
||||
persistContactsAndHosts();
|
||||
setEapForTld("tld");
|
||||
EppException thrown = assertThrows(FeeDescriptionMultipleMatchesException.class, this::runFlow);
|
||||
@@ -2816,54 +2605,17 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_eapFeeApplied_v06() throws Exception {
|
||||
void testSuccess_eapFeeApplied_std_v1() throws Exception {
|
||||
setEppInput(
|
||||
"domain_create_eap_fee.xml",
|
||||
ImmutableMap.of(
|
||||
"FEE_VERSION",
|
||||
"0.6",
|
||||
"DESCRIPTION_1",
|
||||
"create",
|
||||
"DESCRIPTION_2",
|
||||
"Early Access Period"));
|
||||
new ImmutableMap.Builder<String, String>()
|
||||
.putAll(FEE_STD_1_0_MAP)
|
||||
.put("DESCRIPTION_1", "create")
|
||||
.put("DESCRIPTION_2", "Early Access Period")
|
||||
.build());
|
||||
persistContactsAndHosts();
|
||||
setEapForTld("tld");
|
||||
doSuccessfulTest(
|
||||
"tld", "domain_create_response_eap_fee.xml", ImmutableMap.of("FEE_VERSION", "0.6"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_eapFeeApplied_v11() throws Exception {
|
||||
setEppInput(
|
||||
"domain_create_eap_fee.xml",
|
||||
ImmutableMap.of(
|
||||
"FEE_VERSION",
|
||||
"0.11",
|
||||
"DESCRIPTION_1",
|
||||
"create",
|
||||
"DESCRIPTION_2",
|
||||
"Early Access Period"));
|
||||
persistContactsAndHosts();
|
||||
setEapForTld("tld");
|
||||
doSuccessfulTest(
|
||||
"tld", "domain_create_response_eap_fee.xml", ImmutableMap.of("FEE_VERSION", "0.11"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_eapFeeApplied_v12() throws Exception {
|
||||
setEppInput(
|
||||
"domain_create_eap_fee.xml",
|
||||
ImmutableMap.of(
|
||||
"FEE_VERSION",
|
||||
"0.12",
|
||||
"DESCRIPTION_1",
|
||||
"create",
|
||||
"DESCRIPTION_2",
|
||||
"Early Access Period"));
|
||||
persistContactsAndHosts();
|
||||
setEapForTld("tld");
|
||||
doSuccessfulTest(
|
||||
"tld", "domain_create_response_eap_fee.xml", ImmutableMap.of("FEE_VERSION", "0.12"));
|
||||
doSuccessfulTest("tld", "domain_create_response_eap_fee.xml", FEE_STD_1_0_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -3002,7 +2754,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_nonAnchorTenant_nonPremiumRenewal() throws Exception {
|
||||
void testSuccess_nonAnchorTenant_nonPremiumRenewal_std_v1() throws Exception {
|
||||
createTld("example");
|
||||
AllocationToken token =
|
||||
persistResource(
|
||||
@@ -3016,13 +2768,13 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
// Creation is still $100 but it'll create a NONPREMIUM renewal
|
||||
setEppInput(
|
||||
"domain_create_premium_allocationtoken.xml",
|
||||
ImmutableMap.of("YEARS", "2", "FEE", "111.00"));
|
||||
ImmutableMap.of("FEE_VERSION", "epp:fee-1.0", "YEARS", "2", "FEE", "111.00"));
|
||||
runFlow();
|
||||
assertSuccessfulCreate("example", ImmutableSet.of(), token, 111);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_specifiedRenewalPriceToken_specifiedRecurrencePrice() throws Exception {
|
||||
void testSuccess_specifiedRenewalPriceToken_specifiedRecurrencePrice_std_v1() throws Exception {
|
||||
createTld("example");
|
||||
AllocationToken token =
|
||||
persistResource(
|
||||
@@ -3037,7 +2789,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
// Creation is still $100 but it'll create a $1 renewal
|
||||
setEppInput(
|
||||
"domain_create_premium_allocationtoken.xml",
|
||||
ImmutableMap.of("YEARS", "2", "FEE", "101.00"));
|
||||
ImmutableMap.of("FEE_VERSION", "epp:fee-1.0", "YEARS", "2", "FEE", "101.00"));
|
||||
runFlow();
|
||||
assertSuccessfulCreate("example", ImmutableSet.of(), token, 101, 1);
|
||||
}
|
||||
@@ -3087,7 +2839,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_nonpremiumCreateToken() throws Exception {
|
||||
void testSuccess_nonpremiumCreateToken_std_v1() throws Exception {
|
||||
createTld("example");
|
||||
persistContactsAndHosts();
|
||||
persistResource(
|
||||
@@ -3098,8 +2850,9 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
.setDomainName("rich.example")
|
||||
.build());
|
||||
setEppInput(
|
||||
"domain_create_premium_allocationtoken.xml", ImmutableMap.of("YEARS", "1", "FEE", "13.00"));
|
||||
runFlowAssertResponse(loadFile("domain_create_nonpremium_token_response.xml"));
|
||||
"domain_create_premium_allocationtoken.xml",
|
||||
ImmutableMap.of("FEE_VERSION", "epp:fee-1.0", "YEARS", "1", "FEE", "13.00"));
|
||||
runFlowAssertResponse(loadFile("domain_create_nonpremium_token_response.xml", FEE_STD_1_0_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -3495,7 +3248,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
void testTieredPricingPromoResponse() throws Exception {
|
||||
sessionMetadata.setRegistrarId("NewRegistrar");
|
||||
setupDefaultTokenWithDiscount("NewRegistrar");
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.12", "CURRENCY", "USD"));
|
||||
setEppInput("domain_create_fee.xml", FEE_STD_1_0_MAP);
|
||||
persistContactsAndHosts();
|
||||
|
||||
// Fee in the result should be 24 (create cost of 13 plus renew cost of 11) even though the
|
||||
@@ -3503,29 +3256,29 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
runFlowAssertResponse(
|
||||
loadFile(
|
||||
"domain_create_response_fee.xml",
|
||||
ImmutableMap.of("FEE_VERSION", "0.12", "FEE", "24.00")));
|
||||
ImmutableMap.of("FEE_VERSION", "epp:fee-1.0", "FEE", "24.00")));
|
||||
// Expected cost is half off the create cost (13/2 == 6.50) plus one full-cost renew (11)
|
||||
assertThat(Iterables.getOnlyElement(loadAllOf(BillingEvent.class)).getCost())
|
||||
.isEqualTo(Money.of(USD, 17.50));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTieredPricingPromo_registrarNotIncluded_standardResponse() throws Exception {
|
||||
void testTieredPricingPromo_registrarNotIncluded_standardResponse_std_v1() throws Exception {
|
||||
setupDefaultTokenWithDiscount("NewRegistrar");
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.12", "CURRENCY", "USD"));
|
||||
setEppInput("domain_create_fee.xml", FEE_STD_1_0_MAP);
|
||||
persistContactsAndHosts();
|
||||
|
||||
// For a registrar not included in the tiered pricing promo, costs should be 24
|
||||
runFlowAssertResponse(
|
||||
loadFile(
|
||||
"domain_create_response_fee.xml",
|
||||
ImmutableMap.of("FEE_VERSION", "0.12", "FEE", "24.00")));
|
||||
ImmutableMap.of("FEE_VERSION", "epp:fee-1.0", "FEE", "24.00")));
|
||||
assertThat(Iterables.getOnlyElement(loadAllOf(BillingEvent.class)).getCost())
|
||||
.isEqualTo(Money.of(USD, 24));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTieredPricingPromo_registrarIncluded_noTokenActive() throws Exception {
|
||||
void testTieredPricingPromo_registrarIncluded_noTokenActive_std_v1() throws Exception {
|
||||
sessionMetadata.setRegistrarId("NewRegistrar");
|
||||
persistActiveDomain("example1.tld");
|
||||
|
||||
@@ -3540,14 +3293,14 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
TokenStatus.VALID))
|
||||
.build());
|
||||
|
||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.12", "CURRENCY", "USD"));
|
||||
setEppInput("domain_create_fee.xml", FEE_STD_1_0_MAP);
|
||||
persistContactsAndHosts();
|
||||
|
||||
// The token hasn't started yet, so the cost should be create (13) plus renew (11)
|
||||
runFlowAssertResponse(
|
||||
loadFile(
|
||||
"domain_create_response_fee.xml",
|
||||
ImmutableMap.of("FEE_VERSION", "0.12", "FEE", "24.00")));
|
||||
ImmutableMap.of("FEE_VERSION", "epp:fee-1.0", "FEE", "24.00")));
|
||||
assertThat(Iterables.getOnlyElement(loadAllOf(BillingEvent.class)).getCost())
|
||||
.isEqualTo(Money.of(USD, 24));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,440 @@
|
||||
// Copyright 2026 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.flows.domain;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_CREATE;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_DELETE;
|
||||
import static google.registry.testing.DatabaseHelper.assertBillingEvents;
|
||||
import static google.registry.testing.DatabaseHelper.assertDomainDnsRequests;
|
||||
import static google.registry.testing.DatabaseHelper.assertPollMessages;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.getOnlyHistoryEntryOfType;
|
||||
import static google.registry.testing.DatabaseHelper.getOnlyPollMessage;
|
||||
import static google.registry.testing.DatabaseHelper.getPollMessages;
|
||||
import static google.registry.testing.DatabaseHelper.loadByKey;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveContact;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.DomainSubject.assertAboutDomains;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
import static org.joda.money.CurrencyUnit.USD;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import google.registry.model.billing.BillingBase.Flag;
|
||||
import google.registry.model.billing.BillingBase.Reason;
|
||||
import google.registry.model.billing.BillingCancellation;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.billing.BillingRecurrence;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.domain.DomainHistory;
|
||||
import google.registry.model.domain.GracePeriod;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.eppcommon.ProtocolDefinition.ServiceExtension;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.model.poll.PollMessage;
|
||||
import google.registry.model.tld.Tld;
|
||||
import google.registry.testing.DatabaseHelper;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Tests for {@link DomainDeleteFlow} that use the old fee extensions (0.6, 0.11, 0.12). */
|
||||
public class DomainDeleteFlowOldFeeExtensionsTest
|
||||
extends ProductionSimulatingFeeExtensionsTest<DomainDeleteFlow> {
|
||||
|
||||
private static final DateTime TIME_BEFORE_FLOW = DateTime.parse("2000-06-06T22:00:00.0Z");
|
||||
private static final DateTime A_MONTH_AGO = TIME_BEFORE_FLOW.minusMonths(1);
|
||||
private static final DateTime A_MONTH_FROM_NOW = TIME_BEFORE_FLOW.plusMonths(1);
|
||||
|
||||
private static final ImmutableMap<String, String> FEE_06_MAP =
|
||||
ImmutableMap.of("FEE_VERSION", "fee-0.6", "FEE_NS", "fee");
|
||||
private static final ImmutableMap<String, String> FEE_11_MAP =
|
||||
ImmutableMap.of("FEE_VERSION", "fee-0.11", "FEE_NS", "fee11");
|
||||
private static final ImmutableMap<String, String> FEE_12_MAP =
|
||||
ImmutableMap.of("FEE_VERSION", "fee-0.12", "FEE_NS", "fee12");
|
||||
|
||||
private Domain domain;
|
||||
private DomainHistory earlierHistoryEntry;
|
||||
|
||||
@BeforeEach
|
||||
void beforeEachomainDeleteFlowOldFeeExtensionsTest() {
|
||||
clock.setTo(TIME_BEFORE_FLOW);
|
||||
setEppInput("domain_delete.xml");
|
||||
createTld("tld");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_renewGracePeriodCredit_v06() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_11.getUri());
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_12.getUri());
|
||||
doSuccessfulTest_noAddGracePeriod("domain_delete_response_pending_fee.xml", FEE_06_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_renewGracePeriodCredit_v11() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_12.getUri());
|
||||
doSuccessfulTest_noAddGracePeriod("domain_delete_response_pending_fee.xml", FEE_11_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_renewGracePeriodCredit_v12() throws Exception {
|
||||
doSuccessfulTest_noAddGracePeriod("domain_delete_response_pending_fee.xml", FEE_12_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_addGracePeriodCredit_v06() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_11.getUri());
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_12.getUri());
|
||||
doAddGracePeriodDeleteTest(GracePeriodStatus.ADD, "domain_delete_response_fee.xml", FEE_06_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_addGracePeriodCredit_v11() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_12.getUri());
|
||||
doAddGracePeriodDeleteTest(GracePeriodStatus.ADD, "domain_delete_response_fee.xml", FEE_11_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_addGracePeriodCredit_v12() throws Exception {
|
||||
doAddGracePeriodDeleteTest(GracePeriodStatus.ADD, "domain_delete_response_fee.xml", FEE_12_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_autoRenewGracePeriod_v06() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_11.getUri());
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_12.getUri());
|
||||
setUpAutorenewGracePeriod();
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(loadFile("domain_delete_response_autorenew_fee.xml", FEE_06_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_autoRenewGracePeriod_v11() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_12.getUri());
|
||||
setUpAutorenewGracePeriod();
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(loadFile("domain_delete_response_autorenew_fee.xml", FEE_11_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_autoRenewGracePeriod_v12() throws Exception {
|
||||
setUpAutorenewGracePeriod();
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(loadFile("domain_delete_response_autorenew_fee.xml", FEE_12_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_autoRenewGracePeriod_priceChanges_v06() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_11.getUri());
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_12.getUri());
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setRenewBillingCostTransitions(
|
||||
ImmutableSortedMap.of(
|
||||
START_OF_TIME,
|
||||
Money.of(USD, 11),
|
||||
TIME_BEFORE_FLOW.minusDays(5),
|
||||
Money.of(USD, 20)))
|
||||
.build());
|
||||
setUpAutorenewGracePeriod();
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(loadFile("domain_delete_response_autorenew_fee.xml", FEE_06_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_autoRenewGracePeriod_priceChanges_v11() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_12.getUri());
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setRenewBillingCostTransitions(
|
||||
ImmutableSortedMap.of(
|
||||
START_OF_TIME,
|
||||
Money.of(USD, 11),
|
||||
TIME_BEFORE_FLOW.minusDays(5),
|
||||
Money.of(USD, 20)))
|
||||
.build());
|
||||
setUpAutorenewGracePeriod();
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(loadFile("domain_delete_response_autorenew_fee.xml", FEE_11_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_autoRenewGracePeriod_priceChanges_v12() throws Exception {
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setRenewBillingCostTransitions(
|
||||
ImmutableSortedMap.of(
|
||||
START_OF_TIME,
|
||||
Money.of(USD, 11),
|
||||
TIME_BEFORE_FLOW.minusDays(5),
|
||||
Money.of(USD, 20)))
|
||||
.build());
|
||||
setUpAutorenewGracePeriod();
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(loadFile("domain_delete_response_autorenew_fee.xml", FEE_12_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_freeCreation_deletionDuringGracePeriod_v12() throws Exception {
|
||||
// Deletion during the add grace period should still work even if the credit is 0
|
||||
setUpSuccessfulTest();
|
||||
BillingEvent graceBillingEvent =
|
||||
persistResource(createBillingEvent(Reason.CREATE, Money.of(USD, 0)));
|
||||
setUpGracePeriods(
|
||||
GracePeriod.forBillingEvent(GracePeriodStatus.ADD, domain.getRepoId(), graceBillingEvent));
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(loadFile("domain_delete_response_fee_free_grace_v12.xml"));
|
||||
}
|
||||
|
||||
private void createReferencedEntities(DateTime expirationTime) throws Exception {
|
||||
// Persist a linked contact.
|
||||
Contact contact = persistActiveContact("sh8013");
|
||||
domain =
|
||||
persistResource(
|
||||
DatabaseHelper.newDomain(getUniqueIdFromCommand())
|
||||
.asBuilder()
|
||||
.setCreationTimeForTest(TIME_BEFORE_FLOW)
|
||||
.setRegistrant(Optional.of(contact.createVKey()))
|
||||
.setRegistrationExpirationTime(expirationTime)
|
||||
.build());
|
||||
earlierHistoryEntry =
|
||||
persistResource(
|
||||
new DomainHistory.Builder()
|
||||
.setType(DOMAIN_CREATE)
|
||||
.setDomain(domain)
|
||||
.setModificationTime(clock.nowUtc())
|
||||
.setRegistrarId(domain.getCreationRegistrarId())
|
||||
.build());
|
||||
}
|
||||
|
||||
private void setUpSuccessfulTest() throws Exception {
|
||||
createReferencedEntities(A_MONTH_FROM_NOW);
|
||||
BillingRecurrence autorenewBillingEvent =
|
||||
persistResource(createAutorenewBillingEvent("TheRegistrar").build());
|
||||
PollMessage.Autorenew autorenewPollMessage =
|
||||
persistResource(createAutorenewPollMessage("TheRegistrar").build());
|
||||
|
||||
domain =
|
||||
persistResource(
|
||||
domain
|
||||
.asBuilder()
|
||||
.setAutorenewBillingEvent(autorenewBillingEvent.createVKey())
|
||||
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
|
||||
.build());
|
||||
|
||||
assertMutatingFlow(true);
|
||||
}
|
||||
|
||||
private void doSuccessfulTest_noAddGracePeriod(String responseFilename) throws Exception {
|
||||
doSuccessfulTest_noAddGracePeriod(responseFilename, ImmutableMap.of());
|
||||
}
|
||||
|
||||
private void doSuccessfulTest_noAddGracePeriod(
|
||||
String responseFilename, Map<String, String> substitutions) throws Exception {
|
||||
// Persist the billing event so it can be retrieved for cancellation generation and checking.
|
||||
setUpSuccessfulTest();
|
||||
BillingEvent renewBillingEvent =
|
||||
persistResource(createBillingEvent(Reason.RENEW, Money.of(USD, 456)));
|
||||
setUpGracePeriods(
|
||||
GracePeriod.forBillingEvent(GracePeriodStatus.RENEW, domain.getRepoId(), renewBillingEvent),
|
||||
// This grace period has no associated billing event, so it won't cause a cancellation.
|
||||
GracePeriod.create(
|
||||
GracePeriodStatus.TRANSFER,
|
||||
domain.getRepoId(),
|
||||
TIME_BEFORE_FLOW.plusDays(1),
|
||||
"NewRegistrar",
|
||||
null));
|
||||
// We should see exactly one poll message, which is for the autorenew 1 month in the future.
|
||||
assertPollMessages(createAutorenewPollMessage("TheRegistrar").build());
|
||||
DateTime expectedExpirationTime = domain.getRegistrationExpirationTime().minusYears(2);
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(loadFile(responseFilename, substitutions));
|
||||
Domain resource = reloadResourceByForeignKey();
|
||||
// Check that the domain is in the pending delete state.
|
||||
assertAboutDomains()
|
||||
.that(resource)
|
||||
.hasStatusValue(StatusValue.PENDING_DELETE)
|
||||
.and()
|
||||
.hasDeletionTime(
|
||||
clock
|
||||
.nowUtc()
|
||||
.plus(Tld.get("tld").getRedemptionGracePeriodLength())
|
||||
.plus(Tld.get("tld").getPendingDeleteLength()))
|
||||
.and()
|
||||
.hasExactlyStatusValues(StatusValue.INACTIVE, StatusValue.PENDING_DELETE)
|
||||
.and()
|
||||
.hasOneHistoryEntryEachOfTypes(DOMAIN_CREATE, DOMAIN_DELETE);
|
||||
// We leave the original expiration time unchanged; if the expiration time is before the
|
||||
// deletion time, that means once it passes the domain will experience a "phantom autorenew"
|
||||
// where the expirationTime advances and the grace period appears, but since the delete flow
|
||||
// closed the autorenew recurrences immediately, there are no other autorenew effects.
|
||||
assertAboutDomains().that(resource).hasRegistrationExpirationTime(expectedExpirationTime);
|
||||
assertLastHistoryContainsResource(resource);
|
||||
// All existing grace periods that were for billable actions should cause cancellations.
|
||||
assertAutorenewClosedAndCancellationCreatedFor(
|
||||
renewBillingEvent, getOnlyHistoryEntryOfType(resource, DOMAIN_DELETE, DomainHistory.class));
|
||||
// All existing grace periods should be gone, and a new REDEMPTION one should be added.
|
||||
assertThat(resource.getGracePeriods())
|
||||
.containsExactly(
|
||||
GracePeriod.create(
|
||||
GracePeriodStatus.REDEMPTION,
|
||||
domain.getRepoId(),
|
||||
clock.nowUtc().plus(Tld.get("tld").getRedemptionGracePeriodLength()),
|
||||
"TheRegistrar",
|
||||
null,
|
||||
resource.getGracePeriods().iterator().next().getGracePeriodId()));
|
||||
assertDeletionPollMessageFor(resource, "Domain deleted.");
|
||||
}
|
||||
|
||||
private void assertDeletionPollMessageFor(Domain domain, String expectedMessage) {
|
||||
// There should be a future poll message at the deletion time. The previous autorenew poll
|
||||
// message should now be deleted.
|
||||
assertAboutDomains().that(domain).hasDeletePollMessage();
|
||||
DateTime deletionTime = domain.getDeletionTime();
|
||||
assertThat(getPollMessages("TheRegistrar", deletionTime.minusMinutes(1))).isEmpty();
|
||||
assertThat(getPollMessages("TheRegistrar", deletionTime)).hasSize(1);
|
||||
assertThat(domain.getDeletePollMessage())
|
||||
.isEqualTo(getOnlyPollMessage("TheRegistrar").createVKey());
|
||||
PollMessage.OneTime deletePollMessage = loadByKey(domain.getDeletePollMessage());
|
||||
assertThat(deletePollMessage.getMsg()).isEqualTo(expectedMessage);
|
||||
}
|
||||
|
||||
private void setUpGracePeriods(GracePeriod... gracePeriods) {
|
||||
domain =
|
||||
persistResource(
|
||||
domain.asBuilder().setGracePeriods(ImmutableSet.copyOf(gracePeriods)).build());
|
||||
}
|
||||
|
||||
private void assertAutorenewClosedAndCancellationCreatedFor(
|
||||
BillingEvent graceBillingEvent, DomainHistory historyEntryDomainDelete) {
|
||||
assertAutorenewClosedAndCancellationCreatedFor(
|
||||
graceBillingEvent, historyEntryDomainDelete, clock.nowUtc());
|
||||
}
|
||||
|
||||
private void assertAutorenewClosedAndCancellationCreatedFor(
|
||||
BillingEvent graceBillingEvent, DomainHistory historyEntryDomainDelete, DateTime eventTime) {
|
||||
assertBillingEvents(
|
||||
createAutorenewBillingEvent("TheRegistrar").setRecurrenceEndTime(eventTime).build(),
|
||||
graceBillingEvent,
|
||||
new BillingCancellation.Builder()
|
||||
.setReason(graceBillingEvent.getReason())
|
||||
.setTargetId("example.tld")
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(eventTime)
|
||||
.setBillingTime(TIME_BEFORE_FLOW.plusDays(1))
|
||||
.setBillingEvent(graceBillingEvent.createVKey())
|
||||
.setDomainHistory(historyEntryDomainDelete)
|
||||
.build());
|
||||
}
|
||||
|
||||
private BillingRecurrence.Builder createAutorenewBillingEvent(String registrarId) {
|
||||
return new BillingRecurrence.Builder()
|
||||
.setReason(Reason.RENEW)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setTargetId("example.tld")
|
||||
.setRegistrarId(registrarId)
|
||||
.setEventTime(A_MONTH_FROM_NOW)
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setDomainHistory(earlierHistoryEntry);
|
||||
}
|
||||
|
||||
private PollMessage.Autorenew.Builder createAutorenewPollMessage(String registrarId) {
|
||||
return new PollMessage.Autorenew.Builder()
|
||||
.setTargetId("example.tld")
|
||||
.setRegistrarId(registrarId)
|
||||
.setEventTime(A_MONTH_FROM_NOW)
|
||||
.setAutorenewEndTime(END_OF_TIME)
|
||||
.setHistoryEntry(earlierHistoryEntry);
|
||||
}
|
||||
|
||||
private BillingEvent createBillingEvent(Reason reason, Money cost) {
|
||||
return new BillingEvent.Builder()
|
||||
.setReason(reason)
|
||||
.setTargetId("example.tld")
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setCost(cost)
|
||||
.setPeriodYears(2)
|
||||
.setEventTime(TIME_BEFORE_FLOW.minusDays(4))
|
||||
.setBillingTime(TIME_BEFORE_FLOW.plusDays(1))
|
||||
.setDomainHistory(earlierHistoryEntry)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void doAddGracePeriodDeleteTest(
|
||||
GracePeriodStatus gracePeriodStatus, String responseFilename) throws Exception {
|
||||
doAddGracePeriodDeleteTest(gracePeriodStatus, responseFilename, ImmutableMap.of());
|
||||
}
|
||||
|
||||
private void doAddGracePeriodDeleteTest(
|
||||
GracePeriodStatus gracePeriodStatus,
|
||||
String responseFilename,
|
||||
Map<String, String> substitutions)
|
||||
throws Exception {
|
||||
// Persist the billing event so it can be retrieved for cancellation generation and checking.
|
||||
setUpSuccessfulTest();
|
||||
BillingEvent graceBillingEvent =
|
||||
persistResource(createBillingEvent(Reason.CREATE, Money.of(USD, 123)));
|
||||
setUpGracePeriods(
|
||||
GracePeriod.forBillingEvent(gracePeriodStatus, domain.getRepoId(), graceBillingEvent));
|
||||
// We should see exactly one poll message, which is for the autorenew 1 month in the future.
|
||||
assertPollMessages(createAutorenewPollMessage("TheRegistrar").build());
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(loadFile(responseFilename, substitutions));
|
||||
// Check that the domain is fully deleted.
|
||||
assertThat(reloadResourceByForeignKey()).isNull();
|
||||
// The add grace period is for a billable action, so it should trigger a cancellation.
|
||||
assertAutorenewClosedAndCancellationCreatedFor(
|
||||
graceBillingEvent, getOnlyHistoryEntryOfType(domain, DOMAIN_DELETE, DomainHistory.class));
|
||||
assertDomainDnsRequests("example.tld");
|
||||
// There should be no poll messages. The previous autorenew poll message should now be deleted.
|
||||
assertThat(getPollMessages("TheRegistrar")).isEmpty();
|
||||
}
|
||||
|
||||
private void setUpAutorenewGracePeriod() throws Exception {
|
||||
createReferencedEntities(A_MONTH_AGO.plusYears(1));
|
||||
BillingRecurrence autorenewBillingEvent =
|
||||
persistResource(
|
||||
createAutorenewBillingEvent("TheRegistrar").setEventTime(A_MONTH_AGO).build());
|
||||
PollMessage.Autorenew autorenewPollMessage =
|
||||
persistResource(
|
||||
createAutorenewPollMessage("TheRegistrar").setEventTime(A_MONTH_AGO).build());
|
||||
domain =
|
||||
persistResource(
|
||||
domain
|
||||
.asBuilder()
|
||||
.setGracePeriods(
|
||||
ImmutableSet.of(
|
||||
GracePeriod.createForRecurrence(
|
||||
GracePeriodStatus.AUTO_RENEW,
|
||||
domain.getRepoId(),
|
||||
A_MONTH_AGO.plusDays(45),
|
||||
"TheRegistrar",
|
||||
autorenewBillingEvent.createVKey())))
|
||||
.setAutorenewBillingEvent(autorenewBillingEvent.createVKey())
|
||||
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
|
||||
.build());
|
||||
assertMutatingFlow(true);
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,6 @@ import google.registry.model.domain.Domain;
|
||||
import google.registry.model.domain.DomainHistory;
|
||||
import google.registry.model.domain.GracePeriod;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.eppcommon.ProtocolDefinition.ServiceExtension;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.model.eppcommon.Trid;
|
||||
import google.registry.model.host.Host;
|
||||
@@ -122,12 +121,8 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
||||
private static final DateTime A_MONTH_AGO = TIME_BEFORE_FLOW.minusMonths(1);
|
||||
private static final DateTime A_MONTH_FROM_NOW = TIME_BEFORE_FLOW.plusMonths(1);
|
||||
|
||||
private static final ImmutableMap<String, String> FEE_06_MAP =
|
||||
ImmutableMap.of("FEE_VERSION", "0.6", "FEE_NS", "fee");
|
||||
private static final ImmutableMap<String, String> FEE_11_MAP =
|
||||
ImmutableMap.of("FEE_VERSION", "0.11", "FEE_NS", "fee11");
|
||||
private static final ImmutableMap<String, String> FEE_12_MAP =
|
||||
ImmutableMap.of("FEE_VERSION", "0.12", "FEE_NS", "fee12");
|
||||
private static final ImmutableMap<String, String> FEE_STD_1_0_MAP =
|
||||
ImmutableMap.of("FEE_VERSION", "epp:fee-1.0", "FEE_NS", "fee1_00");
|
||||
|
||||
DomainDeleteFlowTest() {
|
||||
setEppInput("domain_delete.xml");
|
||||
@@ -396,24 +391,9 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_addGracePeriodCredit_v06() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_11.getUri());
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_12.getUri());
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_1_00.getUri());
|
||||
doAddGracePeriodDeleteTest(GracePeriodStatus.ADD, "domain_delete_response_fee.xml", FEE_06_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_addGracePeriodCredit_v11() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_12.getUri());
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_1_00.getUri());
|
||||
doAddGracePeriodDeleteTest(GracePeriodStatus.ADD, "domain_delete_response_fee.xml", FEE_11_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_addGracePeriodCredit_v12() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_1_00.getUri());
|
||||
doAddGracePeriodDeleteTest(GracePeriodStatus.ADD, "domain_delete_response_fee.xml", FEE_12_MAP);
|
||||
void testSuccess_addGracePeriodCredit_std_v1() throws Exception {
|
||||
doAddGracePeriodDeleteTest(
|
||||
GracePeriodStatus.ADD, "domain_delete_response_fee.xml", FEE_STD_1_0_MAP);
|
||||
}
|
||||
|
||||
private void doSuccessfulTest_noAddGracePeriod(String responseFilename) throws Exception {
|
||||
@@ -497,24 +477,8 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_renewGracePeriodCredit_v06() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_11.getUri());
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_12.getUri());
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_1_00.getUri());
|
||||
doSuccessfulTest_noAddGracePeriod("domain_delete_response_pending_fee.xml", FEE_06_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_renewGracePeriodCredit_v11() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_12.getUri());
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_1_00.getUri());
|
||||
doSuccessfulTest_noAddGracePeriod("domain_delete_response_pending_fee.xml", FEE_11_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_renewGracePeriodCredit_v12() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_1_00.getUri());
|
||||
doSuccessfulTest_noAddGracePeriod("domain_delete_response_pending_fee.xml", FEE_12_MAP);
|
||||
void testSuccess_renewGracePeriodCredit_std_v1() throws Exception {
|
||||
doSuccessfulTest_noAddGracePeriod("domain_delete_response_pending_fee.xml", FEE_STD_1_0_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -556,37 +520,14 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_autoRenewGracePeriod_v06() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_11.getUri());
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_12.getUri());
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_1_00.getUri());
|
||||
void testSuccess_autoRenewGracePeriod_std_v1() throws Exception {
|
||||
setUpAutorenewGracePeriod();
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(loadFile("domain_delete_response_autorenew_fee.xml", FEE_06_MAP));
|
||||
runFlowAssertResponse(loadFile("domain_delete_response_autorenew_fee.xml", FEE_STD_1_0_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_autoRenewGracePeriod_v11() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_12.getUri());
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_1_00.getUri());
|
||||
setUpAutorenewGracePeriod();
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(loadFile("domain_delete_response_autorenew_fee.xml", FEE_11_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_autoRenewGracePeriod_v12() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_1_00.getUri());
|
||||
setUpAutorenewGracePeriod();
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(loadFile("domain_delete_response_autorenew_fee.xml", FEE_12_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_autoRenewGracePeriod_priceChanges_v06() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_11.getUri());
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_12.getUri());
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_1_00.getUri());
|
||||
void testSuccess_autoRenewGracePeriod_priceChanges_std_v1() throws Exception {
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
@@ -599,44 +540,7 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
||||
.build());
|
||||
setUpAutorenewGracePeriod();
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(loadFile("domain_delete_response_autorenew_fee.xml", FEE_06_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_autoRenewGracePeriod_priceChanges_v11() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_0_12.getUri());
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_1_00.getUri());
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setRenewBillingCostTransitions(
|
||||
ImmutableSortedMap.of(
|
||||
START_OF_TIME,
|
||||
Money.of(USD, 11),
|
||||
TIME_BEFORE_FLOW.minusDays(5),
|
||||
Money.of(USD, 20)))
|
||||
.build());
|
||||
setUpAutorenewGracePeriod();
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(loadFile("domain_delete_response_autorenew_fee.xml", FEE_11_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_autoRenewGracePeriod_priceChanges_v12() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_1_00.getUri());
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setRenewBillingCostTransitions(
|
||||
ImmutableSortedMap.of(
|
||||
START_OF_TIME,
|
||||
Money.of(USD, 11),
|
||||
TIME_BEFORE_FLOW.minusDays(5),
|
||||
Money.of(USD, 20)))
|
||||
.build());
|
||||
setUpAutorenewGracePeriod();
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(loadFile("domain_delete_response_autorenew_fee.xml", FEE_12_MAP));
|
||||
runFlowAssertResponse(loadFile("domain_delete_response_autorenew_fee.xml", FEE_STD_1_0_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1296,7 +1200,6 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
||||
|
||||
@Test
|
||||
void testSuccess_freeCreation_deletionDuringGracePeriod() throws Exception {
|
||||
removeServiceExtensionUri(ServiceExtension.FEE_1_00.getUri());
|
||||
// Deletion during the add grace period should still work even if the credit is 0
|
||||
setUpSuccessfulTest();
|
||||
BillingEvent graceBillingEvent =
|
||||
@@ -1304,7 +1207,7 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
||||
setUpGracePeriods(
|
||||
GracePeriod.forBillingEvent(GracePeriodStatus.ADD, domain.getRepoId(), graceBillingEvent));
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(loadFile("domain_delete_response_fee_free_grace.xml"));
|
||||
runFlowAssertResponse(loadFile("domain_delete_response_fee_free_grace_stdv1.xml"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,523 @@
|
||||
// Copyright 2026 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.flows.domain;
|
||||
|
||||
import static google.registry.model.billing.BillingBase.RenewalPriceBehavior.DEFAULT;
|
||||
import static google.registry.model.billing.BillingBase.RenewalPriceBehavior.NONPREMIUM;
|
||||
import static google.registry.model.billing.BillingBase.RenewalPriceBehavior.SPECIFIED;
|
||||
import static google.registry.testing.DatabaseHelper.assertNoBillingEvents;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveHost;
|
||||
import static google.registry.testing.DatabaseHelper.persistBillingRecurrenceForDomain;
|
||||
import static google.registry.testing.DatabaseHelper.persistPremiumList;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.EppExceptionSubject.assertAboutEppExceptions;
|
||||
import static google.registry.testing.TestDataHelper.updateSubstitutions;
|
||||
import static org.joda.money.CurrencyUnit.USD;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import google.registry.flows.EppException;
|
||||
import google.registry.flows.FlowUtils.UnknownCurrencyEppException;
|
||||
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.BillingBase.RenewalPriceBehavior;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.domain.DomainAuthInfo;
|
||||
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.model.host.Host;
|
||||
import google.registry.model.tld.Tld;
|
||||
import google.registry.persistence.transaction.JpaTransactionManagerExtension;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nullable;
|
||||
import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Tests for {@link DomainInfoFlow} that use the old fee extensions (0.6, 0.11, 0.12). */
|
||||
public class DomainInfoFlowOldFeeExtensionsTest
|
||||
extends ProductionSimulatingFeeExtensionsTest<DomainInfoFlow> {
|
||||
|
||||
/**
|
||||
* The domain_info_fee.xml default substitutions common to most tests.
|
||||
*
|
||||
* <p>It doesn't set a default value to the COMMAND and PERIOD keys, because they are different in
|
||||
* every test.
|
||||
*/
|
||||
private static final ImmutableMap<String, String> SUBSTITUTION_BASE =
|
||||
ImmutableMap.of(
|
||||
"NAME", "example.tld",
|
||||
"CURRENCY", "USD",
|
||||
"UNIT", "y");
|
||||
|
||||
private static final Pattern OK_PATTERN = Pattern.compile("\"ok\"");
|
||||
|
||||
private Host host1;
|
||||
private Host host2;
|
||||
private Host host3;
|
||||
private Domain domain;
|
||||
|
||||
@BeforeEach
|
||||
void beforeEachDomainInfoFlowOldFeeExtensionsTest() {
|
||||
setEppInput("domain_info.xml");
|
||||
clock.setTo(DateTime.parse("2005-03-03T22:00:00.000Z"));
|
||||
sessionMetadata.setRegistrarId("NewRegistrar");
|
||||
createTld("tld");
|
||||
persistResource(
|
||||
JpaTransactionManagerExtension.makeRegistrar1()
|
||||
.asBuilder()
|
||||
.setRegistrarId("ClientZ")
|
||||
.build());
|
||||
}
|
||||
|
||||
private void persistTestEntities(String domainName, boolean inactive) {
|
||||
host1 = persistActiveHost("ns1.example.tld");
|
||||
host2 = persistActiveHost("ns1.example.net");
|
||||
domain =
|
||||
persistResource(
|
||||
new Domain.Builder()
|
||||
.setDomainName(domainName)
|
||||
.setRepoId("2FF-TLD")
|
||||
.setPersistedCurrentSponsorRegistrarId("NewRegistrar")
|
||||
.setCreationRegistrarId("TheRegistrar")
|
||||
.setLastEppUpdateRegistrarId("NewRegistrar")
|
||||
.setCreationTimeForTest(DateTime.parse("1999-04-03T22:00:00.0Z"))
|
||||
.setLastEppUpdateTime(DateTime.parse("1999-12-03T09:00:00.0Z"))
|
||||
.setLastTransferTime(DateTime.parse("2000-04-08T09:00:00.0Z"))
|
||||
.setRegistrationExpirationTime(DateTime.parse("2005-04-03T22:00:00.0Z"))
|
||||
.setNameservers(
|
||||
inactive ? null : ImmutableSet.of(host1.createVKey(), host2.createVKey()))
|
||||
.setAuthInfo(DomainAuthInfo.create(PasswordAuth.create("2fooBAR")))
|
||||
.build());
|
||||
// Set the superordinate domain of ns1.example.com to example.com. In reality, this would have
|
||||
// happened in the flow that created it, but here we just overwrite it in the database.
|
||||
host1 = persistResource(host1.asBuilder().setSuperordinateDomain(domain.createVKey()).build());
|
||||
// Create a subordinate host that is not delegated to by anyone.
|
||||
host3 =
|
||||
persistResource(
|
||||
new Host.Builder()
|
||||
.setHostName("ns2.example.tld")
|
||||
.setRepoId("3FF-TLD")
|
||||
.setSuperordinateDomain(domain.createVKey())
|
||||
.build());
|
||||
// Add the subordinate host keys to the existing domain.
|
||||
domain =
|
||||
persistResource(
|
||||
domain
|
||||
.asBuilder()
|
||||
.setSubordinateHosts(ImmutableSet.of(host1.getHostName(), host3.getHostName()))
|
||||
.build());
|
||||
}
|
||||
|
||||
private void persistTestEntities(boolean inactive) {
|
||||
persistTestEntities("example.tld", inactive);
|
||||
}
|
||||
|
||||
private void doSuccessfulTest(
|
||||
String expectedXmlFilename,
|
||||
boolean inactive,
|
||||
ImmutableMap<String, String> substitutions,
|
||||
boolean expectHistoryAndBilling)
|
||||
throws Exception {
|
||||
assertMutatingFlow(true);
|
||||
String expected =
|
||||
loadFile(expectedXmlFilename, updateSubstitutions(substitutions, "ROID", "2FF-TLD"));
|
||||
if (inactive) {
|
||||
expected = OK_PATTERN.matcher(expected).replaceAll("\"inactive\"");
|
||||
}
|
||||
runFlowAssertResponse(expected);
|
||||
if (!expectHistoryAndBilling) {
|
||||
assertNoHistory();
|
||||
assertNoBillingEvents();
|
||||
}
|
||||
}
|
||||
|
||||
private void doSuccessfulTest(String expectedXmlFilename, boolean inactive) throws Exception {
|
||||
doSuccessfulTest(expectedXmlFilename, inactive, ImmutableMap.of(), false);
|
||||
}
|
||||
|
||||
private void doSuccessfulTest(String expectedXmlFilename) throws Exception {
|
||||
persistTestEntities(false);
|
||||
doSuccessfulTest(expectedXmlFilename, false);
|
||||
}
|
||||
|
||||
private void doSuccessfulTestNoNameservers(String expectedXmlFilename) throws Exception {
|
||||
persistTestEntities(true);
|
||||
doSuccessfulTest(expectedXmlFilename, true);
|
||||
}
|
||||
|
||||
/** sets up a sample recurring billing event as part of the domain creation process. */
|
||||
private void setUpBillingEventForExistingDomain() {
|
||||
setUpBillingEventForExistingDomain(DEFAULT, null);
|
||||
}
|
||||
|
||||
private void setUpBillingEventForExistingDomain(
|
||||
RenewalPriceBehavior renewalPriceBehavior, @Nullable Money renewalPrice) {
|
||||
domain = persistBillingRecurrenceForDomain(domain, renewalPriceBehavior, renewalPrice);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFeeExtension_restoreCommand_pendingDelete_withRenewal() throws Exception {
|
||||
createTld("example");
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(
|
||||
SUBSTITUTION_BASE, "NAME", "rich.example", "COMMAND", "restore", "PERIOD", "1"));
|
||||
persistTestEntities("rich.example", false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
persistResource(
|
||||
domain
|
||||
.asBuilder()
|
||||
.setDeletionTime(clock.nowUtc().plusDays(25))
|
||||
.setRegistrationExpirationTime(clock.nowUtc().minusDays(1))
|
||||
.setStatusValues(ImmutableSet.of(StatusValue.PENDING_DELETE))
|
||||
.build());
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_restore_response_with_renewal.xml", false, ImmutableMap.of(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test create command. Fee extension version 6 is the only one which supports fee extensions on
|
||||
* info commands and responses, so we don't need to test the other versions.
|
||||
*/
|
||||
@Test
|
||||
void testFeeExtension_createCommand() throws Exception {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "create", "PERIOD", "2"));
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_response.xml",
|
||||
false,
|
||||
ImmutableMap.of(
|
||||
"COMMAND", "create",
|
||||
"DESCRIPTION", "create",
|
||||
"PERIOD", "2",
|
||||
"FEE", "24.00"),
|
||||
true);
|
||||
}
|
||||
|
||||
/** Test renew command. */
|
||||
@Test
|
||||
void testFeeExtension_renewCommand() throws Exception {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "renew", "PERIOD", "2"));
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_response.xml",
|
||||
false,
|
||||
ImmutableMap.of(
|
||||
"COMMAND", "renew",
|
||||
"DESCRIPTION", "renew",
|
||||
"PERIOD", "2",
|
||||
"FEE", "22.00"),
|
||||
true);
|
||||
}
|
||||
|
||||
/** Test transfer command. */
|
||||
@Test
|
||||
void testFeeExtension_transferCommand() throws Exception {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "transfer", "PERIOD", "1"));
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_response.xml",
|
||||
false,
|
||||
ImmutableMap.of(
|
||||
"COMMAND", "transfer",
|
||||
"DESCRIPTION", "renew",
|
||||
"PERIOD", "1",
|
||||
"FEE", "11.00"),
|
||||
true);
|
||||
}
|
||||
|
||||
/** Test restore command. */
|
||||
@Test
|
||||
void testFeeExtension_restoreCommand() throws Exception {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "restore", "PERIOD", "1"));
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
doSuccessfulTest("domain_info_fee_restore_response.xml", false, ImmutableMap.of(), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFeeExtension_restoreCommand_pendingDelete_noRenewal() throws Exception {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "restore", "PERIOD", "1"));
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
persistResource(
|
||||
domain
|
||||
.asBuilder()
|
||||
.setDeletionTime(clock.nowUtc().plusDays(25))
|
||||
.setStatusValues(ImmutableSet.of(StatusValue.PENDING_DELETE))
|
||||
.build());
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_restore_response_no_renewal.xml", false, ImmutableMap.of(), true);
|
||||
}
|
||||
|
||||
/** Test create command on a premium label. */
|
||||
@Test
|
||||
void testFeeExtension_createCommandPremium() throws Exception {
|
||||
createTld("example");
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(
|
||||
SUBSTITUTION_BASE, "NAME", "rich.example", "COMMAND", "create", "PERIOD", "1"));
|
||||
persistTestEntities("rich.example", false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_premium_response.xml",
|
||||
false,
|
||||
ImmutableMap.of("COMMAND", "create", "DESCRIPTION", "create"),
|
||||
true);
|
||||
}
|
||||
|
||||
/** Test renew command on a premium label. */
|
||||
@Test
|
||||
void testFeeExtension_renewCommandPremium() throws Exception {
|
||||
createTld("example");
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(
|
||||
SUBSTITUTION_BASE, "NAME", "rich.example", "COMMAND", "renew", "PERIOD", "1"));
|
||||
persistTestEntities("rich.example", false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_premium_response.xml",
|
||||
false,
|
||||
ImmutableMap.of("COMMAND", "renew", "DESCRIPTION", "renew"),
|
||||
true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFeeExtension_renewCommandPremium_anchorTenant() throws Exception {
|
||||
createTld("tld");
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setPremiumList(persistPremiumList("tld", USD, "example,USD 70"))
|
||||
.build());
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "renew", "PERIOD", "1"));
|
||||
persistTestEntities("example.tld", false);
|
||||
setUpBillingEventForExistingDomain(NONPREMIUM, null);
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_response.xml",
|
||||
false,
|
||||
ImmutableMap.of("COMMAND", "renew", "DESCRIPTION", "renew", "FEE", "11.00", "PERIOD", "1"),
|
||||
true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFeeExtension_renewCommandPremium_internalRegistration() throws Exception {
|
||||
createTld("tld");
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setPremiumList(persistPremiumList("tld", USD, "example,USD 70"))
|
||||
.build());
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "renew", "PERIOD", "1"));
|
||||
persistTestEntities("example.tld", false);
|
||||
setUpBillingEventForExistingDomain(SPECIFIED, Money.of(USD, 3));
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_response.xml",
|
||||
false,
|
||||
ImmutableMap.of("COMMAND", "renew", "DESCRIPTION", "renew", "FEE", "3.00", "PERIOD", "1"),
|
||||
true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFeeExtension_renewCommandPremium_anchorTenant_multiYear() throws Exception {
|
||||
createTld("tld");
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setPremiumList(persistPremiumList("tld", USD, "example,USD 70"))
|
||||
.build());
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "renew", "PERIOD", "3"));
|
||||
persistTestEntities("example.tld", false);
|
||||
setUpBillingEventForExistingDomain(NONPREMIUM, null);
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_response.xml",
|
||||
false,
|
||||
ImmutableMap.of("COMMAND", "renew", "DESCRIPTION", "renew", "FEE", "33.00", "PERIOD", "3"),
|
||||
true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFeeExtension_renewCommandPremium_internalRegistration_multiYear() throws Exception {
|
||||
createTld("tld");
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setPremiumList(persistPremiumList("tld", USD, "example,USD 70"))
|
||||
.build());
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "renew", "PERIOD", "3"));
|
||||
persistTestEntities("example.tld", false);
|
||||
setUpBillingEventForExistingDomain(SPECIFIED, Money.of(USD, 3));
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_response.xml",
|
||||
false,
|
||||
ImmutableMap.of("COMMAND", "renew", "DESCRIPTION", "renew", "FEE", "9.00", "PERIOD", "3"),
|
||||
true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFeeExtension_renewCommandStandard_internalRegistration() throws Exception {
|
||||
createTld("tld");
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "renew", "PERIOD", "1"));
|
||||
persistTestEntities("example.tld", false);
|
||||
setUpBillingEventForExistingDomain(SPECIFIED, Money.of(USD, 3));
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_response.xml",
|
||||
false,
|
||||
ImmutableMap.of("COMMAND", "renew", "DESCRIPTION", "renew", "FEE", "3.00", "PERIOD", "1"),
|
||||
true);
|
||||
}
|
||||
|
||||
/** Test transfer command on a premium label. */
|
||||
@Test
|
||||
void testFeeExtension_transferCommandPremium() throws Exception {
|
||||
createTld("example");
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(
|
||||
SUBSTITUTION_BASE, "NAME", "rich.example", "COMMAND", "transfer", "PERIOD", "1"));
|
||||
persistTestEntities("rich.example", false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_premium_response.xml",
|
||||
false,
|
||||
ImmutableMap.of("COMMAND", "transfer", "DESCRIPTION", "renew"),
|
||||
true);
|
||||
}
|
||||
|
||||
/** Test restore command on a premium label. */
|
||||
@Test
|
||||
void testFeeExtension_restoreCommandPremium() throws Exception {
|
||||
createTld("example");
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(
|
||||
SUBSTITUTION_BASE, "NAME", "rich.example", "COMMAND", "restore", "PERIOD", "1"));
|
||||
persistTestEntities("rich.example", false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_restore_premium_response.xml", false, ImmutableMap.of(), true);
|
||||
}
|
||||
|
||||
/** Test setting the currency explicitly to a wrong value. */
|
||||
@Test
|
||||
void testFeeExtension_wrongCurrency() {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(
|
||||
SUBSTITUTION_BASE, "COMMAND", "create", "CURRENCY", "EUR", "PERIOD", "1"));
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
EppException thrown = assertThrows(CurrencyUnitMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
/** Test requesting a period that isn't in years. */
|
||||
@Test
|
||||
void testFeeExtension_periodNotInYears() {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "create", "PERIOD", "2", "UNIT", "m"));
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
EppException thrown = assertThrows(BadPeriodUnitException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
/** Test a command that specifies a phase. */
|
||||
@Test
|
||||
void testFeeExtension_commandPhase() {
|
||||
setEppInput("domain_info_fee_command_phase.xml");
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
EppException thrown = assertThrows(FeeChecksDontSupportPhasesException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
/** Test a command that specifies a subphase. */
|
||||
@Test
|
||||
void testFeeExtension_commandSubphase() {
|
||||
setEppInput("domain_info_fee_command_subphase.xml");
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
EppException thrown = assertThrows(FeeChecksDontSupportPhasesException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
/** Test a restore for more than one year. */
|
||||
@Test
|
||||
void testFeeExtension_multiyearRestore() {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "restore", "PERIOD", "2"));
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
EppException thrown = assertThrows(RestoresAreAlwaysForOneYearException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
/** Test a transfer for more than one year. */
|
||||
@Test
|
||||
void testFeeExtension_multiyearTransfer() {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "transfer", "PERIOD", "2"));
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
EppException thrown = assertThrows(TransfersAreAlwaysForOneYearException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFeeExtension_unknownCurrency() {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(
|
||||
SUBSTITUTION_BASE, "COMMAND", "create", "CURRENCY", "BAD", "PERIOD", "1"));
|
||||
EppException thrown = assertThrows(UnknownCurrencyEppException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
}
|
||||
@@ -17,15 +17,12 @@ package google.registry.flows.domain;
|
||||
import static com.google.common.io.BaseEncoding.base16;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.billing.BillingBase.RenewalPriceBehavior.DEFAULT;
|
||||
import static google.registry.model.billing.BillingBase.RenewalPriceBehavior.NONPREMIUM;
|
||||
import static google.registry.model.billing.BillingBase.RenewalPriceBehavior.SPECIFIED;
|
||||
import static google.registry.model.eppcommon.EppXmlTransformer.marshal;
|
||||
import static google.registry.model.tld.Tld.TldState.QUIET_PERIOD;
|
||||
import static google.registry.testing.DatabaseHelper.assertNoBillingEvents;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveHost;
|
||||
import static google.registry.testing.DatabaseHelper.persistBillingRecurrenceForDomain;
|
||||
import static google.registry.testing.DatabaseHelper.persistPremiumList;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.EppExceptionSubject.assertAboutEppExceptions;
|
||||
import static google.registry.testing.TestDataHelper.updateSubstitutions;
|
||||
@@ -41,15 +38,9 @@ import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import google.registry.flows.EppException;
|
||||
import google.registry.flows.FlowUtils.NotLoggedInException;
|
||||
import google.registry.flows.FlowUtils.UnknownCurrencyEppException;
|
||||
import google.registry.flows.ResourceFlowTestCase;
|
||||
import google.registry.flows.ResourceFlowUtils.BadAuthInfoForResourceException;
|
||||
import google.registry.flows.ResourceFlowUtils.ResourceDoesNotExistException;
|
||||
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.BillingBase.Flag;
|
||||
import google.registry.model.billing.BillingBase.Reason;
|
||||
import google.registry.model.billing.BillingBase.RenewalPriceBehavior;
|
||||
@@ -586,353 +577,6 @@ class DomainInfoFlowTest extends ResourceFlowTestCase<DomainInfoFlow, Domain> {
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test create command. Fee extension version 6 is the only one which supports fee extensions on
|
||||
* info commands and responses, so we don't need to test the other versions.
|
||||
*/
|
||||
@Test
|
||||
void testFeeExtension_createCommand() throws Exception {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "create", "PERIOD", "2"));
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_response.xml",
|
||||
false,
|
||||
ImmutableMap.of(
|
||||
"COMMAND", "create",
|
||||
"DESCRIPTION", "create",
|
||||
"PERIOD", "2",
|
||||
"FEE", "24.00"),
|
||||
true);
|
||||
}
|
||||
|
||||
/** Test renew command. */
|
||||
@Test
|
||||
void testFeeExtension_renewCommand() throws Exception {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "renew", "PERIOD", "2"));
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_response.xml",
|
||||
false,
|
||||
ImmutableMap.of(
|
||||
"COMMAND", "renew",
|
||||
"DESCRIPTION", "renew",
|
||||
"PERIOD", "2",
|
||||
"FEE", "22.00"),
|
||||
true);
|
||||
}
|
||||
|
||||
/** Test transfer command. */
|
||||
@Test
|
||||
void testFeeExtension_transferCommand() throws Exception {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "transfer", "PERIOD", "1"));
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_response.xml",
|
||||
false,
|
||||
ImmutableMap.of(
|
||||
"COMMAND", "transfer",
|
||||
"DESCRIPTION", "renew",
|
||||
"PERIOD", "1",
|
||||
"FEE", "11.00"),
|
||||
true);
|
||||
}
|
||||
|
||||
/** Test restore command. */
|
||||
@Test
|
||||
void testFeeExtension_restoreCommand() throws Exception {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "restore", "PERIOD", "1"));
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
doSuccessfulTest("domain_info_fee_restore_response.xml", false, ImmutableMap.of(), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFeeExtension_restoreCommand_pendingDelete_noRenewal() throws Exception {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "restore", "PERIOD", "1"));
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
persistResource(
|
||||
domain
|
||||
.asBuilder()
|
||||
.setDeletionTime(clock.nowUtc().plusDays(25))
|
||||
.setStatusValues(ImmutableSet.of(StatusValue.PENDING_DELETE))
|
||||
.build());
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_restore_response_no_renewal.xml", false, ImmutableMap.of(), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFeeExtension_restoreCommand_pendingDelete_withRenewal() throws Exception {
|
||||
createTld("example");
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(
|
||||
SUBSTITUTION_BASE, "NAME", "rich.example", "COMMAND", "restore", "PERIOD", "1"));
|
||||
persistTestEntities("rich.example", false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
persistResource(
|
||||
domain
|
||||
.asBuilder()
|
||||
.setDeletionTime(clock.nowUtc().plusDays(25))
|
||||
.setRegistrationExpirationTime(clock.nowUtc().minusDays(1))
|
||||
.setStatusValues(ImmutableSet.of(StatusValue.PENDING_DELETE))
|
||||
.build());
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_restore_response_with_renewal.xml", false, ImmutableMap.of(), true);
|
||||
}
|
||||
|
||||
/** Test create command on a premium label. */
|
||||
@Test
|
||||
void testFeeExtension_createCommandPremium() throws Exception {
|
||||
createTld("example");
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(
|
||||
SUBSTITUTION_BASE, "NAME", "rich.example", "COMMAND", "create", "PERIOD", "1"));
|
||||
persistTestEntities("rich.example", false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_premium_response.xml",
|
||||
false,
|
||||
ImmutableMap.of("COMMAND", "create", "DESCRIPTION", "create"),
|
||||
true);
|
||||
}
|
||||
|
||||
/** Test renew command on a premium label. */
|
||||
@Test
|
||||
void testFeeExtension_renewCommandPremium() throws Exception {
|
||||
createTld("example");
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(
|
||||
SUBSTITUTION_BASE, "NAME", "rich.example", "COMMAND", "renew", "PERIOD", "1"));
|
||||
persistTestEntities("rich.example", false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_premium_response.xml",
|
||||
false,
|
||||
ImmutableMap.of("COMMAND", "renew", "DESCRIPTION", "renew"),
|
||||
true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFeeExtension_renewCommandPremium_anchorTenant() throws Exception {
|
||||
createTld("tld");
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setPremiumList(persistPremiumList("tld", USD, "example,USD 70"))
|
||||
.build());
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "renew", "PERIOD", "1"));
|
||||
persistTestEntities("example.tld", false);
|
||||
setUpBillingEventForExistingDomain(NONPREMIUM, null);
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_response.xml",
|
||||
false,
|
||||
ImmutableMap.of("COMMAND", "renew", "DESCRIPTION", "renew", "FEE", "11.00", "PERIOD", "1"),
|
||||
true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFeeExtension_renewCommandPremium_internalRegistration() throws Exception {
|
||||
createTld("tld");
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setPremiumList(persistPremiumList("tld", USD, "example,USD 70"))
|
||||
.build());
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "renew", "PERIOD", "1"));
|
||||
persistTestEntities("example.tld", false);
|
||||
setUpBillingEventForExistingDomain(SPECIFIED, Money.of(USD, 3));
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_response.xml",
|
||||
false,
|
||||
ImmutableMap.of("COMMAND", "renew", "DESCRIPTION", "renew", "FEE", "3.00", "PERIOD", "1"),
|
||||
true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFeeExtension_renewCommandPremium_anchorTenant_multiYear() throws Exception {
|
||||
createTld("tld");
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setPremiumList(persistPremiumList("tld", USD, "example,USD 70"))
|
||||
.build());
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "renew", "PERIOD", "3"));
|
||||
persistTestEntities("example.tld", false);
|
||||
setUpBillingEventForExistingDomain(NONPREMIUM, null);
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_response.xml",
|
||||
false,
|
||||
ImmutableMap.of("COMMAND", "renew", "DESCRIPTION", "renew", "FEE", "33.00", "PERIOD", "3"),
|
||||
true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFeeExtension_renewCommandPremium_internalRegistration_multiYear() throws Exception {
|
||||
createTld("tld");
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setPremiumList(persistPremiumList("tld", USD, "example,USD 70"))
|
||||
.build());
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "renew", "PERIOD", "3"));
|
||||
persistTestEntities("example.tld", false);
|
||||
setUpBillingEventForExistingDomain(SPECIFIED, Money.of(USD, 3));
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_response.xml",
|
||||
false,
|
||||
ImmutableMap.of("COMMAND", "renew", "DESCRIPTION", "renew", "FEE", "9.00", "PERIOD", "3"),
|
||||
true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFeeExtension_renewCommandStandard_internalRegistration() throws Exception {
|
||||
createTld("tld");
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "renew", "PERIOD", "1"));
|
||||
persistTestEntities("example.tld", false);
|
||||
setUpBillingEventForExistingDomain(SPECIFIED, Money.of(USD, 3));
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_response.xml",
|
||||
false,
|
||||
ImmutableMap.of("COMMAND", "renew", "DESCRIPTION", "renew", "FEE", "3.00", "PERIOD", "1"),
|
||||
true);
|
||||
}
|
||||
|
||||
/** Test transfer command on a premium label. */
|
||||
@Test
|
||||
void testFeeExtension_transferCommandPremium() throws Exception {
|
||||
createTld("example");
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(
|
||||
SUBSTITUTION_BASE, "NAME", "rich.example", "COMMAND", "transfer", "PERIOD", "1"));
|
||||
persistTestEntities("rich.example", false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_premium_response.xml",
|
||||
false,
|
||||
ImmutableMap.of("COMMAND", "transfer", "DESCRIPTION", "renew"),
|
||||
true);
|
||||
}
|
||||
|
||||
/** Test restore command on a premium label. */
|
||||
@Test
|
||||
void testFeeExtension_restoreCommandPremium() throws Exception {
|
||||
createTld("example");
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(
|
||||
SUBSTITUTION_BASE, "NAME", "rich.example", "COMMAND", "restore", "PERIOD", "1"));
|
||||
persistTestEntities("rich.example", false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
doSuccessfulTest(
|
||||
"domain_info_fee_restore_premium_response.xml", false, ImmutableMap.of(), true);
|
||||
}
|
||||
|
||||
/** Test setting the currency explicitly to a wrong value. */
|
||||
@Test
|
||||
void testFeeExtension_wrongCurrency() {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(
|
||||
SUBSTITUTION_BASE, "COMMAND", "create", "CURRENCY", "EUR", "PERIOD", "1"));
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
EppException thrown = assertThrows(CurrencyUnitMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFeeExtension_unknownCurrency() {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(
|
||||
SUBSTITUTION_BASE, "COMMAND", "create", "CURRENCY", "BAD", "PERIOD", "1"));
|
||||
EppException thrown = assertThrows(UnknownCurrencyEppException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
/** Test requesting a period that isn't in years. */
|
||||
@Test
|
||||
void testFeeExtension_periodNotInYears() {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "create", "PERIOD", "2", "UNIT", "m"));
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
EppException thrown = assertThrows(BadPeriodUnitException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
/** Test a command that specifies a phase. */
|
||||
@Test
|
||||
void testFeeExtension_commandPhase() {
|
||||
setEppInput("domain_info_fee_command_phase.xml");
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
EppException thrown = assertThrows(FeeChecksDontSupportPhasesException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
/** Test a command that specifies a subphase. */
|
||||
@Test
|
||||
void testFeeExtension_commandSubphase() {
|
||||
setEppInput("domain_info_fee_command_subphase.xml");
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
EppException thrown = assertThrows(FeeChecksDontSupportPhasesException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
/** Test a restore for more than one year. */
|
||||
@Test
|
||||
void testFeeExtension_multiyearRestore() {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "restore", "PERIOD", "2"));
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
EppException thrown = assertThrows(RestoresAreAlwaysForOneYearException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
/** Test a transfer for more than one year. */
|
||||
@Test
|
||||
void testFeeExtension_multiyearTransfer() {
|
||||
setEppInput(
|
||||
"domain_info_fee.xml",
|
||||
updateSubstitutions(SUBSTITUTION_BASE, "COMMAND", "transfer", "PERIOD", "2"));
|
||||
persistTestEntities(false);
|
||||
setUpBillingEventForExistingDomain();
|
||||
EppException thrown = assertThrows(TransfersAreAlwaysForOneYearException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIcannActivityReportField_getsLogged() throws Exception {
|
||||
persistTestEntities(false);
|
||||
|
||||
@@ -0,0 +1,827 @@
|
||||
// Copyright 2026 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.flows.domain;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.billing.BillingBase.RenewalPriceBehavior.DEFAULT;
|
||||
import static google.registry.model.billing.BillingBase.RenewalPriceBehavior.NONPREMIUM;
|
||||
import static google.registry.model.billing.BillingBase.RenewalPriceBehavior.SPECIFIED;
|
||||
import static google.registry.model.domain.token.AllocationToken.TokenType.DEFAULT_PROMO;
|
||||
import static google.registry.testing.DatabaseHelper.assertBillingEvents;
|
||||
import static google.registry.testing.DatabaseHelper.assertPollMessages;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.getOnlyHistoryEntryOfType;
|
||||
import static google.registry.testing.DatabaseHelper.loadByKey;
|
||||
import static google.registry.testing.DatabaseHelper.loadRegistrar;
|
||||
import static google.registry.testing.DatabaseHelper.persistPremiumList;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.DatabaseHelper.persistResources;
|
||||
import static google.registry.testing.DomainSubject.assertAboutDomains;
|
||||
import static google.registry.testing.EppExceptionSubject.assertAboutEppExceptions;
|
||||
import static google.registry.testing.HistoryEntrySubject.assertAboutHistoryEntries;
|
||||
import static google.registry.testing.TestDataHelper.updateSubstitutions;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
import static org.joda.money.CurrencyUnit.EUR;
|
||||
import static org.joda.money.CurrencyUnit.USD;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import google.registry.flows.EppException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.CurrencyUnitMismatchException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.CurrencyValueScaleException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.FeesMismatchException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.UnsupportedFeeAttributeException;
|
||||
import google.registry.model.billing.BillingBase.Flag;
|
||||
import google.registry.model.billing.BillingBase.Reason;
|
||||
import google.registry.model.billing.BillingBase.RenewalPriceBehavior;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.billing.BillingRecurrence;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.domain.DomainHistory;
|
||||
import google.registry.model.domain.GracePeriod;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.domain.token.AllocationToken;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.model.poll.PollMessage;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.tld.Tld;
|
||||
import google.registry.testing.DatabaseHelper;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Tests for {@link DomainRenewFlow} that use the old fee extensions (0.6, 0.11, 0.12). */
|
||||
public class DomainRenewFlowOldFeeExtensionsTest
|
||||
extends ProductionSimulatingFeeExtensionsTest<DomainRenewFlow> {
|
||||
|
||||
private static final ImmutableMap<String, String> FEE_BASE_MAP =
|
||||
ImmutableMap.of(
|
||||
"NAME", "example.tld",
|
||||
"PERIOD", "5",
|
||||
"EX_DATE", "2005-04-03T22:00:00.0Z",
|
||||
"FEE", "55.00",
|
||||
"CURRENCY", "USD");
|
||||
|
||||
private static final ImmutableMap<String, String> FEE_06_MAP =
|
||||
updateSubstitutions(FEE_BASE_MAP, "FEE_VERSION", "fee-0.6", "FEE_NS", "fee");
|
||||
private static final ImmutableMap<String, String> FEE_11_MAP =
|
||||
updateSubstitutions(FEE_BASE_MAP, "FEE_VERSION", "fee-0.11", "FEE_NS", "fee11");
|
||||
private static final ImmutableMap<String, String> FEE_12_MAP =
|
||||
updateSubstitutions(FEE_BASE_MAP, "FEE_VERSION", "fee-0.12", "FEE_NS", "fee12");
|
||||
|
||||
private final DateTime expirationTime = DateTime.parse("2000-04-03T22:00:00.0Z");
|
||||
|
||||
@BeforeEach
|
||||
void beforeEachDomainRenewFlowOldFeeExtensionsTest() {
|
||||
clock.setTo(expirationTime.minusMillis(20));
|
||||
createTld("tld");
|
||||
persistResource(
|
||||
loadRegistrar("TheRegistrar")
|
||||
.asBuilder()
|
||||
.setBillingAccountMap(ImmutableMap.of(USD, "123", EUR, "567"))
|
||||
.build());
|
||||
setEppInput("domain_renew.xml", ImmutableMap.of("DOMAIN", "example.tld", "YEARS", "5"));
|
||||
}
|
||||
|
||||
private void persistDomain(StatusValue... statusValues) throws Exception {
|
||||
persistDomain(DEFAULT, null, statusValues);
|
||||
}
|
||||
|
||||
private void persistDomain(
|
||||
RenewalPriceBehavior renewalPriceBehavior,
|
||||
@Nullable Money renewalPrice,
|
||||
StatusValue... statusValues)
|
||||
throws Exception {
|
||||
Domain domain = DatabaseHelper.newDomain(getUniqueIdFromCommand());
|
||||
try {
|
||||
DomainHistory historyEntryDomainCreate =
|
||||
new DomainHistory.Builder()
|
||||
.setDomain(domain)
|
||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||
.setModificationTime(clock.nowUtc())
|
||||
.setRegistrarId(domain.getCreationRegistrarId())
|
||||
.build();
|
||||
BillingRecurrence autorenewEvent =
|
||||
new BillingRecurrence.Builder()
|
||||
.setReason(Reason.RENEW)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setTargetId(getUniqueIdFromCommand())
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(expirationTime)
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setDomainHistory(historyEntryDomainCreate)
|
||||
.setRenewalPriceBehavior(renewalPriceBehavior)
|
||||
.setRenewalPrice(renewalPrice)
|
||||
.build();
|
||||
PollMessage.Autorenew autorenewPollMessage =
|
||||
new PollMessage.Autorenew.Builder()
|
||||
.setTargetId(getUniqueIdFromCommand())
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(expirationTime)
|
||||
.setAutorenewEndTime(END_OF_TIME)
|
||||
.setMsg("Domain was auto-renewed.")
|
||||
.setHistoryEntry(historyEntryDomainCreate)
|
||||
.build();
|
||||
Domain newDomain =
|
||||
domain
|
||||
.asBuilder()
|
||||
.setRegistrationExpirationTime(expirationTime)
|
||||
.setStatusValues(ImmutableSet.copyOf(statusValues))
|
||||
.setAutorenewBillingEvent(autorenewEvent.createVKey())
|
||||
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
|
||||
.build();
|
||||
persistResources(
|
||||
ImmutableSet.of(
|
||||
historyEntryDomainCreate, autorenewEvent,
|
||||
autorenewPollMessage, newDomain));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error persisting domain", e);
|
||||
}
|
||||
clock.advanceOneMilli();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_06_MAP);
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 20)))
|
||||
.build());
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_11_MAP);
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 20)))
|
||||
.build());
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_12_MAP);
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 20)))
|
||||
.build());
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_06_MAP);
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setCurrency(EUR)
|
||||
.setCreateBillingCostTransitions(
|
||||
ImmutableSortedMap.of(START_OF_TIME, Money.of(EUR, 13)))
|
||||
.setRestoreBillingCost(Money.of(EUR, 11))
|
||||
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(EUR, 7)))
|
||||
.setEapFeeSchedule(ImmutableSortedMap.of(START_OF_TIME, Money.zero(EUR)))
|
||||
.setRegistryLockOrUnlockBillingCost(Money.of(EUR, 20))
|
||||
.setServerStatusChangeBillingCost(Money.of(EUR, 19))
|
||||
.build());
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(CurrencyUnitMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_11_MAP);
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setCurrency(EUR)
|
||||
.setCreateBillingCostTransitions(
|
||||
ImmutableSortedMap.of(START_OF_TIME, Money.of(EUR, 13)))
|
||||
.setRestoreBillingCost(Money.of(EUR, 11))
|
||||
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(EUR, 7)))
|
||||
.setEapFeeSchedule(ImmutableSortedMap.of(START_OF_TIME, Money.zero(EUR)))
|
||||
.setRegistryLockOrUnlockBillingCost(Money.of(EUR, 20))
|
||||
.setServerStatusChangeBillingCost(Money.of(EUR, 19))
|
||||
.build());
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(CurrencyUnitMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_12_MAP);
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setCurrency(EUR)
|
||||
.setCreateBillingCostTransitions(
|
||||
ImmutableSortedMap.of(START_OF_TIME, Money.of(EUR, 13)))
|
||||
.setRestoreBillingCost(Money.of(EUR, 11))
|
||||
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(EUR, 7)))
|
||||
.setEapFeeSchedule(ImmutableSortedMap.of(START_OF_TIME, Money.zero(EUR)))
|
||||
.setRegistryLockOrUnlockBillingCost(Money.of(EUR, 20))
|
||||
.setServerStatusChangeBillingCost(Money.of(EUR, 19))
|
||||
.build());
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(CurrencyUnitMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee_bad_scale.xml", FEE_06_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(CurrencyValueScaleException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee_bad_scale.xml", FEE_11_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(CurrencyValueScaleException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee_bad_scale.xml", FEE_12_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(CurrencyValueScaleException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_doesNotApplyNonPremiumDefaultTokenToPremiumName_v06() throws Exception {
|
||||
ImmutableMap<String, String> customFeeMap = updateSubstitutions(FEE_06_MAP, "FEE", "500");
|
||||
setEppInput("domain_renew_fee.xml", customFeeMap);
|
||||
persistDomain();
|
||||
AllocationToken defaultToken1 =
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("aaaaa")
|
||||
.setTokenType(DEFAULT_PROMO)
|
||||
.setDiscountFraction(0.5)
|
||||
.setDiscountYears(1)
|
||||
.setAllowedTlds(ImmutableSet.of("tld"))
|
||||
.build());
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setDefaultPromoTokens(ImmutableList.of(defaultToken1.createVKey()))
|
||||
.setPremiumList(persistPremiumList("tld", USD, "example,USD 100"))
|
||||
.build());
|
||||
runFlowAssertResponse(
|
||||
loadFile(
|
||||
"domain_renew_response_fee.xml",
|
||||
ImmutableMap.of(
|
||||
"NAME",
|
||||
"example.tld",
|
||||
"PERIOD",
|
||||
"5",
|
||||
"EX_DATE",
|
||||
"2005-04-03T22:00:00.0Z",
|
||||
"FEE",
|
||||
"500.00",
|
||||
"CURRENCY",
|
||||
"USD",
|
||||
"FEE_VERSION",
|
||||
"fee-0.6",
|
||||
"FEE_NS",
|
||||
"fee")));
|
||||
BillingEvent billingEvent =
|
||||
Iterables.getOnlyElement(DatabaseHelper.loadAllOf(BillingEvent.class));
|
||||
assertThat(billingEvent.getTargetId()).isEqualTo("example.tld");
|
||||
assertThat(billingEvent.getAllocationToken()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_internalRegiration_premiumDomain_v06() throws Exception {
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setPremiumList(persistPremiumList("tld", USD, "example,USD 100"))
|
||||
.build());
|
||||
persistDomain(SPECIFIED, Money.of(USD, 2));
|
||||
setRegistrarIdForFlow("NewRegistrar");
|
||||
ImmutableMap<String, String> customFeeMap = updateSubstitutions(FEE_06_MAP, "FEE", "10.00");
|
||||
setEppInput("domain_renew_fee.xml", customFeeMap);
|
||||
doSuccessfulTest(
|
||||
"domain_renew_response_fee.xml",
|
||||
5,
|
||||
"NewRegistrar",
|
||||
UserPrivileges.SUPERUSER,
|
||||
customFeeMap,
|
||||
Money.of(USD, 10),
|
||||
SPECIFIED,
|
||||
Money.of(USD, 2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_wrongFeeAmountTooHigh_defaultToken_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_06_MAP);
|
||||
persistDomain();
|
||||
AllocationToken defaultToken1 =
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("aaaaa")
|
||||
.setTokenType(DEFAULT_PROMO)
|
||||
.setDiscountFraction(0.5)
|
||||
.setDiscountYears(1)
|
||||
.setAllowedTlds(ImmutableSet.of("tld"))
|
||||
.build());
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setDefaultPromoTokens(ImmutableList.of(defaultToken1.createVKey()))
|
||||
.build());
|
||||
runFlowAssertResponse(
|
||||
loadFile(
|
||||
"domain_renew_response_fee.xml",
|
||||
ImmutableMap.of(
|
||||
"NAME",
|
||||
"example.tld",
|
||||
"PERIOD",
|
||||
"5",
|
||||
"EX_DATE",
|
||||
"2005-04-03T22:00:00.0Z",
|
||||
"FEE",
|
||||
"49.50",
|
||||
"CURRENCY",
|
||||
"USD",
|
||||
"FEE_VERSION",
|
||||
"fee-0.6",
|
||||
"FEE_NS",
|
||||
"fee")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmountTooLow_defaultToken_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_06_MAP);
|
||||
persistDomain();
|
||||
AllocationToken defaultToken1 =
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("aaaaa")
|
||||
.setTokenType(DEFAULT_PROMO)
|
||||
.setDiscountFraction(0.5)
|
||||
.setDiscountYears(1)
|
||||
.setAllowedTlds(ImmutableSet.of("tld"))
|
||||
.build());
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setDefaultPromoTokens(ImmutableList.of(defaultToken1.createVKey()))
|
||||
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 20)))
|
||||
.build());
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_wrongFeeAmountTooHigh_defaultToken_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_11_MAP);
|
||||
persistDomain();
|
||||
AllocationToken defaultToken1 =
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("aaaaa")
|
||||
.setTokenType(DEFAULT_PROMO)
|
||||
.setDiscountFraction(0.5)
|
||||
.setDiscountYears(1)
|
||||
.setAllowedTlds(ImmutableSet.of("tld"))
|
||||
.build());
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setDefaultPromoTokens(ImmutableList.of(defaultToken1.createVKey()))
|
||||
.build());
|
||||
runFlowAssertResponse(
|
||||
loadFile(
|
||||
"domain_renew_response_fee.xml",
|
||||
ImmutableMap.of(
|
||||
"NAME",
|
||||
"example.tld",
|
||||
"PERIOD",
|
||||
"5",
|
||||
"EX_DATE",
|
||||
"2005-04-03T22:00:00.0Z",
|
||||
"FEE",
|
||||
"49.50",
|
||||
"CURRENCY",
|
||||
"USD",
|
||||
"FEE_VERSION",
|
||||
"fee-0.11",
|
||||
"FEE_NS",
|
||||
"fee")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmountTooLow_defaultToken_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_11_MAP);
|
||||
persistDomain();
|
||||
AllocationToken defaultToken1 =
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("aaaaa")
|
||||
.setTokenType(DEFAULT_PROMO)
|
||||
.setDiscountFraction(0.5)
|
||||
.setDiscountYears(1)
|
||||
.setAllowedTlds(ImmutableSet.of("tld"))
|
||||
.build());
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setDefaultPromoTokens(ImmutableList.of(defaultToken1.createVKey()))
|
||||
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 20)))
|
||||
.build());
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_wrongFeeAmountTooHigh_defaultToken_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_12_MAP);
|
||||
persistDomain();
|
||||
AllocationToken defaultToken1 =
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("aaaaa")
|
||||
.setTokenType(DEFAULT_PROMO)
|
||||
.setDiscountFraction(0.5)
|
||||
.setDiscountYears(1)
|
||||
.setAllowedTlds(ImmutableSet.of("tld"))
|
||||
.build());
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setDefaultPromoTokens(ImmutableList.of(defaultToken1.createVKey()))
|
||||
.build());
|
||||
runFlowAssertResponse(
|
||||
loadFile(
|
||||
"domain_renew_response_fee.xml",
|
||||
ImmutableMap.of(
|
||||
"NAME",
|
||||
"example.tld",
|
||||
"PERIOD",
|
||||
"5",
|
||||
"EX_DATE",
|
||||
"2005-04-03T22:00:00.0Z",
|
||||
"FEE",
|
||||
"49.50",
|
||||
"CURRENCY",
|
||||
"USD",
|
||||
"FEE_VERSION",
|
||||
"fee-0.12",
|
||||
"FEE_NS",
|
||||
"fee")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmountTooLow_defaultToken_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_06_MAP);
|
||||
persistDomain();
|
||||
AllocationToken defaultToken1 =
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("aaaaa")
|
||||
.setTokenType(DEFAULT_PROMO)
|
||||
.setDiscountFraction(0.5)
|
||||
.setDiscountYears(1)
|
||||
.setAllowedTlds(ImmutableSet.of("tld"))
|
||||
.build());
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setDefaultPromoTokens(ImmutableList.of(defaultToken1.createVKey()))
|
||||
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 20)))
|
||||
.build());
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee_refundable.xml", FEE_06_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee_refundable.xml", FEE_11_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee_refundable.xml", FEE_12_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee_grace_period.xml", FEE_06_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee_grace_period.xml", FEE_11_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee_grace_period.xml", FEE_12_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee_applied.xml", FEE_06_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee_applied.xml", FEE_11_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee_applied.xml", FEE_12_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_06_MAP);
|
||||
persistDomain();
|
||||
doSuccessfulTest("domain_renew_response_fee.xml", 5, FEE_06_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_11_MAP);
|
||||
persistDomain();
|
||||
doSuccessfulTest("domain_renew_response_fee.xml", 5, FEE_11_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_12_MAP);
|
||||
persistDomain();
|
||||
doSuccessfulTest("domain_renew_response_fee.xml", 5, FEE_12_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee_defaults.xml", FEE_06_MAP);
|
||||
persistDomain();
|
||||
doSuccessfulTest("domain_renew_response_fee.xml", 5, FEE_06_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee_defaults.xml", FEE_11_MAP);
|
||||
persistDomain();
|
||||
doSuccessfulTest("domain_renew_response_fee.xml", 5, FEE_11_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee_defaults.xml", FEE_12_MAP);
|
||||
persistDomain();
|
||||
doSuccessfulTest("domain_renew_response_fee.xml", 5, FEE_12_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_anchorTenant_premiumDomain_v06() throws Exception {
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setPremiumList(persistPremiumList("tld", USD, "example,USD 100"))
|
||||
.build());
|
||||
persistDomain(NONPREMIUM, null);
|
||||
setRegistrarIdForFlow("NewRegistrar");
|
||||
ImmutableMap<String, String> customFeeMap = updateSubstitutions(FEE_06_MAP, "FEE", "55.00");
|
||||
setEppInput("domain_renew_fee.xml", customFeeMap);
|
||||
doSuccessfulTest(
|
||||
"domain_renew_response_fee.xml",
|
||||
5,
|
||||
"NewRegistrar",
|
||||
UserPrivileges.SUPERUSER,
|
||||
customFeeMap,
|
||||
Money.of(USD, 55),
|
||||
NONPREMIUM,
|
||||
null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_customLogicFee_v06() throws Exception {
|
||||
// The "costly-renew" domain has an additional RENEW fee of 100 from custom logic on top of the
|
||||
// normal $11 standard renew price for this TLD.
|
||||
ImmutableMap<String, String> customFeeMap =
|
||||
updateSubstitutions(
|
||||
FEE_06_MAP,
|
||||
"NAME",
|
||||
"costly-renew.tld",
|
||||
"PERIOD",
|
||||
"1",
|
||||
"EX_DATE",
|
||||
"2001-04-03T22:00:00.0Z",
|
||||
"FEE",
|
||||
"111.00");
|
||||
setEppInput("domain_renew_fee.xml", customFeeMap);
|
||||
persistDomain();
|
||||
doSuccessfulTest(
|
||||
"domain_renew_response_fee.xml",
|
||||
1,
|
||||
"TheRegistrar",
|
||||
UserPrivileges.NORMAL,
|
||||
customFeeMap,
|
||||
Money.of(USD, 111));
|
||||
}
|
||||
|
||||
private void doSuccessfulTest(String responseFilename, int renewalYears) throws Exception {
|
||||
doSuccessfulTest(responseFilename, renewalYears, ImmutableMap.of());
|
||||
}
|
||||
|
||||
private void doSuccessfulTest(
|
||||
String responseFilename, int renewalYears, Map<String, String> substitutions)
|
||||
throws Exception {
|
||||
doSuccessfulTest(
|
||||
responseFilename,
|
||||
renewalYears,
|
||||
"TheRegistrar",
|
||||
UserPrivileges.NORMAL,
|
||||
substitutions,
|
||||
Money.of(USD, 11).multipliedBy(renewalYears),
|
||||
DEFAULT,
|
||||
null);
|
||||
}
|
||||
|
||||
private void doSuccessfulTest(
|
||||
String responseFilename,
|
||||
int renewalYears,
|
||||
String renewalClientId,
|
||||
UserPrivileges userPrivileges,
|
||||
Map<String, String> substitutions,
|
||||
Money totalRenewCost)
|
||||
throws Exception {
|
||||
doSuccessfulTest(
|
||||
responseFilename,
|
||||
renewalYears,
|
||||
renewalClientId,
|
||||
userPrivileges,
|
||||
substitutions,
|
||||
totalRenewCost,
|
||||
DEFAULT,
|
||||
null);
|
||||
}
|
||||
|
||||
private void doSuccessfulTest(
|
||||
String responseFilename,
|
||||
int renewalYears,
|
||||
String renewalClientId,
|
||||
UserPrivileges userPrivileges,
|
||||
Map<String, String> substitutions,
|
||||
Money totalRenewCost,
|
||||
RenewalPriceBehavior renewalPriceBehavior,
|
||||
@Nullable Money renewalPrice)
|
||||
throws Exception {
|
||||
assertMutatingFlow(true);
|
||||
DateTime currentExpiration = reloadResourceByForeignKey().getRegistrationExpirationTime();
|
||||
DateTime newExpiration = currentExpiration.plusYears(renewalYears);
|
||||
runFlowAssertResponse(
|
||||
CommitMode.LIVE, userPrivileges, loadFile(responseFilename, substitutions));
|
||||
Domain domain = reloadResourceByForeignKey();
|
||||
assertLastHistoryContainsResource(domain);
|
||||
DomainHistory historyEntryDomainRenew =
|
||||
getOnlyHistoryEntryOfType(domain, HistoryEntry.Type.DOMAIN_RENEW, DomainHistory.class);
|
||||
assertThat(loadByKey(domain.getAutorenewBillingEvent()).getEventTime())
|
||||
.isEqualTo(newExpiration);
|
||||
assertAboutDomains()
|
||||
.that(domain)
|
||||
.isActiveAt(clock.nowUtc())
|
||||
.and()
|
||||
.hasRegistrationExpirationTime(newExpiration)
|
||||
.and()
|
||||
.hasOneHistoryEntryEachOfTypes(
|
||||
HistoryEntry.Type.DOMAIN_CREATE, HistoryEntry.Type.DOMAIN_RENEW)
|
||||
.and()
|
||||
.hasLastEppUpdateTime(clock.nowUtc())
|
||||
.and()
|
||||
.hasLastEppUpdateRegistrarId(renewalClientId);
|
||||
assertAboutHistoryEntries().that(historyEntryDomainRenew).hasPeriodYears(renewalYears);
|
||||
BillingEvent renewBillingEvent =
|
||||
new BillingEvent.Builder()
|
||||
.setReason(Reason.RENEW)
|
||||
.setTargetId(getUniqueIdFromCommand())
|
||||
.setRegistrarId(renewalClientId)
|
||||
.setCost(totalRenewCost)
|
||||
.setPeriodYears(renewalYears)
|
||||
.setEventTime(clock.nowUtc())
|
||||
.setBillingTime(clock.nowUtc().plus(Tld.get("tld").getRenewGracePeriodLength()))
|
||||
.setDomainHistory(historyEntryDomainRenew)
|
||||
.build();
|
||||
assertBillingEvents(
|
||||
renewBillingEvent,
|
||||
new BillingRecurrence.Builder()
|
||||
.setReason(Reason.RENEW)
|
||||
.setRenewalPriceBehavior(renewalPriceBehavior)
|
||||
.setRenewalPrice(renewalPrice)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setTargetId(getUniqueIdFromCommand())
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(expirationTime)
|
||||
.setRecurrenceEndTime(clock.nowUtc())
|
||||
.setDomainHistory(
|
||||
getOnlyHistoryEntryOfType(
|
||||
domain, HistoryEntry.Type.DOMAIN_CREATE, DomainHistory.class))
|
||||
.build(),
|
||||
new BillingRecurrence.Builder()
|
||||
.setReason(Reason.RENEW)
|
||||
.setRenewalPriceBehavior(renewalPriceBehavior)
|
||||
.setRenewalPrice(renewalPrice)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setTargetId(getUniqueIdFromCommand())
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(domain.getRegistrationExpirationTime())
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setDomainHistory(historyEntryDomainRenew)
|
||||
.build());
|
||||
// There should only be the new autorenew poll message, as the old one will have been deleted
|
||||
// since it had no messages left to deliver.
|
||||
assertPollMessages(
|
||||
new PollMessage.Autorenew.Builder()
|
||||
.setTargetId(getUniqueIdFromCommand())
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(domain.getRegistrationExpirationTime())
|
||||
.setAutorenewEndTime(END_OF_TIME)
|
||||
.setMsg("Domain was auto-renewed.")
|
||||
.setHistoryEntry(historyEntryDomainRenew)
|
||||
.build());
|
||||
assertGracePeriods(
|
||||
domain.getGracePeriods(),
|
||||
ImmutableMap.of(
|
||||
GracePeriod.create(
|
||||
GracePeriodStatus.RENEW,
|
||||
domain.getRepoId(),
|
||||
clock.nowUtc().plus(Tld.get("tld").getRenewGracePeriodLength()),
|
||||
renewalClientId,
|
||||
null),
|
||||
renewBillingEvent));
|
||||
}
|
||||
}
|
||||
@@ -119,12 +119,8 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, Domain>
|
||||
"FEE", "55.00",
|
||||
"CURRENCY", "USD");
|
||||
|
||||
private static final ImmutableMap<String, String> FEE_06_MAP =
|
||||
updateSubstitutions(FEE_BASE_MAP, "FEE_VERSION", "0.6", "FEE_NS", "fee");
|
||||
private static final ImmutableMap<String, String> FEE_11_MAP =
|
||||
updateSubstitutions(FEE_BASE_MAP, "FEE_VERSION", "0.11", "FEE_NS", "fee11");
|
||||
private static final ImmutableMap<String, String> FEE_12_MAP =
|
||||
updateSubstitutions(FEE_BASE_MAP, "FEE_VERSION", "0.12", "FEE_NS", "fee12");
|
||||
private static final ImmutableMap<String, String> FEE_STD_1_0_MAP =
|
||||
updateSubstitutions(FEE_BASE_MAP, "FEE_VERSION", "epp:fee-1.0", "FEE_NS", "fee1_00");
|
||||
|
||||
private final DateTime expirationTime = DateTime.parse("2000-04-03T22:00:00.0Z");
|
||||
|
||||
@@ -390,7 +386,7 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, Domain>
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_internalRegiration_premiumDomain() throws Exception {
|
||||
void testSuccess_internalRegiration_premiumDomain_std_v1() throws Exception {
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
@@ -398,7 +394,8 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, Domain>
|
||||
.build());
|
||||
persistDomain(SPECIFIED, Money.of(USD, 2));
|
||||
setRegistrarIdForFlow("NewRegistrar");
|
||||
ImmutableMap<String, String> customFeeMap = updateSubstitutions(FEE_06_MAP, "FEE", "10.00");
|
||||
ImmutableMap<String, String> customFeeMap =
|
||||
updateSubstitutions(FEE_STD_1_0_MAP, "FEE", "10.00");
|
||||
setEppInput("domain_renew_fee.xml", customFeeMap);
|
||||
doSuccessfulTest(
|
||||
"domain_renew_response_fee.xml",
|
||||
@@ -427,7 +424,7 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, Domain>
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_anchorTenant_premiumDomain() throws Exception {
|
||||
void testSuccess_anchorTenant_premiumDomain_std_v1() throws Exception {
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
@@ -435,7 +432,8 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, Domain>
|
||||
.build());
|
||||
persistDomain(NONPREMIUM, null);
|
||||
setRegistrarIdForFlow("NewRegistrar");
|
||||
ImmutableMap<String, String> customFeeMap = updateSubstitutions(FEE_06_MAP, "FEE", "55.00");
|
||||
ImmutableMap<String, String> customFeeMap =
|
||||
updateSubstitutions(FEE_STD_1_0_MAP, "FEE", "55.00");
|
||||
setEppInput("domain_renew_fee.xml", customFeeMap);
|
||||
doSuccessfulTest(
|
||||
"domain_renew_response_fee.xml",
|
||||
@@ -449,12 +447,12 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, Domain>
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_customLogicFee() throws Exception {
|
||||
void testSuccess_customLogicFee_std_v1() throws Exception {
|
||||
// The "costly-renew" domain has an additional RENEW fee of 100 from custom logic on top of the
|
||||
// normal $11 standard renew price for this TLD.
|
||||
ImmutableMap<String, String> customFeeMap =
|
||||
updateSubstitutions(
|
||||
FEE_06_MAP,
|
||||
FEE_STD_1_0_MAP,
|
||||
"NAME",
|
||||
"costly-renew.tld",
|
||||
"PERIOD",
|
||||
@@ -475,121 +473,45 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, Domain>
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_06_MAP);
|
||||
void testSuccess_fee_std_v1() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_STD_1_0_MAP);
|
||||
persistDomain();
|
||||
doSuccessfulTest("domain_renew_response_fee.xml", 5, FEE_06_MAP);
|
||||
doSuccessfulTest("domain_renew_response_fee.xml", 5, FEE_STD_1_0_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_11_MAP);
|
||||
void testSuccess_fee_withDefaultAttributes_std_v1() throws Exception {
|
||||
setEppInput("domain_renew_fee_defaults.xml", FEE_STD_1_0_MAP);
|
||||
persistDomain();
|
||||
doSuccessfulTest("domain_renew_response_fee.xml", 5, FEE_11_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_12_MAP);
|
||||
persistDomain();
|
||||
doSuccessfulTest("domain_renew_response_fee.xml", 5, FEE_12_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee_defaults.xml", FEE_06_MAP);
|
||||
persistDomain();
|
||||
doSuccessfulTest("domain_renew_response_fee.xml", 5, FEE_06_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee_defaults.xml", FEE_11_MAP);
|
||||
persistDomain();
|
||||
doSuccessfulTest("domain_renew_response_fee.xml", 5, FEE_11_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee_defaults.xml", FEE_12_MAP);
|
||||
persistDomain();
|
||||
doSuccessfulTest("domain_renew_response_fee.xml", 5, FEE_12_MAP);
|
||||
doSuccessfulTest("domain_renew_response_fee.xml", 5, FEE_STD_1_0_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_fee_unknownCurrency() {
|
||||
setEppInput("domain_renew_fee.xml", updateSubstitutions(FEE_06_MAP, "CURRENCY", "BAD"));
|
||||
setEppInput("domain_renew_fee.xml", updateSubstitutions(FEE_STD_1_0_MAP, "CURRENCY", "BAD"));
|
||||
EppException thrown = assertThrows(UnknownCurrencyEppException.class, this::persistDomain);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee_refundable.xml", FEE_06_MAP);
|
||||
void testFailure_refundableFee_std_v1() throws Exception {
|
||||
setEppInput("domain_renew_fee_refundable.xml", FEE_STD_1_0_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee_refundable.xml", FEE_11_MAP);
|
||||
void testFailure_gracePeriodFee_std_v1() throws Exception {
|
||||
setEppInput("domain_renew_fee_grace_period.xml", FEE_STD_1_0_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee_refundable.xml", FEE_12_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee_grace_period.xml", FEE_06_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee_grace_period.xml", FEE_11_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee_grace_period.xml", FEE_12_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee_applied.xml", FEE_06_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee_applied.xml", FEE_11_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee_applied.xml", FEE_12_MAP);
|
||||
void testFailure_appliedFee_std_v1() throws Exception {
|
||||
setEppInput("domain_renew_fee_applied.xml", FEE_STD_1_0_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
@@ -991,8 +913,8 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, Domain>
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_06_MAP);
|
||||
void testFailure_wrongFeeAmount_std_v1() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_STD_1_0_MAP);
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
@@ -1004,34 +926,8 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, Domain>
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_11_MAP);
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 20)))
|
||||
.build());
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_12_MAP);
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 20)))
|
||||
.build());
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_06_MAP);
|
||||
void testFailure_wrongCurrency_std_v1() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_STD_1_0_MAP);
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
@@ -1050,64 +946,8 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, Domain>
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_11_MAP);
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setCurrency(EUR)
|
||||
.setCreateBillingCostTransitions(
|
||||
ImmutableSortedMap.of(START_OF_TIME, Money.of(EUR, 13)))
|
||||
.setRestoreBillingCost(Money.of(EUR, 11))
|
||||
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(EUR, 7)))
|
||||
.setEapFeeSchedule(ImmutableSortedMap.of(START_OF_TIME, Money.zero(EUR)))
|
||||
.setRegistryLockOrUnlockBillingCost(Money.of(EUR, 20))
|
||||
.setServerStatusChangeBillingCost(Money.of(EUR, 19))
|
||||
.build());
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(CurrencyUnitMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_12_MAP);
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setCurrency(EUR)
|
||||
.setCreateBillingCostTransitions(
|
||||
ImmutableSortedMap.of(START_OF_TIME, Money.of(EUR, 13)))
|
||||
.setRestoreBillingCost(Money.of(EUR, 11))
|
||||
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(EUR, 7)))
|
||||
.setEapFeeSchedule(ImmutableSortedMap.of(START_OF_TIME, Money.zero(EUR)))
|
||||
.setRegistryLockOrUnlockBillingCost(Money.of(EUR, 20))
|
||||
.setServerStatusChangeBillingCost(Money.of(EUR, 19))
|
||||
.build());
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(CurrencyUnitMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee_bad_scale.xml", FEE_06_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(CurrencyValueScaleException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee_bad_scale.xml", FEE_11_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(CurrencyValueScaleException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee_bad_scale.xml", FEE_12_MAP);
|
||||
void testFailure_feeGivenInWrongScale_std_v1() throws Exception {
|
||||
setEppInput("domain_renew_fee_bad_scale.xml", FEE_STD_1_0_MAP);
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(CurrencyValueScaleException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
@@ -1522,8 +1362,8 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, Domain>
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_doesNotApplyNonPremiumDefaultTokenToPremiumName() throws Exception {
|
||||
ImmutableMap<String, String> customFeeMap = updateSubstitutions(FEE_06_MAP, "FEE", "500");
|
||||
void testSuccess_doesNotApplyNonPremiumDefaultTokenToPremiumName_std_v1() throws Exception {
|
||||
ImmutableMap<String, String> customFeeMap = updateSubstitutions(FEE_STD_1_0_MAP, "FEE", "500");
|
||||
setEppInput("domain_renew_fee.xml", customFeeMap);
|
||||
persistDomain();
|
||||
AllocationToken defaultToken1 =
|
||||
@@ -1556,9 +1396,9 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, Domain>
|
||||
"CURRENCY",
|
||||
"USD",
|
||||
"FEE_VERSION",
|
||||
"0.6",
|
||||
"epp:fee-1.0",
|
||||
"FEE_NS",
|
||||
"fee")));
|
||||
"fee1_00")));
|
||||
BillingEvent billingEvent =
|
||||
Iterables.getOnlyElement(DatabaseHelper.loadAllOf(BillingEvent.class));
|
||||
assertThat(billingEvent.getTargetId()).isEqualTo("example.tld");
|
||||
@@ -1662,8 +1502,8 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, Domain>
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_wrongFeeAmountTooHigh_defaultToken_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_06_MAP);
|
||||
void testSuccess_wrongFeeAmountTooHigh_defaultToken_std_v1() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_STD_1_0_MAP);
|
||||
persistDomain();
|
||||
AllocationToken defaultToken1 =
|
||||
persistResource(
|
||||
@@ -1694,136 +1534,14 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, Domain>
|
||||
"CURRENCY",
|
||||
"USD",
|
||||
"FEE_VERSION",
|
||||
"0.6",
|
||||
"epp:fee-1.0",
|
||||
"FEE_NS",
|
||||
"fee")));
|
||||
"fee1_00")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmountTooLow_defaultToken_v06() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_06_MAP);
|
||||
persistDomain();
|
||||
AllocationToken defaultToken1 =
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("aaaaa")
|
||||
.setTokenType(DEFAULT_PROMO)
|
||||
.setDiscountFraction(0.5)
|
||||
.setDiscountYears(1)
|
||||
.setAllowedTlds(ImmutableSet.of("tld"))
|
||||
.build());
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setDefaultPromoTokens(ImmutableList.of(defaultToken1.createVKey()))
|
||||
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 20)))
|
||||
.build());
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_wrongFeeAmountTooHigh_defaultToken_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_11_MAP);
|
||||
persistDomain();
|
||||
AllocationToken defaultToken1 =
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("aaaaa")
|
||||
.setTokenType(DEFAULT_PROMO)
|
||||
.setDiscountFraction(0.5)
|
||||
.setDiscountYears(1)
|
||||
.setAllowedTlds(ImmutableSet.of("tld"))
|
||||
.build());
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setDefaultPromoTokens(ImmutableList.of(defaultToken1.createVKey()))
|
||||
.build());
|
||||
runFlowAssertResponse(
|
||||
loadFile(
|
||||
"domain_renew_response_fee.xml",
|
||||
ImmutableMap.of(
|
||||
"NAME",
|
||||
"example.tld",
|
||||
"PERIOD",
|
||||
"5",
|
||||
"EX_DATE",
|
||||
"2005-04-03T22:00:00.0Z",
|
||||
"FEE",
|
||||
"49.50",
|
||||
"CURRENCY",
|
||||
"USD",
|
||||
"FEE_VERSION",
|
||||
"0.11",
|
||||
"FEE_NS",
|
||||
"fee")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmountTooLow_defaultToken_v11() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_11_MAP);
|
||||
persistDomain();
|
||||
AllocationToken defaultToken1 =
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("aaaaa")
|
||||
.setTokenType(DEFAULT_PROMO)
|
||||
.setDiscountFraction(0.5)
|
||||
.setDiscountYears(1)
|
||||
.setAllowedTlds(ImmutableSet.of("tld"))
|
||||
.build());
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setDefaultPromoTokens(ImmutableList.of(defaultToken1.createVKey()))
|
||||
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 20)))
|
||||
.build());
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_wrongFeeAmountTooHigh_defaultToken_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_12_MAP);
|
||||
persistDomain();
|
||||
AllocationToken defaultToken1 =
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("aaaaa")
|
||||
.setTokenType(DEFAULT_PROMO)
|
||||
.setDiscountFraction(0.5)
|
||||
.setDiscountYears(1)
|
||||
.setAllowedTlds(ImmutableSet.of("tld"))
|
||||
.build());
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setDefaultPromoTokens(ImmutableList.of(defaultToken1.createVKey()))
|
||||
.build());
|
||||
runFlowAssertResponse(
|
||||
loadFile(
|
||||
"domain_renew_response_fee.xml",
|
||||
ImmutableMap.of(
|
||||
"NAME",
|
||||
"example.tld",
|
||||
"PERIOD",
|
||||
"5",
|
||||
"EX_DATE",
|
||||
"2005-04-03T22:00:00.0Z",
|
||||
"FEE",
|
||||
"49.50",
|
||||
"CURRENCY",
|
||||
"USD",
|
||||
"FEE_VERSION",
|
||||
"0.12",
|
||||
"FEE_NS",
|
||||
"fee")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmountTooLow_defaultToken_v12() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_06_MAP);
|
||||
void testFailure_wrongFeeAmountTooLow_defaultToken_std_v1() throws Exception {
|
||||
setEppInput("domain_renew_fee.xml", FEE_STD_1_0_MAP);
|
||||
persistDomain();
|
||||
AllocationToken defaultToken1 =
|
||||
persistResource(
|
||||
|
||||
@@ -0,0 +1,351 @@
|
||||
// Copyright 2026 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.flows.domain;
|
||||
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.loadRegistrar;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.EppExceptionSubject.assertAboutEppExceptions;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
import static org.joda.money.CurrencyUnit.EUR;
|
||||
import static org.joda.money.CurrencyUnit.USD;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import google.registry.flows.EppException;
|
||||
import google.registry.flows.FlowUtils.UnknownCurrencyEppException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.CurrencyUnitMismatchException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.CurrencyValueScaleException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.FeesMismatchException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.PremiumNameBlockedException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.UnsupportedFeeAttributeException;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.domain.DomainHistory;
|
||||
import google.registry.model.domain.GracePeriod;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.model.poll.PollMessage;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.tld.Tld;
|
||||
import google.registry.testing.DatabaseHelper;
|
||||
import java.util.Map;
|
||||
import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Tests for {@link DomainRestoreRequestFlow} that use the old fee extensions (0.6, 0.11, 0.12). */
|
||||
public class DomainRestoreRequestFlowOldFeeExtensionsTest
|
||||
extends ProductionSimulatingFeeExtensionsTest<DomainRestoreRequestFlow> {
|
||||
|
||||
private static final ImmutableMap<String, String> FEE_06_MAP =
|
||||
ImmutableMap.of("FEE_VERSION", "fee-0.6", "FEE_NS", "fee", "CURRENCY", "USD");
|
||||
private static final ImmutableMap<String, String> FEE_11_MAP =
|
||||
ImmutableMap.of("FEE_VERSION", "fee-0.11", "FEE_NS", "fee11", "CURRENCY", "USD");
|
||||
private static final ImmutableMap<String, String> FEE_12_MAP =
|
||||
ImmutableMap.of("FEE_VERSION", "fee-0.12", "FEE_NS", "fee12", "CURRENCY", "USD");
|
||||
|
||||
@BeforeEach
|
||||
void beforeEachDomainRestoreRequestFlowOldFeeExtensionsTest() {
|
||||
createTld("tld");
|
||||
persistResource(
|
||||
loadRegistrar("TheRegistrar")
|
||||
.asBuilder()
|
||||
.setBillingAccountMap(ImmutableMap.of(USD, "123", EUR, "567"))
|
||||
.build());
|
||||
setEppInput("domain_update_restore_request.xml", ImmutableMap.of("DOMAIN", "example.tld"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v06() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee.xml", FEE_06_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
persistResource(Tld.get("tld").asBuilder().setRestoreBillingCost(Money.of(USD, 100)).build());
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v11() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee.xml", FEE_11_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
persistResource(Tld.get("tld").asBuilder().setRestoreBillingCost(Money.of(USD, 100)).build());
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v12() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee.xml", FEE_12_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
persistResource(Tld.get("tld").asBuilder().setRestoreBillingCost(Money.of(USD, 100)).build());
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v06() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_bad_scale.xml", FEE_06_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(CurrencyValueScaleException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v11() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_bad_scale.xml", FEE_11_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(CurrencyValueScaleException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v12() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_bad_scale.xml", FEE_12_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(CurrencyValueScaleException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v06() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_applied.xml", FEE_06_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v11() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_applied.xml", FEE_11_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v12() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_applied.xml", FEE_12_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v06() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_defaults.xml", FEE_06_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_06_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v11() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_defaults.xml", FEE_11_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_11_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v12() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_defaults.xml", FEE_12_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_12_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v06() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee.xml", FEE_06_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_06_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v06_noRenewal() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_no_renewal.xml", FEE_06_MAP);
|
||||
persistPendingDeleteDomain(clock.nowUtc().plusMonths(6));
|
||||
runFlowAssertResponse(
|
||||
loadFile("domain_update_restore_request_response_fee_no_renewal.xml", FEE_06_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v11() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee.xml", FEE_11_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_11_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v12() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee.xml", FEE_12_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_12_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v06() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_refundable.xml", FEE_06_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v11() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_refundable.xml", FEE_11_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v12() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_refundable.xml", FEE_12_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v06() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_grace_period.xml", FEE_06_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v11() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_grace_period.xml", FEE_11_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v12() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_grace_period.xml", FEE_12_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
private void runWrongCurrencyTest(Map<String, String> substitutions) throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee.xml", substitutions);
|
||||
persistPendingDeleteDomain();
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setCurrency(EUR)
|
||||
.setCreateBillingCostTransitions(
|
||||
ImmutableSortedMap.of(START_OF_TIME, Money.of(EUR, 13)))
|
||||
.setRestoreBillingCost(Money.of(EUR, 11))
|
||||
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(EUR, 7)))
|
||||
.setEapFeeSchedule(ImmutableSortedMap.of(START_OF_TIME, Money.zero(EUR)))
|
||||
.setServerStatusChangeBillingCost(Money.of(EUR, 19))
|
||||
.setRegistryLockOrUnlockBillingCost(Money.of(EUR, 0))
|
||||
.build());
|
||||
EppException thrown = assertThrows(CurrencyUnitMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v06() throws Exception {
|
||||
runWrongCurrencyTest(FEE_06_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v11() throws Exception {
|
||||
runWrongCurrencyTest(FEE_11_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v12() throws Exception {
|
||||
runWrongCurrencyTest(FEE_12_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_premiumBlocked_v12() throws Exception {
|
||||
createTld("example");
|
||||
setEppInput("domain_update_restore_request_premium.xml", FEE_12_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
// Modify the Registrar to block premium names.
|
||||
persistResource(loadRegistrar("TheRegistrar").asBuilder().setBlockPremiumNames(true).build());
|
||||
EppException thrown = assertThrows(PremiumNameBlockedException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_premiumNotBlocked_andNoRenewal_v12() throws Exception {
|
||||
createTld("example");
|
||||
setEppInput("domain_update_restore_request_premium_no_renewal.xml", FEE_12_MAP);
|
||||
persistPendingDeleteDomain(clock.nowUtc().plusYears(2));
|
||||
runFlowAssertResponse(
|
||||
loadFile("domain_update_restore_request_response_fee_no_renewal.xml", FEE_12_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_fee_unknownCurrency_v12() {
|
||||
ImmutableMap<String, String> substitutions =
|
||||
ImmutableMap.of("FEE_VERSION", "fee-0.12", "FEE_NS", "fee12", "CURRENCY", "BAD");
|
||||
setEppInput("domain_update_restore_request_fee.xml", substitutions);
|
||||
EppException thrown =
|
||||
assertThrows(UnknownCurrencyEppException.class, this::persistPendingDeleteDomain);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
private Domain persistPendingDeleteDomain() throws Exception {
|
||||
// The domain is now past what had been its expiration date at the time of deletion.
|
||||
return persistPendingDeleteDomain(clock.nowUtc().minusDays(5));
|
||||
}
|
||||
|
||||
private Domain persistPendingDeleteDomain(DateTime expirationTime) throws Exception {
|
||||
Domain domain = persistResource(DatabaseHelper.newDomain(getUniqueIdFromCommand()));
|
||||
HistoryEntry historyEntry =
|
||||
persistResource(
|
||||
new DomainHistory.Builder()
|
||||
.setType(HistoryEntry.Type.DOMAIN_DELETE)
|
||||
.setModificationTime(clock.nowUtc())
|
||||
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
|
||||
.setDomain(domain)
|
||||
.build());
|
||||
domain =
|
||||
persistResource(
|
||||
domain
|
||||
.asBuilder()
|
||||
.setRegistrationExpirationTime(expirationTime)
|
||||
.setDeletionTime(clock.nowUtc().plusDays(35))
|
||||
.addGracePeriod(
|
||||
GracePeriod.create(
|
||||
GracePeriodStatus.REDEMPTION,
|
||||
domain.getRepoId(),
|
||||
clock.nowUtc().plusDays(1),
|
||||
"TheRegistrar",
|
||||
null))
|
||||
.setStatusValues(ImmutableSet.of(StatusValue.PENDING_DELETE))
|
||||
.setDeletePollMessage(
|
||||
persistResource(
|
||||
new PollMessage.OneTime.Builder()
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(clock.nowUtc().plusDays(5))
|
||||
.setHistoryEntry(historyEntry)
|
||||
.build())
|
||||
.createVKey())
|
||||
.build());
|
||||
clock.advanceOneMilli();
|
||||
return domain;
|
||||
}
|
||||
}
|
||||
@@ -86,12 +86,8 @@ import org.junit.jupiter.api.Test;
|
||||
/** Unit tests for {@link DomainRestoreRequestFlow}. */
|
||||
class DomainRestoreRequestFlowTest extends ResourceFlowTestCase<DomainRestoreRequestFlow, Domain> {
|
||||
|
||||
private static final ImmutableMap<String, String> FEE_06_MAP =
|
||||
ImmutableMap.of("FEE_VERSION", "0.6", "FEE_NS", "fee", "CURRENCY", "USD");
|
||||
private static final ImmutableMap<String, String> FEE_11_MAP =
|
||||
ImmutableMap.of("FEE_VERSION", "0.11", "FEE_NS", "fee11", "CURRENCY", "USD");
|
||||
private static final ImmutableMap<String, String> FEE_12_MAP =
|
||||
ImmutableMap.of("FEE_VERSION", "0.12", "FEE_NS", "fee12", "CURRENCY", "USD");
|
||||
private static final ImmutableMap<String, String> FEE_STD_1_0_MAP =
|
||||
ImmutableMap.of("FEE_VERSION", "epp:fee-1.0", "FEE_NS", "fee1_00", "CURRENCY", "USD");
|
||||
|
||||
@BeforeEach
|
||||
void initDomainTest() {
|
||||
@@ -308,7 +304,7 @@ class DomainRestoreRequestFlowTest extends ResourceFlowTestCase<DomainRestoreReq
|
||||
|
||||
@Test
|
||||
void testSuccess_autorenewEndTimeIsCleared() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee.xml", FEE_06_MAP);
|
||||
setEppInput("domain_update_restore_request_fee.xml", FEE_STD_1_0_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
persistResource(
|
||||
reloadResourceByForeignKey()
|
||||
@@ -316,64 +312,31 @@ class DomainRestoreRequestFlowTest extends ResourceFlowTestCase<DomainRestoreReq
|
||||
.setAutorenewEndTime(Optional.of(clock.nowUtc().plusYears(2)))
|
||||
.build());
|
||||
assertThat(reloadResourceByForeignKey().getAutorenewEndTime()).isPresent();
|
||||
runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_06_MAP));
|
||||
runFlowAssertResponse(
|
||||
loadFile("domain_update_restore_request_response_fee.xml", FEE_STD_1_0_MAP));
|
||||
assertThat(reloadResourceByForeignKey().getAutorenewEndTime()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v06() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee.xml", FEE_06_MAP);
|
||||
void testSuccess_fee_std_v1() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee.xml", FEE_STD_1_0_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_06_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v06_noRenewal() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_no_renewal.xml", FEE_06_MAP);
|
||||
persistPendingDeleteDomain(clock.nowUtc().plusMonths(6));
|
||||
runFlowAssertResponse(
|
||||
loadFile("domain_update_restore_request_response_fee_no_renewal.xml", FEE_06_MAP));
|
||||
loadFile("domain_update_restore_request_response_fee.xml", FEE_STD_1_0_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v11() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee.xml", FEE_11_MAP);
|
||||
void testSuccess_fee_withDefaultAttributes_std_v1() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_defaults.xml", FEE_STD_1_0_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_11_MAP));
|
||||
runFlowAssertResponse(
|
||||
loadFile("domain_update_restore_request_response_fee.xml", FEE_STD_1_0_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v12() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee.xml", FEE_12_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_12_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v06() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_defaults.xml", FEE_06_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_06_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v11() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_defaults.xml", FEE_11_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_11_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v12() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_defaults.xml", FEE_12_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
runFlowAssertResponse(loadFile("domain_update_restore_request_response_fee.xml", FEE_12_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_fee_unknownCurrency() {
|
||||
void testFailure_fee_unknownCurrency_std_v1() {
|
||||
ImmutableMap<String, String> substitutions =
|
||||
ImmutableMap.of("FEE_VERSION", "0.12", "FEE_NS", "fee12", "CURRENCY", "BAD");
|
||||
ImmutableMap.of("FEE_VERSION", "epp:fee-1.0", "FEE_NS", "fee1_00", "CURRENCY", "BAD");
|
||||
setEppInput("domain_update_restore_request_fee.xml", substitutions);
|
||||
EppException thrown =
|
||||
assertThrows(UnknownCurrencyEppException.class, this::persistPendingDeleteDomain);
|
||||
@@ -381,72 +344,24 @@ class DomainRestoreRequestFlowTest extends ResourceFlowTestCase<DomainRestoreReq
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v06() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_refundable.xml", FEE_06_MAP);
|
||||
void testFailure_refundableFee_std_v1() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_refundable.xml", FEE_STD_1_0_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v11() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_refundable.xml", FEE_11_MAP);
|
||||
void testFailure_gracePeriodFee_std_v1() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_grace_period.xml", FEE_STD_1_0_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v12() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_refundable.xml", FEE_12_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v06() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_grace_period.xml", FEE_06_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v11() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_grace_period.xml", FEE_11_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v12() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_grace_period.xml", FEE_12_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v06() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_applied.xml", FEE_06_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v11() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_applied.xml", FEE_11_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v12() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_applied.xml", FEE_12_MAP);
|
||||
void testFailure_appliedFee_std_v1() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_applied.xml", FEE_STD_1_0_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(UnsupportedFeeAttributeException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
@@ -455,18 +370,19 @@ class DomainRestoreRequestFlowTest extends ResourceFlowTestCase<DomainRestoreReq
|
||||
@Test
|
||||
void testSuccess_premiumNotBlocked() throws Exception {
|
||||
createTld("example");
|
||||
setEppInput("domain_update_restore_request_premium.xml");
|
||||
setEppInput("domain_update_restore_request_premium.xml", FEE_STD_1_0_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
runFlowAssertResponse(loadFile("domain_update_restore_request_response_premium.xml"));
|
||||
runFlowAssertResponse(
|
||||
loadFile("domain_update_restore_request_response_premium.xml", FEE_STD_1_0_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_premiumNotBlocked_andNoRenewal() throws Exception {
|
||||
void testSuccess_premiumNotBlocked_andNoRenewal_std_v1() throws Exception {
|
||||
createTld("example");
|
||||
setEppInput("domain_update_restore_request_premium_no_renewal.xml");
|
||||
setEppInput("domain_update_restore_request_premium_no_renewal.xml", FEE_STD_1_0_MAP);
|
||||
persistPendingDeleteDomain(clock.nowUtc().plusYears(2));
|
||||
runFlowAssertResponse(
|
||||
loadFile("domain_update_restore_request_response_fee_no_renewal.xml", FEE_12_MAP));
|
||||
loadFile("domain_update_restore_request_response_fee_no_renewal.xml", FEE_STD_1_0_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -484,14 +400,14 @@ class DomainRestoreRequestFlowTest extends ResourceFlowTestCase<DomainRestoreReq
|
||||
@Test
|
||||
void testSuccess_superuserOverridesPremiumNameBlock() throws Exception {
|
||||
createTld("example");
|
||||
setEppInput("domain_update_restore_request_premium.xml");
|
||||
setEppInput("domain_update_restore_request_premium.xml", FEE_STD_1_0_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
// Modify the Registrar to block premium names.
|
||||
persistResource(loadRegistrar("TheRegistrar").asBuilder().setBlockPremiumNames(true).build());
|
||||
runFlowAssertResponse(
|
||||
CommitMode.LIVE,
|
||||
UserPrivileges.SUPERUSER,
|
||||
loadFile("domain_update_restore_request_response_premium.xml"));
|
||||
loadFile("domain_update_restore_request_response_premium.xml", FEE_STD_1_0_MAP));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -538,26 +454,8 @@ class DomainRestoreRequestFlowTest extends ResourceFlowTestCase<DomainRestoreReq
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v06() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee.xml", FEE_06_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
persistResource(Tld.get("tld").asBuilder().setRestoreBillingCost(Money.of(USD, 100)).build());
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v11() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee.xml", FEE_11_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
persistResource(Tld.get("tld").asBuilder().setRestoreBillingCost(Money.of(USD, 100)).build());
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v12() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee.xml", FEE_12_MAP);
|
||||
void testFailure_wrongFeeAmount_std_v1() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee.xml", FEE_STD_1_0_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
persistResource(Tld.get("tld").asBuilder().setRestoreBillingCost(Money.of(USD, 100)).build());
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
@@ -584,39 +482,13 @@ class DomainRestoreRequestFlowTest extends ResourceFlowTestCase<DomainRestoreReq
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v06() throws Exception {
|
||||
runWrongCurrencyTest(FEE_06_MAP);
|
||||
void testFailure_wrongCurrency_std_v1() throws Exception {
|
||||
runWrongCurrencyTest(FEE_STD_1_0_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v11() throws Exception {
|
||||
runWrongCurrencyTest(FEE_11_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v12() throws Exception {
|
||||
runWrongCurrencyTest(FEE_12_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v06() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_bad_scale.xml", FEE_06_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(CurrencyValueScaleException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v11() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_bad_scale.xml", FEE_11_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(CurrencyValueScaleException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v12() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_bad_scale.xml", FEE_12_MAP);
|
||||
void testFailure_feeGivenInWrongScale_std_v1() throws Exception {
|
||||
setEppInput("domain_update_restore_request_fee_bad_scale.xml", FEE_STD_1_0_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
EppException thrown = assertThrows(CurrencyValueScaleException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
@@ -738,9 +610,9 @@ class DomainRestoreRequestFlowTest extends ResourceFlowTestCase<DomainRestoreReq
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_premiumBlocked() throws Exception {
|
||||
void testFailure_premiumBlocked_std_v1() throws Exception {
|
||||
createTld("example");
|
||||
setEppInput("domain_update_restore_request_premium.xml");
|
||||
setEppInput("domain_update_restore_request_premium.xml", FEE_STD_1_0_MAP);
|
||||
persistPendingDeleteDomain();
|
||||
// Modify the Registrar to block premium names.
|
||||
persistResource(loadRegistrar("TheRegistrar").asBuilder().setBlockPremiumNames(true).build());
|
||||
|
||||
@@ -0,0 +1,897 @@
|
||||
// Copyright 2026 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.flows.domain;
|
||||
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.common.collect.MoreCollectors.onlyElement;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_REQUESTED_TIME;
|
||||
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESOURCE_KEY;
|
||||
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_CREATE;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST;
|
||||
import static google.registry.testing.DatabaseHelper.assertBillingEvents;
|
||||
import static google.registry.testing.DatabaseHelper.assertBillingEventsEqual;
|
||||
import static google.registry.testing.DatabaseHelper.assertPollMessagesEqual;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.getOnlyHistoryEntryOfType;
|
||||
import static google.registry.testing.DatabaseHelper.getOnlyPollMessage;
|
||||
import static google.registry.testing.DatabaseHelper.getPollMessages;
|
||||
import static google.registry.testing.DatabaseHelper.loadByKey;
|
||||
import static google.registry.testing.DatabaseHelper.loadByKeys;
|
||||
import static google.registry.testing.DatabaseHelper.loadRegistrar;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveContact;
|
||||
import static google.registry.testing.DatabaseHelper.persistDomainWithDependentResources;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.DomainSubject.assertAboutDomains;
|
||||
import static google.registry.testing.EppExceptionSubject.assertAboutEppExceptions;
|
||||
import static google.registry.testing.HistoryEntrySubject.assertAboutHistoryEntries;
|
||||
import static google.registry.testing.HostSubject.assertAboutHosts;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
import static org.joda.money.CurrencyUnit.USD;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import com.google.cloud.tasks.v2.HttpMethod;
|
||||
import com.google.common.base.Ascii;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.Streams;
|
||||
import google.registry.batch.ResaveEntityAction;
|
||||
import google.registry.flows.EppException;
|
||||
import google.registry.flows.EppRequestSource;
|
||||
import google.registry.flows.domain.DomainFlowUtils.CurrencyUnitMismatchException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.CurrencyValueScaleException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.FeesMismatchException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.UnsupportedFeeAttributeException;
|
||||
import google.registry.flows.exceptions.TransferPeriodZeroAndFeeTransferExtensionException;
|
||||
import google.registry.model.billing.BillingBase;
|
||||
import google.registry.model.billing.BillingBase.Flag;
|
||||
import google.registry.model.billing.BillingBase.Reason;
|
||||
import google.registry.model.billing.BillingCancellation;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.billing.BillingRecurrence;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.domain.DomainHistory;
|
||||
import google.registry.model.domain.GracePeriod;
|
||||
import google.registry.model.domain.Period;
|
||||
import google.registry.model.domain.Period.Unit;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.model.eppcommon.Trid;
|
||||
import google.registry.model.host.Host;
|
||||
import google.registry.model.poll.PendingActionNotificationResponse;
|
||||
import google.registry.model.poll.PollMessage;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.tld.Tld;
|
||||
import google.registry.model.transfer.DomainTransferData;
|
||||
import google.registry.model.transfer.TransferResponse;
|
||||
import google.registry.model.transfer.TransferStatus;
|
||||
import google.registry.testing.CloudTasksHelper.TaskMatcher;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Duration;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Tests for {@link DomainTransferRequestFlow} that use the old fee extensions (0.6, 0.11, 0.12).
|
||||
*/
|
||||
public class DomainTransferRequestFlowOldFeeExtensionsTest
|
||||
extends ProductionSimulatingFeeExtensionsTest<DomainTransferRequestFlow> {
|
||||
|
||||
private static final ImmutableMap<String, String> BASE_FEE_MAP =
|
||||
new ImmutableMap.Builder<String, String>()
|
||||
.put("DOMAIN", "example.tld")
|
||||
.put("YEARS", "1")
|
||||
.put("AMOUNT", "11.00")
|
||||
.put("CURRENCY", "USD")
|
||||
.build();
|
||||
private static final ImmutableMap<String, String> FEE_06_MAP =
|
||||
new ImmutableMap.Builder<String, String>()
|
||||
.putAll(BASE_FEE_MAP)
|
||||
.put("FEE_VERSION", "fee-0.6")
|
||||
.put("FEE_NS", "fee")
|
||||
.build();
|
||||
private static final ImmutableMap<String, String> FEE_11_MAP =
|
||||
new ImmutableMap.Builder<String, String>()
|
||||
.putAll(BASE_FEE_MAP)
|
||||
.put("FEE_VERSION", "fee-0.11")
|
||||
.put("FEE_NS", "fee11")
|
||||
.build();
|
||||
private static final ImmutableMap<String, String> FEE_12_MAP =
|
||||
new ImmutableMap.Builder<String, String>()
|
||||
.putAll(BASE_FEE_MAP)
|
||||
.put("FEE_VERSION", "fee-0.12")
|
||||
.put("FEE_NS", "fee12")
|
||||
.build();
|
||||
private static final ImmutableMap<String, String> RICH_DOMAIN_MAP =
|
||||
ImmutableMap.<String, String>builder()
|
||||
.put("DOMAIN", "rich.example")
|
||||
.put("YEARS", "1")
|
||||
.put("AMOUNT", "100.00")
|
||||
.put("CURRENCY", "USD")
|
||||
.put("FEE_VERSION", "fee-0.12")
|
||||
.put("FEE_NS", "fee12")
|
||||
.build();
|
||||
|
||||
private static final DateTime TRANSFER_REQUEST_TIME = DateTime.parse("2000-06-06T22:00:00.0Z");
|
||||
private static final DateTime TRANSFER_EXPIRATION_TIME =
|
||||
TRANSFER_REQUEST_TIME.plus(Tld.DEFAULT_AUTOMATIC_TRANSFER_LENGTH);
|
||||
private static final Duration TIME_SINCE_REQUEST = Duration.standardDays(3);
|
||||
private static final int EXTENDED_REGISTRATION_YEARS = 1;
|
||||
private static final DateTime REGISTRATION_EXPIRATION_TIME =
|
||||
DateTime.parse("2001-09-08T22:00:00.0Z");
|
||||
private static final DateTime EXTENDED_REGISTRATION_EXPIRATION_TIME =
|
||||
REGISTRATION_EXPIRATION_TIME.plusYears(EXTENDED_REGISTRATION_YEARS);
|
||||
|
||||
private Contact contact;
|
||||
private Domain domain;
|
||||
private Host subordinateHost;
|
||||
private DomainHistory historyEntryDomainCreate;
|
||||
|
||||
@BeforeEach
|
||||
void beforeEachDomainTransferRequestFlowOldFeeExtensionsTest() {
|
||||
setEppInput("domain_transfer_request.xml");
|
||||
setRegistrarIdForFlow("NewRegistrar");
|
||||
clock.setTo(TRANSFER_REQUEST_TIME.plus(TIME_SINCE_REQUEST));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v06() {
|
||||
setupDomain("example", "tld");
|
||||
runWrongFeeAmountTest(FEE_06_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v11() {
|
||||
setupDomain("example", "tld");
|
||||
runWrongFeeAmountTest(FEE_11_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v12() {
|
||||
setupDomain("example", "tld");
|
||||
runWrongFeeAmountTest(FEE_12_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v06() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
UnsupportedFeeAttributeException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_applied.xml", FEE_06_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v11() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
UnsupportedFeeAttributeException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_applied.xml", FEE_11_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v12() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
UnsupportedFeeAttributeException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_applied.xml", FEE_12_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v06() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
UnsupportedFeeAttributeException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_grace_period.xml", FEE_06_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v11() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
UnsupportedFeeAttributeException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_grace_period.xml", FEE_11_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v12() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
UnsupportedFeeAttributeException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_grace_period.xml", FEE_12_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v06() throws Exception {
|
||||
setupDomain("example", "tld");
|
||||
doSuccessfulTest(
|
||||
"domain_transfer_request_fee_defaults.xml",
|
||||
"domain_transfer_request_response_fee.xml",
|
||||
FEE_06_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v11() throws Exception {
|
||||
setupDomain("example", "tld");
|
||||
doSuccessfulTest(
|
||||
"domain_transfer_request_fee_defaults.xml",
|
||||
"domain_transfer_request_response_fee.xml",
|
||||
FEE_11_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v12() throws Exception {
|
||||
setupDomain("example", "tld");
|
||||
doSuccessfulTest(
|
||||
"domain_transfer_request_fee_defaults.xml",
|
||||
"domain_transfer_request_response_fee.xml",
|
||||
FEE_12_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v06() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
UnsupportedFeeAttributeException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_refundable.xml", FEE_06_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v11() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
UnsupportedFeeAttributeException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_refundable.xml", FEE_11_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v12() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
UnsupportedFeeAttributeException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_refundable.xml", FEE_12_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v06() {
|
||||
runWrongCurrencyTest(FEE_06_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v11() {
|
||||
runWrongCurrencyTest(FEE_11_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v12() {
|
||||
runWrongCurrencyTest(FEE_12_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v06() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
CurrencyValueScaleException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_bad_scale.xml", FEE_06_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v11() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
CurrencyValueScaleException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_bad_scale.xml", FEE_11_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v12() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
CurrencyValueScaleException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_bad_scale.xml", FEE_12_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v06() throws Exception {
|
||||
setupDomain("example", "tld");
|
||||
doSuccessfulTest(
|
||||
"domain_transfer_request_fee.xml", "domain_transfer_request_response_fee.xml", FEE_06_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v11() throws Exception {
|
||||
setupDomain("example", "tld");
|
||||
doSuccessfulTest(
|
||||
"domain_transfer_request_fee.xml", "domain_transfer_request_response_fee.xml", FEE_11_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v12() throws Exception {
|
||||
setupDomain("example", "tld");
|
||||
doSuccessfulTest(
|
||||
"domain_transfer_request_fee.xml", "domain_transfer_request_response_fee.xml", FEE_12_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_customLogicFee_v06() throws Exception {
|
||||
setupDomain("expensive-domain", "foo");
|
||||
clock.advanceOneMilli();
|
||||
doSuccessfulTest(
|
||||
"domain_transfer_request_separate_fees.xml",
|
||||
"domain_transfer_request_response_fees.xml",
|
||||
domain.getRegistrationExpirationTime().plusYears(1),
|
||||
new ImmutableMap.Builder<String, String>()
|
||||
.put("DOMAIN", "expensive-domain.foo")
|
||||
.put("YEARS", "1")
|
||||
.put("AMOUNT", "111.00")
|
||||
.put("EXDATE", "2002-09-08T22:00:00.0Z")
|
||||
.put("FEE_VERSION", "fee-0.6")
|
||||
.put("FEE_NS", "fee")
|
||||
.build(),
|
||||
Optional.of(Money.of(USD, 111)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_premiumNotBlocked_v12() throws Exception {
|
||||
setupDomain("rich", "example");
|
||||
clock.advanceOneMilli();
|
||||
// We don't verify the results; just check that the flow doesn't fail.
|
||||
runTest("domain_transfer_request_fee.xml", UserPrivileges.NORMAL, RICH_DOMAIN_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_superuserExtension_zeroPeriod_feeTransferExtension_v12() {
|
||||
setupDomain("example", "tld");
|
||||
eppRequestSource = EppRequestSource.TOOL;
|
||||
clock.advanceOneMilli();
|
||||
assertThrows(
|
||||
TransferPeriodZeroAndFeeTransferExtensionException.class,
|
||||
() ->
|
||||
runTest(
|
||||
"domain_transfer_request_fee_and_superuser_extension.xml",
|
||||
UserPrivileges.SUPERUSER,
|
||||
new ImmutableMap.Builder<String, String>()
|
||||
.putAll(FEE_12_MAP)
|
||||
.put("PERIOD", "0")
|
||||
.put("AUTOMATIC_TRANSFER_LENGTH", "5")
|
||||
.build()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_premiumNotBlockedInSuperuserMode_v12() throws Exception {
|
||||
setupDomain("rich", "example");
|
||||
clock.advanceOneMilli();
|
||||
// Modify the Registrar to block premium names.
|
||||
persistResource(loadRegistrar("NewRegistrar").asBuilder().setBlockPremiumNames(true).build());
|
||||
// We don't verify the results; just check that the flow doesn't fail.
|
||||
runTest("domain_transfer_request_fee.xml", UserPrivileges.SUPERUSER, RICH_DOMAIN_MAP);
|
||||
}
|
||||
|
||||
private void runWrongCurrencyTest(Map<String, String> substitutions) {
|
||||
Map<String, String> fullSubstitutions = Maps.newHashMap();
|
||||
fullSubstitutions.putAll(substitutions);
|
||||
fullSubstitutions.put("CURRENCY", "EUR");
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
CurrencyUnitMismatchException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee.xml", fullSubstitutions));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,
|
||||
BillingCancellation.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.
|
||||
Tld registry = Tld.get(domain.getTld());
|
||||
DateTime implicitTransferTime = clock.nowUtc().plus(registry.getAutomaticTransferLength());
|
||||
// Setup done; run the test.
|
||||
assertMutatingFlow(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);
|
||||
assertLastHistoryContainsResource(domain);
|
||||
final HistoryEntry historyEntryTransferRequest =
|
||||
getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_REQUEST);
|
||||
assertAboutHistoryEntries()
|
||||
.that(historyEntryTransferRequest)
|
||||
.hasPeriodYears(1)
|
||||
.and()
|
||||
.hasOtherRegistrarId("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));
|
||||
cloudTasksHelper.assertTasksEnqueued(
|
||||
QUEUE_ASYNC_ACTIONS,
|
||||
new TaskMatcher()
|
||||
.path(ResaveEntityAction.PATH)
|
||||
.method(HttpMethod.POST)
|
||||
.service("backend")
|
||||
.header("content-type", "application/x-www-form-urlencoded")
|
||||
.param(PARAM_RESOURCE_KEY, domain.createVKey().stringify())
|
||||
.param(PARAM_REQUESTED_TIME, clock.nowUtc().toString())
|
||||
.scheduleTime(clock.nowUtc().plus(registry.getAutomaticTransferLength())));
|
||||
}
|
||||
|
||||
private void doSuccessfulTest(
|
||||
String commandFilename, String expectedXmlFilename, Map<String, String> substitutions)
|
||||
throws Exception {
|
||||
clock.advanceOneMilli();
|
||||
doSuccessfulTest(
|
||||
commandFilename,
|
||||
expectedXmlFilename,
|
||||
domain.getRegistrationExpirationTime().plusYears(1),
|
||||
substitutions,
|
||||
Optional.empty());
|
||||
}
|
||||
|
||||
private void doSuccessfulTest(String commandFilename, String expectedXmlFilename)
|
||||
throws Exception {
|
||||
clock.advanceOneMilli();
|
||||
doSuccessfulTest(
|
||||
commandFilename, expectedXmlFilename, domain.getRegistrationExpirationTime().plusYears(1));
|
||||
}
|
||||
|
||||
private void doSuccessfulTest(
|
||||
String commandFilename,
|
||||
String expectedXmlFilename,
|
||||
DateTime expectedExpirationTime,
|
||||
BillingCancellation.Builder... extraExpectedBillingEvents)
|
||||
throws Exception {
|
||||
doSuccessfulTest(
|
||||
commandFilename,
|
||||
expectedXmlFilename,
|
||||
expectedExpirationTime,
|
||||
ImmutableMap.of(),
|
||||
Optional.empty(),
|
||||
extraExpectedBillingEvents);
|
||||
}
|
||||
|
||||
private void runWrongFeeAmountTest(Map<String, String> substitutions) {
|
||||
persistResource(
|
||||
Tld.get("tld")
|
||||
.asBuilder()
|
||||
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 20)))
|
||||
.build());
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
FeesMismatchException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee.xml", substitutions));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
private void runTest(
|
||||
String commandFilename, UserPrivileges userPrivileges, Map<String, String> substitutions)
|
||||
throws Exception {
|
||||
setEppInput(commandFilename, substitutions);
|
||||
// Replace the ROID in the xml file with the one generated in our test.
|
||||
eppLoader.replaceAll("JD1234-REP", contact.getRepoId());
|
||||
// Setup done; run the test.
|
||||
assertMutatingFlow(true);
|
||||
runFlow(CommitMode.LIVE, userPrivileges);
|
||||
}
|
||||
|
||||
private void runTest(String commandFilename, UserPrivileges userPrivileges) throws Exception {
|
||||
runTest(commandFilename, userPrivileges, ImmutableMap.of());
|
||||
}
|
||||
|
||||
private void doFailingTest(String commandFilename, Map<String, String> substitutions)
|
||||
throws Exception {
|
||||
runTest(commandFilename, UserPrivileges.NORMAL, substitutions);
|
||||
}
|
||||
|
||||
private void doFailingTest(String commandFilename) throws Exception {
|
||||
runTest(commandFilename, UserPrivileges.NORMAL, ImmutableMap.of());
|
||||
}
|
||||
|
||||
/** Adds a domain with no pending transfer on it. */
|
||||
void setupDomain(String label, String tld) {
|
||||
createTld(tld);
|
||||
contact = persistActiveContact("jd1234");
|
||||
domain =
|
||||
persistDomainWithDependentResources(
|
||||
label,
|
||||
tld,
|
||||
contact,
|
||||
clock.nowUtc(),
|
||||
DateTime.parse("1999-04-03T22:00:00.0Z"),
|
||||
REGISTRATION_EXPIRATION_TIME);
|
||||
subordinateHost =
|
||||
persistResource(
|
||||
new Host.Builder()
|
||||
.setRepoId("2-".concat(Ascii.toUpperCase(tld)))
|
||||
.setHostName("ns1." + label + "." + tld)
|
||||
.setPersistedCurrentSponsorRegistrarId("TheRegistrar")
|
||||
.setCreationRegistrarId("TheRegistrar")
|
||||
.setCreationTimeForTest(DateTime.parse("1999-04-03T22:00:00.0Z"))
|
||||
.setSuperordinateDomain(domain.createVKey())
|
||||
.build());
|
||||
domain =
|
||||
persistResource(
|
||||
domain.asBuilder().addSubordinateHost(subordinateHost.getHostName()).build());
|
||||
historyEntryDomainCreate =
|
||||
getOnlyHistoryEntryOfType(domain, DOMAIN_CREATE, DomainHistory.class);
|
||||
}
|
||||
|
||||
private void assertPollMessagesEmitted(
|
||||
DateTime expectedExpirationTime, DateTime implicitTransferTime) {
|
||||
// Assert that there exists a poll message to notify the losing registrar that a transfer was
|
||||
// requested. If the implicit transfer time is now (i.e. the automatic transfer length is zero)
|
||||
// then also expect a server approved poll message.
|
||||
assertThat(getPollMessages("TheRegistrar", clock.nowUtc()))
|
||||
.hasSize(implicitTransferTime.equals(clock.nowUtc()) ? 2 : 1);
|
||||
|
||||
// Two poll messages on the gaining registrar's side at the expected expiration time: a
|
||||
// (OneTime) transfer approved message, and an Autorenew poll message.
|
||||
assertThat(getPollMessages("NewRegistrar", expectedExpirationTime)).hasSize(2);
|
||||
PollMessage transferApprovedPollMessage =
|
||||
getOnlyPollMessage("NewRegistrar", implicitTransferTime, PollMessage.OneTime.class);
|
||||
PollMessage autorenewPollMessage =
|
||||
getOnlyPollMessage("NewRegistrar", expectedExpirationTime, PollMessage.Autorenew.class);
|
||||
assertThat(transferApprovedPollMessage.getEventTime()).isEqualTo(implicitTransferTime);
|
||||
assertThat(autorenewPollMessage.getEventTime()).isEqualTo(expectedExpirationTime);
|
||||
assertThat(
|
||||
transferApprovedPollMessage.getResponseData().stream()
|
||||
.filter(TransferResponse.class::isInstance)
|
||||
.map(TransferResponse.class::cast)
|
||||
.collect(onlyElement())
|
||||
.getTransferStatus())
|
||||
.isEqualTo(TransferStatus.SERVER_APPROVED);
|
||||
PendingActionNotificationResponse panData =
|
||||
transferApprovedPollMessage.getResponseData().stream()
|
||||
.filter(PendingActionNotificationResponse.class::isInstance)
|
||||
.map(PendingActionNotificationResponse.class::cast)
|
||||
.collect(onlyElement());
|
||||
assertThat(panData.getTrid().getClientTransactionId()).hasValue("ABC-12345");
|
||||
assertThat(panData.getActionResult()).isTrue();
|
||||
|
||||
// Two poll messages on the losing registrar's side at the implicit transfer time: a
|
||||
// transfer pending message, and a transfer approved message (both OneTime messages).
|
||||
assertThat(getPollMessages("TheRegistrar", implicitTransferTime)).hasSize(2);
|
||||
PollMessage losingTransferPendingPollMessage =
|
||||
getPollMessages("TheRegistrar", clock.nowUtc()).stream()
|
||||
.filter(pollMessage -> TransferStatus.PENDING.getMessage().equals(pollMessage.getMsg()))
|
||||
.collect(onlyElement());
|
||||
PollMessage losingTransferApprovedPollMessage =
|
||||
getPollMessages("TheRegistrar", implicitTransferTime).stream()
|
||||
.filter(Predicates.not(Predicates.equalTo(losingTransferPendingPollMessage)))
|
||||
.collect(onlyElement());
|
||||
assertThat(losingTransferPendingPollMessage.getEventTime()).isEqualTo(clock.nowUtc());
|
||||
assertThat(losingTransferApprovedPollMessage.getEventTime()).isEqualTo(implicitTransferTime);
|
||||
assertThat(
|
||||
losingTransferPendingPollMessage.getResponseData().stream()
|
||||
.filter(TransferResponse.class::isInstance)
|
||||
.map(TransferResponse.class::cast)
|
||||
.collect(onlyElement())
|
||||
.getTransferStatus())
|
||||
.isEqualTo(TransferStatus.PENDING);
|
||||
assertThat(
|
||||
losingTransferApprovedPollMessage.getResponseData().stream()
|
||||
.filter(TransferResponse.class::isInstance)
|
||||
.map(TransferResponse.class::cast)
|
||||
.collect(onlyElement())
|
||||
.getTransferStatus())
|
||||
.isEqualTo(TransferStatus.SERVER_APPROVED);
|
||||
|
||||
// Assert that the poll messages show up in the TransferData server approve entities.
|
||||
assertPollMessagesEqual(
|
||||
loadByKey(domain.getTransferData().getServerApproveAutorenewPollMessage()),
|
||||
autorenewPollMessage);
|
||||
// Assert that the full set of server-approve poll messages is exactly the server approve
|
||||
// OneTime messages to gaining and losing registrars plus the gaining client autorenew.
|
||||
assertPollMessagesEqual(
|
||||
Iterables.filter(
|
||||
loadByKeys(domain.getTransferData().getServerApproveEntities()), PollMessage.class),
|
||||
ImmutableList.of(
|
||||
transferApprovedPollMessage, losingTransferApprovedPollMessage, autorenewPollMessage));
|
||||
}
|
||||
|
||||
private void assertHistoryEntriesContainBillingEventsAndGracePeriods(
|
||||
DateTime expectedExpirationTime,
|
||||
DateTime implicitTransferTime,
|
||||
Optional<Money> transferCost,
|
||||
ImmutableSet<GracePeriod> originalGracePeriods,
|
||||
boolean expectTransferBillingEvent,
|
||||
BillingCancellation.Builder... extraExpectedBillingEvents) {
|
||||
Tld registry = Tld.get(domain.getTld());
|
||||
final DomainHistory historyEntryTransferRequest =
|
||||
getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_REQUEST, DomainHistory.class);
|
||||
|
||||
// Construct the billing events we expect to exist, starting with the (optional) billing
|
||||
// event for the transfer itself.
|
||||
Optional<BillingEvent> optionalTransferBillingEvent;
|
||||
if (expectTransferBillingEvent) {
|
||||
// For normal transfers, a BillingEvent should be created AUTOMATIC_TRANSFER_DAYS in the
|
||||
// future, for the case when the transfer is implicitly acked.
|
||||
optionalTransferBillingEvent =
|
||||
Optional.of(
|
||||
new BillingEvent.Builder()
|
||||
.setReason(Reason.TRANSFER)
|
||||
.setTargetId(domain.getDomainName())
|
||||
.setEventTime(implicitTransferTime)
|
||||
.setBillingTime(
|
||||
implicitTransferTime.plus(registry.getTransferGracePeriodLength()))
|
||||
.setRegistrarId("NewRegistrar")
|
||||
.setCost(transferCost.orElse(Money.of(USD, 11)))
|
||||
.setPeriodYears(1)
|
||||
.setDomainHistory(historyEntryTransferRequest)
|
||||
.build());
|
||||
} else {
|
||||
// Superuser transfers with no bundled renewal have no transfer billing event.
|
||||
optionalTransferBillingEvent = Optional.empty();
|
||||
}
|
||||
// Construct the autorenew events for the losing/existing client and the gaining one. Note that
|
||||
// all of the other transfer flow tests happen on day 3 of the transfer, but the initial
|
||||
// request by definition takes place on day 1, so we need to edit the times in the
|
||||
// autorenew events from the base test case.
|
||||
BillingRecurrence losingClientAutorenew =
|
||||
getLosingClientAutorenewEvent()
|
||||
.asBuilder()
|
||||
.setRecurrenceEndTime(implicitTransferTime)
|
||||
.build();
|
||||
BillingRecurrence gainingClientAutorenew =
|
||||
getGainingClientAutorenewEvent()
|
||||
.asBuilder()
|
||||
.setEventTime(expectedExpirationTime)
|
||||
.setRecurrenceLastExpansion(expectedExpirationTime.minusYears(1))
|
||||
.build();
|
||||
// Construct extra billing events expected by the specific test.
|
||||
ImmutableSet<BillingBase> extraBillingBases =
|
||||
Stream.of(extraExpectedBillingEvents)
|
||||
.map(builder -> builder.setDomainHistory(historyEntryTransferRequest).build())
|
||||
.collect(toImmutableSet());
|
||||
// Assert that the billing events we constructed above actually exist in the database.
|
||||
ImmutableSet<BillingBase> expectedBillingBases =
|
||||
Streams.concat(
|
||||
Stream.of(losingClientAutorenew, gainingClientAutorenew),
|
||||
optionalTransferBillingEvent.stream())
|
||||
.collect(toImmutableSet());
|
||||
assertBillingEvents(Sets.union(expectedBillingBases, extraBillingBases));
|
||||
// Assert that the domain's TransferData server-approve billing events match the above.
|
||||
if (expectTransferBillingEvent) {
|
||||
assertBillingEventsEqual(
|
||||
loadByKey(domain.getTransferData().getServerApproveBillingEvent()),
|
||||
optionalTransferBillingEvent.get());
|
||||
} else {
|
||||
assertThat(domain.getTransferData().getServerApproveBillingEvent()).isNull();
|
||||
}
|
||||
assertBillingEventsEqual(
|
||||
loadByKey(domain.getTransferData().getServerApproveAutorenewEvent()),
|
||||
gainingClientAutorenew);
|
||||
// Assert that the full set of server-approve billing events is exactly the extra ones plus
|
||||
// the transfer billing event (if present) and the gaining client autorenew.
|
||||
ImmutableSet<BillingBase> expectedServeApproveBillingBases =
|
||||
Streams.concat(Stream.of(gainingClientAutorenew), optionalTransferBillingEvent.stream())
|
||||
.collect(toImmutableSet());
|
||||
assertBillingEventsEqual(
|
||||
Iterables.filter(
|
||||
loadByKeys(domain.getTransferData().getServerApproveEntities()), BillingBase.class),
|
||||
Sets.union(expectedServeApproveBillingBases, extraBillingBases));
|
||||
// The domain's autorenew billing event should still point to the losing client's event.
|
||||
BillingRecurrence domainAutorenewEvent = loadByKey(domain.getAutorenewBillingEvent());
|
||||
assertThat(domainAutorenewEvent.getRegistrarId()).isEqualTo("TheRegistrar");
|
||||
assertThat(domainAutorenewEvent.getRecurrenceEndTime()).isEqualTo(implicitTransferTime);
|
||||
// The original grace periods should remain untouched.
|
||||
assertThat(domain.getGracePeriods()).containsExactlyElementsIn(originalGracePeriods);
|
||||
// If we fast forward AUTOMATIC_TRANSFER_DAYS, the transfer should have cleared out all other
|
||||
// grace periods, but expect a transfer grace period (if there was a transfer billing event).
|
||||
Domain domainAfterAutomaticTransfer = domain.cloneProjectedAtTime(implicitTransferTime);
|
||||
if (expectTransferBillingEvent) {
|
||||
assertGracePeriods(
|
||||
domainAfterAutomaticTransfer.getGracePeriods(),
|
||||
ImmutableMap.of(
|
||||
GracePeriod.create(
|
||||
GracePeriodStatus.TRANSFER,
|
||||
domain.getRepoId(),
|
||||
implicitTransferTime.plus(registry.getTransferGracePeriodLength()),
|
||||
"NewRegistrar",
|
||||
null),
|
||||
optionalTransferBillingEvent.get()));
|
||||
} else {
|
||||
assertGracePeriods(domainAfterAutomaticTransfer.getGracePeriods(), ImmutableMap.of());
|
||||
}
|
||||
}
|
||||
|
||||
private BillingRecurrence getGainingClientAutorenewEvent() {
|
||||
return new BillingRecurrence.Builder()
|
||||
.setReason(Reason.RENEW)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setTargetId(domain.getDomainName())
|
||||
.setRegistrarId("NewRegistrar")
|
||||
.setEventTime(EXTENDED_REGISTRATION_EXPIRATION_TIME)
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setDomainHistory(
|
||||
getOnlyHistoryEntryOfType(
|
||||
domain, HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST, DomainHistory.class))
|
||||
.build();
|
||||
}
|
||||
|
||||
/** Get the autorenew event that the losing client will have after a SERVER_APPROVED transfer. */
|
||||
private BillingRecurrence getLosingClientAutorenewEvent() {
|
||||
return new BillingRecurrence.Builder()
|
||||
.setReason(Reason.RENEW)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setTargetId(domain.getDomainName())
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(REGISTRATION_EXPIRATION_TIME)
|
||||
.setRecurrenceEndTime(TRANSFER_EXPIRATION_TIME)
|
||||
.setDomainHistory(historyEntryDomainCreate)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void assertAboutDomainAfterAutomaticTransfer(
|
||||
DateTime expectedExpirationTime, DateTime implicitTransferTime, Period expectedPeriod)
|
||||
throws Exception {
|
||||
Tld registry = Tld.get(domain.getTld());
|
||||
Domain domainAfterAutomaticTransfer = domain.cloneProjectedAtTime(implicitTransferTime);
|
||||
assertTransferApproved(domainAfterAutomaticTransfer, implicitTransferTime, expectedPeriod);
|
||||
assertAboutDomains()
|
||||
.that(domainAfterAutomaticTransfer)
|
||||
.hasRegistrationExpirationTime(expectedExpirationTime)
|
||||
.and()
|
||||
.hasLastEppUpdateTime(implicitTransferTime)
|
||||
.and()
|
||||
.hasLastEppUpdateRegistrarId("NewRegistrar");
|
||||
assertThat(loadByKey(domainAfterAutomaticTransfer.getAutorenewBillingEvent()).getEventTime())
|
||||
.isEqualTo(expectedExpirationTime);
|
||||
// And after the expected grace time, the grace period should be gone.
|
||||
Domain afterGracePeriod =
|
||||
domain.cloneProjectedAtTime(
|
||||
clock
|
||||
.nowUtc()
|
||||
.plus(registry.getAutomaticTransferLength())
|
||||
.plus(registry.getTransferGracePeriodLength()));
|
||||
assertThat(afterGracePeriod.getGracePeriods()).isEmpty();
|
||||
}
|
||||
|
||||
private void assertTransferApproved(
|
||||
Domain domain, DateTime automaticTransferTime, Period expectedPeriod) throws Exception {
|
||||
assertAboutDomains()
|
||||
.that(domain)
|
||||
.hasCurrentSponsorRegistrarId("NewRegistrar")
|
||||
.and()
|
||||
.hasLastTransferTime(automaticTransferTime)
|
||||
.and()
|
||||
.doesNotHaveStatusValue(StatusValue.PENDING_TRANSFER);
|
||||
Trid expectedTrid =
|
||||
Trid.create(
|
||||
getClientTrid(),
|
||||
domain.getTransferData().getTransferRequestTrid().getServerTransactionId());
|
||||
assertThat(domain.getTransferData())
|
||||
.isEqualTo(
|
||||
new DomainTransferData.Builder()
|
||||
.setGainingRegistrarId("NewRegistrar")
|
||||
.setLosingRegistrarId("TheRegistrar")
|
||||
.setTransferRequestTrid(expectedTrid)
|
||||
.setTransferRequestTime(clock.nowUtc())
|
||||
.setTransferPeriod(expectedPeriod)
|
||||
.setTransferStatus(TransferStatus.SERVER_APPROVED)
|
||||
.setPendingTransferExpirationTime(automaticTransferTime)
|
||||
.setTransferredRegistrationExpirationTime(domain.getRegistrationExpirationTime())
|
||||
// Server-approve entity fields should all be nulled out.
|
||||
.build());
|
||||
}
|
||||
|
||||
private void assertTransferRequested(
|
||||
Domain domain,
|
||||
DateTime automaticTransferTime,
|
||||
Period expectedPeriod,
|
||||
DateTime expectedExpirationTime)
|
||||
throws Exception {
|
||||
assertAboutDomains()
|
||||
.that(domain)
|
||||
.hasCurrentSponsorRegistrarId("TheRegistrar")
|
||||
.and()
|
||||
.hasStatusValue(StatusValue.PENDING_TRANSFER)
|
||||
.and()
|
||||
.hasLastEppUpdateTime(clock.nowUtc())
|
||||
.and()
|
||||
.hasLastEppUpdateRegistrarId("NewRegistrar");
|
||||
Trid expectedTrid =
|
||||
Trid.create(
|
||||
getClientTrid(),
|
||||
domain.getTransferData().getTransferRequestTrid().getServerTransactionId());
|
||||
assertThat(domain.getTransferData())
|
||||
.isEqualTo(
|
||||
// Compare against only the following fields by rebuilding the existing TransferData.
|
||||
// Equivalent to assertThat(transferData.getGainingClientId()).isEqualTo("NewReg")
|
||||
// and similar individual assertions, but produces a nicer error message this way.
|
||||
domain
|
||||
.getTransferData()
|
||||
.asBuilder()
|
||||
.setGainingRegistrarId("NewRegistrar")
|
||||
.setLosingRegistrarId("TheRegistrar")
|
||||
.setTransferRequestTrid(expectedTrid)
|
||||
.setTransferRequestTime(clock.nowUtc())
|
||||
.setTransferPeriod(expectedPeriod)
|
||||
.setTransferStatus(TransferStatus.PENDING)
|
||||
.setPendingTransferExpirationTime(automaticTransferTime)
|
||||
.setTransferredRegistrationExpirationTime(expectedExpirationTime)
|
||||
// Don't compare the server-approve entity fields; they're hard to reconstruct
|
||||
// and logic later will check them.
|
||||
.build());
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,7 @@ import static google.registry.testing.DomainSubject.assertAboutDomains;
|
||||
import static google.registry.testing.EppExceptionSubject.assertAboutEppExceptions;
|
||||
import static google.registry.testing.HistoryEntrySubject.assertAboutHistoryEntries;
|
||||
import static google.registry.testing.HostSubject.assertAboutHosts;
|
||||
import static google.registry.testing.TestDataHelper.updateSubstitutions;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
import static org.joda.money.CurrencyUnit.JPY;
|
||||
import static org.joda.money.CurrencyUnit.USD;
|
||||
@@ -146,32 +147,16 @@ class DomainTransferRequestFlowTest
|
||||
.put("AMOUNT", "11.00")
|
||||
.put("CURRENCY", "USD")
|
||||
.build();
|
||||
private static final ImmutableMap<String, String> FEE_06_MAP =
|
||||
new ImmutableMap.Builder<String, String>()
|
||||
.putAll(BASE_FEE_MAP)
|
||||
.put("FEE_VERSION", "0.6")
|
||||
.put("FEE_NS", "fee")
|
||||
.build();
|
||||
private static final ImmutableMap<String, String> FEE_11_MAP =
|
||||
new ImmutableMap.Builder<String, String>()
|
||||
.putAll(BASE_FEE_MAP)
|
||||
.put("FEE_VERSION", "0.11")
|
||||
.put("FEE_NS", "fee11")
|
||||
.build();
|
||||
private static final ImmutableMap<String, String> FEE_12_MAP =
|
||||
new ImmutableMap.Builder<String, String>()
|
||||
.putAll(BASE_FEE_MAP)
|
||||
.put("FEE_VERSION", "0.12")
|
||||
.put("FEE_NS", "fee12")
|
||||
.build();
|
||||
private static final ImmutableMap<String, String> FEE_STD_1_0_MAP =
|
||||
updateSubstitutions(BASE_FEE_MAP, "FEE_VERSION", "epp:fee-1.0", "FEE_NS", "fee1_00");
|
||||
private static final ImmutableMap<String, String> RICH_DOMAIN_MAP =
|
||||
ImmutableMap.<String, String>builder()
|
||||
.put("DOMAIN", "rich.example")
|
||||
.put("YEARS", "1")
|
||||
.put("AMOUNT", "100.00")
|
||||
.put("CURRENCY", "USD")
|
||||
.put("FEE_VERSION", "0.12")
|
||||
.put("FEE_NS", "fee12")
|
||||
.put("FEE_VERSION", "epp:fee-1.0")
|
||||
.put("FEE_NS", "fee")
|
||||
.build();
|
||||
|
||||
@BeforeEach
|
||||
@@ -665,140 +650,50 @@ class DomainTransferRequestFlowTest
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v06() throws Exception {
|
||||
void testSuccess_fee_std_v1() throws Exception {
|
||||
setupDomain("example", "tld");
|
||||
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_STD_1_0_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v11() throws Exception {
|
||||
setupDomain("example", "tld");
|
||||
doSuccessfulTest(
|
||||
"domain_transfer_request_fee.xml", "domain_transfer_request_response_fee.xml", FEE_11_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_v12() throws Exception {
|
||||
setupDomain("example", "tld");
|
||||
doSuccessfulTest(
|
||||
"domain_transfer_request_fee.xml", "domain_transfer_request_response_fee.xml", FEE_12_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v06() throws Exception {
|
||||
void testSuccess_fee_withDefaultAttributes_std_v1() throws Exception {
|
||||
setupDomain("example", "tld");
|
||||
doSuccessfulTest(
|
||||
"domain_transfer_request_fee_defaults.xml",
|
||||
"domain_transfer_request_response_fee.xml",
|
||||
FEE_06_MAP);
|
||||
FEE_STD_1_0_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v11() throws Exception {
|
||||
setupDomain("example", "tld");
|
||||
doSuccessfulTest(
|
||||
"domain_transfer_request_fee_defaults.xml",
|
||||
"domain_transfer_request_response_fee.xml",
|
||||
FEE_11_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fee_withDefaultAttributes_v12() throws Exception {
|
||||
setupDomain("example", "tld");
|
||||
doSuccessfulTest(
|
||||
"domain_transfer_request_fee_defaults.xml",
|
||||
"domain_transfer_request_response_fee.xml",
|
||||
FEE_12_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v06() {
|
||||
void testFailure_refundableFee_std_v1() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
UnsupportedFeeAttributeException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_refundable.xml", FEE_06_MAP));
|
||||
() -> doFailingTest("domain_transfer_request_fee_refundable.xml", FEE_STD_1_0_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v11() {
|
||||
void testFailure_gracePeriodFee_std_v1() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
UnsupportedFeeAttributeException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_refundable.xml", FEE_11_MAP));
|
||||
() -> doFailingTest("domain_transfer_request_fee_grace_period.xml", FEE_STD_1_0_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_refundableFee_v12() {
|
||||
void testFailure_appliedFee_std_v1() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
UnsupportedFeeAttributeException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_refundable.xml", FEE_12_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v06() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
UnsupportedFeeAttributeException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_grace_period.xml", FEE_06_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v11() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
UnsupportedFeeAttributeException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_grace_period.xml", FEE_11_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gracePeriodFee_v12() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
UnsupportedFeeAttributeException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_grace_period.xml", FEE_12_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v06() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
UnsupportedFeeAttributeException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_applied.xml", FEE_06_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v11() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
UnsupportedFeeAttributeException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_applied.xml", FEE_11_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_appliedFee_v12() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
UnsupportedFeeAttributeException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_applied.xml", FEE_12_MAP));
|
||||
() -> doFailingTest("domain_transfer_request_fee_applied.xml", FEE_STD_1_0_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@@ -991,7 +886,7 @@ class DomainTransferRequestFlowTest
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_superuserExtension_zeroPeriod_feeTransferExtension() {
|
||||
void testFailure_superuserExtension_zeroPeriod_feeTransferExtension_std_v1() {
|
||||
setupDomain("example", "tld");
|
||||
eppRequestSource = EppRequestSource.TOOL;
|
||||
clock.advanceOneMilli();
|
||||
@@ -1001,7 +896,11 @@ class DomainTransferRequestFlowTest
|
||||
runTest(
|
||||
"domain_transfer_request_fee_and_superuser_extension.xml",
|
||||
UserPrivileges.SUPERUSER,
|
||||
ImmutableMap.of("PERIOD", "0", "AUTOMATIC_TRANSFER_LENGTH", "5")));
|
||||
new ImmutableMap.Builder<String, String>()
|
||||
.putAll(FEE_STD_1_0_MAP)
|
||||
.put("PERIOD", "0")
|
||||
.put("AUTOMATIC_TRANSFER_LENGTH", "5")
|
||||
.build()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1063,7 +962,7 @@ class DomainTransferRequestFlowTest
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_customLogicFee() throws Exception {
|
||||
void testSuccess_customLogicFee_std_v1() throws Exception {
|
||||
setupDomain("expensive-domain", "foo");
|
||||
clock.advanceOneMilli();
|
||||
doSuccessfulTest(
|
||||
@@ -1075,7 +974,7 @@ class DomainTransferRequestFlowTest
|
||||
.put("YEARS", "1")
|
||||
.put("AMOUNT", "111.00")
|
||||
.put("EXDATE", "2002-09-08T22:00:00.0Z")
|
||||
.put("FEE_VERSION", "0.6")
|
||||
.put("FEE_VERSION", "epp:fee-1.0")
|
||||
.put("FEE_NS", "fee")
|
||||
.build(),
|
||||
Optional.of(Money.of(USD, 111)));
|
||||
@@ -1227,7 +1126,7 @@ class DomainTransferRequestFlowTest
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_premiumNotBlocked() throws Exception {
|
||||
void testSuccess_premiumNotBlocked_v06() throws Exception {
|
||||
setupDomain("rich", "example");
|
||||
clock.advanceOneMilli();
|
||||
// We don't verify the results; just check that the flow doesn't fail.
|
||||
@@ -1235,7 +1134,7 @@ class DomainTransferRequestFlowTest
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_premiumNotBlockedInSuperuserMode() throws Exception {
|
||||
void testSuccess_premiumNotBlockedInSuperuserMode_std_v1() throws Exception {
|
||||
setupDomain("rich", "example");
|
||||
clock.advanceOneMilli();
|
||||
// Modify the Registrar to block premium names.
|
||||
@@ -1525,24 +1424,14 @@ class DomainTransferRequestFlowTest
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v06() {
|
||||
runWrongCurrencyTest(FEE_06_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v11() {
|
||||
runWrongCurrencyTest(FEE_11_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongCurrency_v12() {
|
||||
runWrongCurrencyTest(FEE_12_MAP);
|
||||
void testFailure_wrongCurrency_std_v1() {
|
||||
runWrongCurrencyTest(FEE_STD_1_0_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_unknownCurrency() {
|
||||
Map<String, String> substitutions = Maps.newHashMap();
|
||||
substitutions.putAll(FEE_06_MAP);
|
||||
substitutions.putAll(FEE_STD_1_0_MAP);
|
||||
substitutions.put("CURRENCY", "BAD");
|
||||
setupDomain("example", "tld");
|
||||
setEppInput("domain_transfer_request_fee.xml", substitutions);
|
||||
@@ -1551,32 +1440,12 @@ class DomainTransferRequestFlowTest
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v06() {
|
||||
void testFailure_feeGivenInWrongScale_std_v1() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
CurrencyValueScaleException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_bad_scale.xml", FEE_06_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v11() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
CurrencyValueScaleException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_bad_scale.xml", FEE_11_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_feeGivenInWrongScale_v12() {
|
||||
setupDomain("example", "tld");
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
CurrencyValueScaleException.class,
|
||||
() -> doFailingTest("domain_transfer_request_fee_bad_scale.xml", FEE_12_MAP));
|
||||
() -> doFailingTest("domain_transfer_request_fee_bad_scale.xml", FEE_STD_1_0_MAP));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@@ -1594,21 +1463,9 @@ class DomainTransferRequestFlowTest
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v06() {
|
||||
void testFailure_wrongFeeAmount_std_v1() {
|
||||
setupDomain("example", "tld");
|
||||
runWrongFeeAmountTest(FEE_06_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v11() {
|
||||
setupDomain("example", "tld");
|
||||
runWrongFeeAmountTest(FEE_11_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_wrongFeeAmount_v12() {
|
||||
setupDomain("example", "tld");
|
||||
runWrongFeeAmountTest(FEE_12_MAP);
|
||||
runWrongFeeAmountTest(FEE_STD_1_0_MAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -63,8 +63,6 @@ import google.registry.config.RegistryConfig;
|
||||
import google.registry.flows.EppException;
|
||||
import google.registry.flows.EppException.UnimplementedExtensionException;
|
||||
import google.registry.flows.EppRequestSource;
|
||||
import google.registry.flows.FlowTestCase.CommitMode;
|
||||
import google.registry.flows.FlowTestCase.UserPrivileges;
|
||||
import google.registry.flows.FlowUtils.NotLoggedInException;
|
||||
import google.registry.flows.ResourceFlowTestCase;
|
||||
import google.registry.flows.ResourceFlowUtils.AddExistingValueException;
|
||||
@@ -74,7 +72,6 @@ import google.registry.flows.ResourceFlowUtils.ResourceDoesNotExistException;
|
||||
import google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException;
|
||||
import google.registry.flows.ResourceFlowUtils.StatusNotClientSettableException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.EmptySecDnsUpdateException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.FeesMismatchException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.FeesRequiredForNonFreeOperationException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.InvalidDsRecordException;
|
||||
import google.registry.flows.domain.DomainFlowUtils.LinkedResourceInPendingDeleteProhibitsOperationException;
|
||||
@@ -361,10 +358,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||
}
|
||||
}
|
||||
persistResource(
|
||||
reloadResourceByForeignKey()
|
||||
.asBuilder()
|
||||
.setNameservers(nameservers.build())
|
||||
.build());
|
||||
reloadResourceByForeignKey().asBuilder().setNameservers(nameservers.build()).build());
|
||||
clock.advanceOneMilli();
|
||||
assertMutatingFlow(true);
|
||||
runFlowAssertResponse(loadFile("generic_success_response.xml"));
|
||||
@@ -454,6 +448,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||
|
||||
@Test
|
||||
void testSuccess_removeClientUpdateProhibited() throws Exception {
|
||||
setEppInput("domain_update_remove_client_update_prohibited.xml");
|
||||
persistReferencedEntities();
|
||||
persistResource(
|
||||
persistDomain()
|
||||
@@ -549,21 +544,26 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_secDnsAddSameDoesNothing() throws Exception {
|
||||
doSecDnsSuccessfulTest(
|
||||
"domain_update_dsdata_add.xml",
|
||||
ImmutableSet.of(SOME_DSDATA),
|
||||
ImmutableSet.of(SOME_DSDATA),
|
||||
ImmutableMap.of(
|
||||
"KEY_TAG",
|
||||
"1",
|
||||
"ALG",
|
||||
"2",
|
||||
"DIGEST_TYPE",
|
||||
"2",
|
||||
"DIGEST",
|
||||
"9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08"),
|
||||
false);
|
||||
void testFailure_secDnsAddSame_throwsException() throws Exception {
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
AddExistingValueException.class,
|
||||
() ->
|
||||
doSecDnsSuccessfulTest(
|
||||
"domain_update_dsdata_add.xml",
|
||||
ImmutableSet.of(SOME_DSDATA),
|
||||
ImmutableSet.of(SOME_DSDATA),
|
||||
ImmutableMap.of(
|
||||
"KEY_TAG",
|
||||
"1",
|
||||
"ALG",
|
||||
"2",
|
||||
"DIGEST_TYPE",
|
||||
"2",
|
||||
"DIGEST",
|
||||
"9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08"),
|
||||
false));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -681,7 +681,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||
2,
|
||||
2,
|
||||
base16()
|
||||
.decode("9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08"))),
|
||||
.decode("0F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08"))),
|
||||
ImmutableMap.of(
|
||||
"KEY_TAG",
|
||||
"1",
|
||||
@@ -690,8 +690,8 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||
"DIGEST_TYPE",
|
||||
"2",
|
||||
"DIGEST",
|
||||
"9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08"),
|
||||
false);
|
||||
"0F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08"),
|
||||
true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -799,29 +799,43 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_secDnsAddRemoveSame() throws Exception {
|
||||
// Adding and removing the same dsData is a no-op because removes are processed first.
|
||||
doSecDnsSuccessfulTest(
|
||||
"domain_update_dsdata_add_rem_same.xml",
|
||||
ImmutableSet.of(
|
||||
SOME_DSDATA,
|
||||
DomainDsData.create(
|
||||
12345, 3, 1, base16().decode("A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"))),
|
||||
ImmutableSet.of(
|
||||
SOME_DSDATA,
|
||||
DomainDsData.create(
|
||||
12345, 3, 1, base16().decode("A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"))),
|
||||
false);
|
||||
void testFailure_secDnsAddRemoveSame_throwsException() throws Exception {
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
AddRemoveSameValueException.class,
|
||||
() ->
|
||||
doSecDnsSuccessfulTest(
|
||||
"domain_update_dsdata_add_rem_same.xml",
|
||||
ImmutableSet.of(
|
||||
SOME_DSDATA,
|
||||
DomainDsData.create(
|
||||
12345,
|
||||
3,
|
||||
1,
|
||||
base16().decode("A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"))),
|
||||
ImmutableSet.of(
|
||||
SOME_DSDATA,
|
||||
DomainDsData.create(
|
||||
12345,
|
||||
3,
|
||||
1,
|
||||
base16().decode("A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"))),
|
||||
false));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_secDnsRemoveAlreadyNotThere() throws Exception {
|
||||
// Removing a dsData that isn't there is a no-op.
|
||||
doSecDnsSuccessfulTest(
|
||||
"domain_update_dsdata_rem.xml",
|
||||
ImmutableSet.of(SOME_DSDATA),
|
||||
ImmutableSet.of(SOME_DSDATA),
|
||||
false);
|
||||
void testFailure_secDnsRemoveAlreadyNotThere_throwsException() throws Exception {
|
||||
EppException thrown =
|
||||
assertThrows(
|
||||
RemoveNonexistentValueException.class,
|
||||
() ->
|
||||
doSecDnsSuccessfulTest(
|
||||
"domain_update_dsdata_rem.xml",
|
||||
ImmutableSet.of(SOME_DSDATA),
|
||||
ImmutableSet.of(SOME_DSDATA),
|
||||
false));
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
void doServerStatusBillingTest(String xmlFilename, boolean isBillable) throws Exception {
|
||||
@@ -856,14 +870,6 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||
doServerStatusBillingTest("domain_update_add_server_status.xml", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_noBillingOnPreExistingServerStatus() throws Exception {
|
||||
eppRequestSource = EppRequestSource.TOOL;
|
||||
Domain addStatusDomain = persistActiveDomain(getUniqueIdFromCommand());
|
||||
persistResource(addStatusDomain.asBuilder().addStatusValue(SERVER_RENEW_PROHIBITED).build());
|
||||
doServerStatusBillingTest("domain_update_add_server_status.xml", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_removeServerStatusBillingEvent() throws Exception {
|
||||
eppRequestSource = EppRequestSource.TOOL;
|
||||
@@ -1390,7 +1396,20 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_removeNonexistentValue() throws Exception {
|
||||
void testFailure_addExistingStatusValue() throws Exception {
|
||||
persistResource(
|
||||
DatabaseHelper.newDomain(getUniqueIdFromCommand())
|
||||
.asBuilder()
|
||||
.setStatusValues(ImmutableSet.of(CLIENT_RENEW_PROHIBITED))
|
||||
.build());
|
||||
setEppInput("domain_update_add_non_server_status.xml");
|
||||
assertAboutEppExceptions()
|
||||
.that(assertThrows(AddExistingValueException.class, this::runFlow))
|
||||
.marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_removeNonexistentNameserver() throws Exception {
|
||||
persistActiveDomain(getUniqueIdFromCommand());
|
||||
persistActiveHost("ns1.example.foo");
|
||||
setEppInput("domain_update_remove_nameserver.xml");
|
||||
@@ -1399,6 +1418,15 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||
.marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_removeNonexistentStatusValue() throws Exception {
|
||||
persistActiveDomain(getUniqueIdFromCommand());
|
||||
setEppInput("domain_update_remove_client_update_prohibited.xml");
|
||||
assertAboutEppExceptions()
|
||||
.that(assertThrows(RemoveNonexistentValueException.class, this::runFlow))
|
||||
.marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_minimumDataset_addingNewRegistrantFails() throws Exception {
|
||||
persistReferencedEntities();
|
||||
@@ -1502,15 +1530,6 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||
assertAboutDomains().that(reloadResourceByForeignKey()).hasExactlyStatusValues(CLIENT_HOLD);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_freePremium_wrongFee() throws Exception {
|
||||
setEppInput("domain_update_fee.xml", ImmutableMap.of("FEE_VERSION", "0.11"));
|
||||
persistReferencedEntities();
|
||||
persistDomain();
|
||||
EppException thrown = assertThrows(FeesMismatchException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
// This test should throw an exception, because the fee extension is required when the fee is not
|
||||
// zero.
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
// Copyright 2026 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.flows.domain;
|
||||
|
||||
import google.registry.flows.Flow;
|
||||
import google.registry.flows.ResourceFlowTestCase;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.eppcommon.EppXmlTransformer;
|
||||
import google.registry.model.eppcommon.ProtocolDefinition;
|
||||
import google.registry.util.RegistryEnvironment;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
/**
|
||||
* Abstract class for tests that require old versions of the fee extension (0.6, 0.11, 0.12).
|
||||
*
|
||||
* <p>These are enabled only in the production environment so in order to test them, we need to
|
||||
* simulate the production environment for each test (and reset it to the test environment
|
||||
* afterward).
|
||||
*/
|
||||
public abstract class ProductionSimulatingFeeExtensionsTest<F extends Flow>
|
||||
extends ResourceFlowTestCase<F, Domain> {
|
||||
|
||||
private RegistryEnvironment previousEnvironment;
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
previousEnvironment = RegistryEnvironment.get();
|
||||
RegistryEnvironment.PRODUCTION.setup();
|
||||
reloadServiceExtensionUris();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
previousEnvironment.setup();
|
||||
reloadServiceExtensionUris();
|
||||
}
|
||||
|
||||
void reloadServiceExtensionUris() {
|
||||
ProtocolDefinition.reloadServiceExtensionUris();
|
||||
sessionMetadata.setServiceExtensionUris(ProtocolDefinition.getVisibleServiceExtensionUris());
|
||||
EppXmlTransformer.reloadTransformers();
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,7 @@ import google.registry.flows.host.HostFlowUtils.HostNameNotNormalizedException;
|
||||
import google.registry.flows.host.HostFlowUtils.HostNameNotPunyCodedException;
|
||||
import google.registry.flows.host.HostFlowUtils.HostNameTooLongException;
|
||||
import google.registry.flows.host.HostFlowUtils.HostNameTooShallowException;
|
||||
import google.registry.flows.host.HostFlowUtils.InvalidHostNameException;
|
||||
import google.registry.flows.host.HostFlowUtils.LoopbackIpNotValidForHostException;
|
||||
import google.registry.flows.host.HostFlowUtils.SuperordinateDomainDoesNotExistException;
|
||||
import google.registry.flows.host.HostFlowUtils.SuperordinateDomainInPendingDeleteException;
|
||||
@@ -82,9 +83,14 @@ class HostCreateFlowTest extends ResourceFlowTestCase<HostCreateFlow, Host> {
|
||||
}
|
||||
|
||||
private void doSuccessfulTest() throws Exception {
|
||||
doSuccessfulTest("host_create_response.xml", ImmutableMap.of());
|
||||
}
|
||||
|
||||
private void doSuccessfulTest(String responseFile, ImmutableMap<String, String> substitutions)
|
||||
throws Exception {
|
||||
clock.advanceOneMilli();
|
||||
assertMutatingFlow(true);
|
||||
runFlowAssertResponse(loadFile("host_create_response.xml"));
|
||||
runFlowAssertResponse(loadFile(responseFile, substitutions));
|
||||
Host host = reloadResourceByForeignKey();
|
||||
// Check that the host was created and persisted with a history entry.
|
||||
assertAboutHosts()
|
||||
@@ -134,6 +140,28 @@ class HostCreateFlowTest extends ResourceFlowTestCase<HostCreateFlow, Host> {
|
||||
assertHostDnsRequests("ns1.example.tld");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_tldWithHyphenOn3And4() throws Exception {
|
||||
setEppHostCreateInput("ns1.example.zz--main-2262", null);
|
||||
doSuccessfulTest(
|
||||
"host_create_response_wildcard.xml",
|
||||
ImmutableMap.of("HOSTNAME", "ns1.example.zz--main-2262"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_domainWithHyphenOn3And4() throws Exception {
|
||||
setEppHostCreateInput("ns1.zz--main-2262.tld", null);
|
||||
EppException thrown = assertThrows(InvalidHostNameException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_hostnameWithHyphenOn3And4() throws Exception {
|
||||
setEppHostCreateInput("zz--ns1.domain.tld", null);
|
||||
EppException thrown = assertThrows(InvalidHostNameException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_multipartTLDsAndInvalidHost() {
|
||||
createTlds("bar.tld", "tld");
|
||||
|
||||
@@ -24,12 +24,9 @@ import google.registry.testing.EppLoader;
|
||||
/** Unit tests for {@code ResourceCommand}. */
|
||||
public abstract class ResourceCommandTestCase extends EntityTestCase {
|
||||
|
||||
protected void doXmlRoundtripTest(String inputFilename, String... ignoredPaths)
|
||||
throws Exception {
|
||||
protected void doXmlRoundtripTest(String inputFilename) throws Exception {
|
||||
EppLoader eppLoader = new EppLoader(this, inputFilename);
|
||||
assertXmlEquals(
|
||||
eppLoader.getEppXml(),
|
||||
new String(marshalInput(eppLoader.getEpp(), STRICT), UTF_8),
|
||||
ignoredPaths);
|
||||
eppLoader.getEppXml(), new String(marshalInput(eppLoader.getEpp(), STRICT), UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,11 +113,6 @@ class DomainCommandTest extends ResourceCommandTestCase {
|
||||
doXmlRoundtripTest("domain_update.xml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdate_fee() throws Exception {
|
||||
doXmlRoundtripTest("domain_update_fee.xml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdate_emptyCommand() throws Exception {
|
||||
// This EPP command wouldn't be allowed for policy reasons, but should marshal/unmarshal fine.
|
||||
@@ -153,11 +148,6 @@ class DomainCommandTest extends ResourceCommandTestCase {
|
||||
doXmlRoundtripTest("domain_info_sunrise.xml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInfo_feeExtension() throws Exception {
|
||||
doXmlRoundtripTest("domain_info_fee.xml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheck() throws Exception {
|
||||
doXmlRoundtripTest("domain_check.xml");
|
||||
|
||||
@@ -68,10 +68,7 @@ class EppInputTest {
|
||||
assertThat(loginCommand.options.version).isEqualTo("1.0");
|
||||
assertThat(loginCommand.options.language).isEqualTo("en");
|
||||
assertThat(loginCommand.services.objectServices)
|
||||
.containsExactly(
|
||||
"urn:ietf:params:xml:ns:host-1.0",
|
||||
"urn:ietf:params:xml:ns:domain-1.0",
|
||||
"urn:ietf:params:xml:ns:contact-1.0");
|
||||
.containsExactly("urn:ietf:params:xml:ns:host-1.0", "urn:ietf:params:xml:ns:domain-1.0");
|
||||
assertThat(loginCommand.services.serviceExtensions)
|
||||
.containsExactly("urn:ietf:params:xml:ns:launch-1.0", "urn:ietf:params:xml:ns:rgp-1.0");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<response>
|
||||
<result code="1000">
|
||||
<msg>Command completed successfully</msg>
|
||||
</result>
|
||||
<resData>
|
||||
<domain:chkData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:cd>
|
||||
<domain:name avail="true">example1.tld</domain:name>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example2.example</domain:name>
|
||||
<domain:reason>Alloc token invalid for domain</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">reserved.tld</domain:name>
|
||||
<domain:reason>Alloc token invalid for domain</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">rich.example</domain:name>
|
||||
<domain:reason>Alloc token invalid for domain</domain:reason>
|
||||
</domain:cd>
|
||||
</domain:chkData>
|
||||
</resData>
|
||||
<extension>
|
||||
<fee:chkData xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:cd>
|
||||
<fee:objID>example1.tld</fee:objID>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="create">0.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example2.example</fee:objID>
|
||||
<fee:class>token-not-supported</fee:class>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>reserved.tld</fee:objID>
|
||||
<fee:class>token-not-supported</fee:class>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>rich.example</fee:objID>
|
||||
<fee:class>token-not-supported</fee:class>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example1.tld</fee:objID>
|
||||
<fee:class>premium</fee:class>
|
||||
<fee:command name="renew">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example2.example</fee:objID>
|
||||
<fee:class>token-not-supported</fee:class>
|
||||
<fee:command name="renew">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>reserved.tld</fee:objID>
|
||||
<fee:class>token-not-supported</fee:class>
|
||||
<fee:command name="renew">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>rich.example</fee:objID>
|
||||
<fee:class>token-not-supported</fee:class>
|
||||
<fee:command name="renew">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
</fee:chkData>
|
||||
</extension>
|
||||
<trID>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
<svTRID>server-trid</svTRID>
|
||||
</trID>
|
||||
</response>
|
||||
</epp>
|
||||
@@ -0,0 +1,91 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<response>
|
||||
<result code="1000">
|
||||
<msg>Command completed successfully</msg>
|
||||
</result>
|
||||
<resData>
|
||||
<domain:chkData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:cd>
|
||||
<domain:name avail="true">example1.tld</domain:name>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="true">example2.example</domain:name>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">reserved.tld</domain:name>
|
||||
<domain:reason>Reserved</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="true">rich.example</domain:name>
|
||||
</domain:cd>
|
||||
</domain:chkData>
|
||||
</resData>
|
||||
<extension>
|
||||
<fee:chkData xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:cd>
|
||||
<fee:objID>example2.example</fee:objID>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="create">6.50</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example1.tld</fee:objID>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="create">6.50</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>reserved.tld</fee:objID>
|
||||
<fee:class>reserved</fee:class>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>rich.example</fee:objID>
|
||||
<fee:class>premium</fee:class>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="create">100.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example1.tld</fee:objID>
|
||||
<fee:command name="renew">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example2.example</fee:objID>
|
||||
<fee:command name="renew">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>reserved.tld</fee:objID>
|
||||
<fee:command name="renew">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>rich.example</fee:objID>
|
||||
<fee:class>premium</fee:class>
|
||||
<fee:command name="renew">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="renew">100.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
</fee:chkData>
|
||||
</extension>
|
||||
<trID>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
<svTRID>server-trid</svTRID>
|
||||
</trID>
|
||||
</response>
|
||||
</epp>
|
||||
@@ -0,0 +1,63 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<response>
|
||||
<result code="1000">
|
||||
<msg>Command completed successfully</msg>
|
||||
</result>
|
||||
<resData>
|
||||
<domain:chkData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example1.tld</domain:name>
|
||||
<domain:reason>Alloc token invalid for domain</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example2.example</domain:name>
|
||||
<domain:reason>Alloc token invalid for domain</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">reserved.tld</domain:name>
|
||||
<domain:reason>Alloc token invalid for domain</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="true">specificuse.tld</domain:name>
|
||||
</domain:cd>
|
||||
</domain:chkData>
|
||||
</resData>
|
||||
<extension>
|
||||
<fee:chkData xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:cd>
|
||||
<fee:objID>example1.tld</fee:objID>
|
||||
<fee:class>token-not-supported</fee:class>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example2.example</fee:objID>
|
||||
<fee:class>token-not-supported</fee:class>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>reserved.tld</fee:objID>
|
||||
<fee:class>token-not-supported</fee:class>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>specificuse.tld</fee:objID>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="create">13.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
</fee:chkData>
|
||||
</extension>
|
||||
<trID>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
<svTRID>server-trid</svTRID>
|
||||
</trID>
|
||||
</response>
|
||||
</epp>
|
||||
@@ -0,0 +1,26 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<check>
|
||||
<domain:check
|
||||
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>example1.tld</domain:name>
|
||||
<domain:name>example2.example</domain:name>
|
||||
<domain:name>reserved.tld</domain:name>
|
||||
<domain:name>specificuse.tld</domain:name>
|
||||
</domain:check>
|
||||
</check>
|
||||
<extension>
|
||||
<allocationToken:allocationToken
|
||||
xmlns:allocationToken=
|
||||
"urn:ietf:params:xml:ns:allocationToken-1.0">
|
||||
abc123
|
||||
</allocationToken:allocationToken>
|
||||
<fee:check
|
||||
xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:command name="create" />
|
||||
</fee:check>
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -0,0 +1,27 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<check>
|
||||
<domain:check
|
||||
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>example1.tld</domain:name>
|
||||
<domain:name>example2.example</domain:name>
|
||||
<domain:name>reserved.tld</domain:name>
|
||||
<domain:name>rich.example</domain:name>
|
||||
</domain:check>
|
||||
</check>
|
||||
<extension>
|
||||
<allocationToken:allocationToken
|
||||
xmlns:allocationToken=
|
||||
"urn:ietf:params:xml:ns:allocationToken-1.0">
|
||||
abc123
|
||||
</allocationToken:allocationToken>
|
||||
<fee:check
|
||||
xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:command name="create" />
|
||||
<fee:command name="renew" />
|
||||
</fee:check>
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -17,4 +17,4 @@
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
</epp>
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<response>
|
||||
<result code="1000">
|
||||
<msg>Command completed successfully</msg>
|
||||
</result>
|
||||
<resData>
|
||||
<domain:chkData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:cd>
|
||||
<domain:name avail="true">%DOMAIN%</domain:name>
|
||||
</domain:cd>
|
||||
</domain:chkData>
|
||||
</resData>
|
||||
<extension>
|
||||
<fee:chkData xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:cd>
|
||||
<fee:objID>%DOMAIN%</fee:objID>
|
||||
%FEE_CLASS%
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="create">%COST_1YR%</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>%DOMAIN%</fee:objID>
|
||||
%FEE_CLASS%
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">2</fee:period>
|
||||
<fee:fee description="create">%COST_2YR%</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>%DOMAIN%</fee:objID>
|
||||
%FEE_CLASS%
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">5</fee:period>
|
||||
<fee:fee description="create">%COST_5YR%</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
</fee:chkData>
|
||||
</extension>
|
||||
<trID>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
<svTRID>server-trid</svTRID>
|
||||
</trID>
|
||||
</response>
|
||||
</epp>
|
||||
@@ -0,0 +1,31 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<check>
|
||||
<domain:check
|
||||
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>%DOMAIN%</domain:name>
|
||||
</domain:check>
|
||||
</check>
|
||||
<extension>
|
||||
<allocationToken:allocationToken
|
||||
xmlns:allocationToken=
|
||||
"urn:ietf:params:xml:ns:allocationToken-1.0">
|
||||
abc123
|
||||
</allocationToken:allocationToken>
|
||||
<fee:check
|
||||
xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:command>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">2</fee:period>
|
||||
</fee:command>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">5</fee:period>
|
||||
</fee:command>
|
||||
</fee:check>
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -0,0 +1,23 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<check>
|
||||
<domain:check xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>example1.tld</domain:name>
|
||||
<domain:name>example2.tld</domain:name>
|
||||
<domain:name>example3.tld</domain:name>
|
||||
</domain:check>
|
||||
</check>
|
||||
<extension>
|
||||
<launch:check xmlns:launch="urn:ietf:params:xml:ns:launch-1.0" type="avail">
|
||||
<launch:phase name="foo">custom</launch:phase>
|
||||
</launch:check>
|
||||
<fee:check xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:currency>BAD</fee:currency>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:command>
|
||||
</fee:check>
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -0,0 +1,18 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<check>
|
||||
<domain:check xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>example1.tld</domain:name>
|
||||
</domain:check>
|
||||
</check>
|
||||
<extension>
|
||||
<fee:check xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="m">1</fee:period>
|
||||
</fee:command>
|
||||
</fee:check>
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -0,0 +1,15 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<check>
|
||||
<domain:check xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>example1.tld</domain:name>
|
||||
</domain:check>
|
||||
</check>
|
||||
<extension>
|
||||
<fee:check xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:command name="create" phase="claims" />
|
||||
</fee:check>
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -0,0 +1,15 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<check>
|
||||
<domain:check xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>example1.tld</domain:name>
|
||||
</domain:check>
|
||||
</check>
|
||||
<extension>
|
||||
<fee:check xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:command name="create" subphase="landrush" />
|
||||
</fee:check>
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -0,0 +1,23 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<check>
|
||||
<domain:check xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>example1.tld</domain:name>
|
||||
<domain:name>example2.tld</domain:name>
|
||||
<domain:name>example3.tld</domain:name>
|
||||
</domain:check>
|
||||
</check>
|
||||
<extension>
|
||||
<launch:check xmlns:launch="urn:ietf:params:xml:ns:launch-1.0" type="avail">
|
||||
<launch:phase name="foo">custom</launch:phase>
|
||||
</launch:check>
|
||||
<fee:check xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:currency>EUR</fee:currency>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:command>
|
||||
</fee:check>
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -0,0 +1,30 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<response>
|
||||
<result code="1000">
|
||||
<msg>Command completed successfully</msg>
|
||||
</result>
|
||||
<resData>
|
||||
<domain:chkData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:cd>
|
||||
<domain:name avail="1">example1.tld</domain:name>
|
||||
</domain:cd>
|
||||
</domain:chkData>
|
||||
</resData>
|
||||
<extension>
|
||||
<fee:chkData xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:cd>
|
||||
<fee:objID>example1.tld</fee:objID>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="create">11.10</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
</fee:chkData>
|
||||
</extension>
|
||||
<trID>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
<svTRID>server-trid</svTRID>
|
||||
</trID>
|
||||
</response>
|
||||
</epp>
|
||||
@@ -0,0 +1,21 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<check>
|
||||
<domain:check xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>example1.tld</domain:name>
|
||||
</domain:check>
|
||||
</check>
|
||||
<extension>
|
||||
<launch:check xmlns:launch="urn:ietf:params:xml:ns:launch-1.0" type="avail">
|
||||
<launch:phase name="foo">custom</launch:phase>
|
||||
</launch:check>
|
||||
<fee:check xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:command>
|
||||
</fee:check>
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -6,7 +6,7 @@
|
||||
</domain:check>
|
||||
</check>
|
||||
<extension>
|
||||
<fee:check xmlns:fee="urn:ietf:params:xml:ns:fee-0.12">
|
||||
<fee:check xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:command name="Create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:command>
|
||||
|
||||
@@ -36,4 +36,4 @@
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
</epp>
|
||||
|
||||
@@ -42,4 +42,4 @@
|
||||
<svTRID>server-trid</svTRID>
|
||||
</trID>
|
||||
</response>
|
||||
</epp>
|
||||
</epp>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<check>
|
||||
<domain:check xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>example1.tld</domain:name>
|
||||
</domain:check>
|
||||
</check>
|
||||
<extension>
|
||||
<launch:check xmlns:launch="urn:ietf:params:xml:ns:launch-1.0" type="avail">
|
||||
<launch:phase name="foo">custom</launch:phase>
|
||||
</launch:check>
|
||||
<fee:check xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">2</fee:period>
|
||||
</fee:command>
|
||||
</fee:check>
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -0,0 +1,20 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<check>
|
||||
<domain:check xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>example1.tld</domain:name>
|
||||
</domain:check>
|
||||
</check>
|
||||
<extension>
|
||||
<launch:check xmlns:launch="urn:ietf:params:xml:ns:launch-1.0" type="avail">
|
||||
<launch:phase name="foo">custom</launch:phase>
|
||||
</launch:check>
|
||||
<fee:check xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:command name="transfer">
|
||||
<fee:period unit="y">2</fee:period>
|
||||
</fee:command>
|
||||
</fee:check>
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -0,0 +1,378 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<response>
|
||||
<result code="1000">
|
||||
<msg>Command completed successfully</msg>
|
||||
</result>
|
||||
<resData>
|
||||
<domain:chkData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:cd>
|
||||
<domain:name avail="true">example-00.tld</domain:name>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-01.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-02.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-03.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-04.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-05.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-06.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-07.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-08.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-09.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-10.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-11.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-12.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-13.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-14.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-15.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-16.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-17.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-18.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-19.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-20.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-21.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-22.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-23.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-24.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-25.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-26.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-27.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-28.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example-29.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
</domain:chkData>
|
||||
</resData>
|
||||
<extension>
|
||||
<fee:chkData xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:cd>
|
||||
<fee:objID>example-00.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-01.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-02.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-03.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-04.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-05.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-06.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-07.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-08.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-09.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-10.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-11.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-12.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-13.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-14.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-15.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-16.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-17.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-18.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-19.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-20.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-21.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-22.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-23.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-24.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-25.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-26.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-27.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-28.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example-29.tld</fee:objID>
|
||||
<fee:command name="restore">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="restore">17.00</fee:fee>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
</fee:chkData>
|
||||
</extension>
|
||||
<trID>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
<svTRID>server-trid</svTRID>
|
||||
</trID>
|
||||
</response>
|
||||
</epp>
|
||||
@@ -0,0 +1,48 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<check>
|
||||
<domain:check xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>example-00.tld</domain:name>
|
||||
<domain:name>example-01.tld</domain:name>
|
||||
<domain:name>example-02.tld</domain:name>
|
||||
<domain:name>example-03.tld</domain:name>
|
||||
<domain:name>example-04.tld</domain:name>
|
||||
<domain:name>example-05.tld</domain:name>
|
||||
<domain:name>example-06.tld</domain:name>
|
||||
<domain:name>example-07.tld</domain:name>
|
||||
<domain:name>example-08.tld</domain:name>
|
||||
<domain:name>example-09.tld</domain:name>
|
||||
<domain:name>example-10.tld</domain:name>
|
||||
<domain:name>example-11.tld</domain:name>
|
||||
<domain:name>example-12.tld</domain:name>
|
||||
<domain:name>example-13.tld</domain:name>
|
||||
<domain:name>example-14.tld</domain:name>
|
||||
<domain:name>example-15.tld</domain:name>
|
||||
<domain:name>example-16.tld</domain:name>
|
||||
<domain:name>example-17.tld</domain:name>
|
||||
<domain:name>example-18.tld</domain:name>
|
||||
<domain:name>example-19.tld</domain:name>
|
||||
<domain:name>example-20.tld</domain:name>
|
||||
<domain:name>example-21.tld</domain:name>
|
||||
<domain:name>example-22.tld</domain:name>
|
||||
<domain:name>example-23.tld</domain:name>
|
||||
<domain:name>example-24.tld</domain:name>
|
||||
<domain:name>example-25.tld</domain:name>
|
||||
<domain:name>example-26.tld</domain:name>
|
||||
<domain:name>example-27.tld</domain:name>
|
||||
<domain:name>example-28.tld</domain:name>
|
||||
<domain:name>example-29.tld</domain:name>
|
||||
</domain:check>
|
||||
</check>
|
||||
<extension>
|
||||
<launch:check xmlns:launch="urn:ietf:params:xml:ns:launch-1.0" type="avail">
|
||||
<launch:phase name="foo">custom</launch:phase>
|
||||
</launch:check>
|
||||
<fee:check xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:command name="restore"/>
|
||||
</fee:check>
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -0,0 +1,17 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<check>
|
||||
<domain:check xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>example1.tld</domain:name>
|
||||
</domain:check>
|
||||
</check>
|
||||
<extension>
|
||||
<fee:check xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:command name="delete">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:command>
|
||||
</fee:check>
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -0,0 +1,78 @@
|
||||
<epp xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" xmlns:contact="urn:ietf:params:xml:ns:contact-1.0" xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:rgp="urn:ietf:params:xml:ns:rgp-1.0" xmlns:bulkToken="urn:google:params:xml:ns:bulkToken-1.0" xmlns:fee="urn:ietf:params:xml:ns:fee-0.12" xmlns:launch="urn:ietf:params:xml:ns:launch-1.0" xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1" xmlns:host="urn:ietf:params:xml:ns:host-1.0">
|
||||
<response>
|
||||
<result code="1000">
|
||||
<msg>Command completed successfully</msg>
|
||||
</result>
|
||||
<resData>
|
||||
<domain:chkData>
|
||||
<domain:cd>
|
||||
<domain:name avail="false">example1.tld</domain:name>
|
||||
<domain:reason>In use</domain:reason>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="true">example2.tld</domain:name>
|
||||
</domain:cd>
|
||||
<domain:cd>
|
||||
<domain:name avail="true">example3.tld</domain:name>
|
||||
</domain:cd>
|
||||
</domain:chkData>
|
||||
</resData>
|
||||
<extension>
|
||||
<fee:chkData xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:cd>
|
||||
<fee:objID>example1.tld</fee:objID>
|
||||
<fee:class>STANDARD</fee:class>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="create">13.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example1.tld</fee:objID>
|
||||
<fee:class>STANDARD PROMOTION</fee:class>
|
||||
<fee:command name="custom">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="create">6.50</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example2.tld</fee:objID>
|
||||
<fee:class>STANDARD</fee:class>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="create">13.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example2.tld</fee:objID>
|
||||
<fee:class>STANDARD PROMOTION</fee:class>
|
||||
<fee:command name="custom">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="create">6.50</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example3.tld</fee:objID>
|
||||
<fee:class>STANDARD</fee:class>
|
||||
<fee:command name="create">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="create">13.00</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:objID>example3.tld</fee:objID>
|
||||
<fee:class>STANDARD PROMOTION</fee:class>
|
||||
<fee:command name="custom">
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="create">6.50</fee:fee>
|
||||
</fee:command>
|
||||
</fee:cd>
|
||||
</fee:chkData>
|
||||
</extension>
|
||||
<trID>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
<svTRID>server-trid</svTRID>
|
||||
</trID>
|
||||
</response>
|
||||
</epp>
|
||||
@@ -88,4 +88,4 @@
|
||||
<svTRID>server-trid</svTRID>
|
||||
</trID>
|
||||
</response>
|
||||
</epp>
|
||||
</epp>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</domain:create>
|
||||
</create>
|
||||
<extension>
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:fee-0.6">
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee>126.00</fee:fee>
|
||||
</fee:create>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</domain:create>
|
||||
</create>
|
||||
<extension>
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee description="%DESCRIPTION_1%">24.00</fee:fee>
|
||||
<fee:fee description="%DESCRIPTION_2%">100.00</fee:fee>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</domain:create>
|
||||
</create>
|
||||
<extension>
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee description="%DESCRIPTION_1%">%FEE_1%</fee:fee>
|
||||
<fee:fee description="%DESCRIPTION_2%">%FEE_2%</fee:fee>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</domain:create>
|
||||
</create>
|
||||
<extension>
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>%CURRENCY%</fee:currency>
|
||||
<fee:fee>24.00</fee:fee>
|
||||
</fee:create>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</domain:create>
|
||||
</create>
|
||||
<extension>
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee applied="delayed">26.00</fee:fee>
|
||||
</fee:create>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</domain:create>
|
||||
</create>
|
||||
<extension>
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee>26.000</fee:fee>
|
||||
</fee:create>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</domain:create>
|
||||
</create>
|
||||
<extension>
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee refundable="true" grace-period="P0D" applied="immediate">24.00</fee:fee>
|
||||
</fee:create>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</domain:create>
|
||||
</create>
|
||||
<extension>
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee grace-period="P1D">26.00</fee:fee>
|
||||
</fee:create>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</domain:create>
|
||||
</create>
|
||||
<extension>
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee refundable="false">26.00</fee:fee>
|
||||
</fee:create>
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<epp xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" xmlns="urn:ietf:params:xml:ns:epp-1.0"
|
||||
xmlns:fee12="urn:ietf:params:xml:ns:fee-0.12"
|
||||
>
|
||||
<epp xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<response>
|
||||
<result code="1000">
|
||||
<msg>Command completed successfully</msg>
|
||||
@@ -14,14 +11,14 @@
|
||||
</domain:creData>
|
||||
</resData>
|
||||
<extension>
|
||||
<fee12:creData>
|
||||
<fee12:currency>USD</fee12:currency>
|
||||
<fee12:fee description="create">13.00</fee12:fee>
|
||||
</fee12:creData>
|
||||
<fee:creData xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee description="create">13.00</fee:fee>
|
||||
</fee:creData>
|
||||
</extension>
|
||||
<trID>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
<svTRID>server-trid</svTRID>
|
||||
</trID>
|
||||
</response>
|
||||
</epp>
|
||||
</epp>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</domain:create>
|
||||
</create>
|
||||
<extension>
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:fee-0.12">
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee>200.00</fee:fee>
|
||||
</fee:create>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"urn:ietf:params:xml:ns:allocationToken-1.0">
|
||||
abc123
|
||||
</allocationToken:allocationToken>
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:fee-0.12">
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee>%FEE%</fee:fee>
|
||||
</fee:create>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</domain:create>
|
||||
</create>
|
||||
<extension>
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:fee-0.6">
|
||||
<fee:create xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee description="create">200.00</fee:fee>
|
||||
<fee:fee description="Early Access Period">100.00</fee:fee>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</domain:creData>
|
||||
</resData>
|
||||
<extension>
|
||||
<fee:creData xmlns:fee="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
<fee:creData xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee description="create">24.00</fee:fee>
|
||||
<fee:fee description="Early Access Period, fee expires: 1999-04-04T22:00:00.023Z">100.00</fee:fee>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</domain:creData>
|
||||
</resData>
|
||||
<extension>
|
||||
<fee:creData xmlns:fee="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
<fee:creData xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee description="create">%FEE%</fee:fee>
|
||||
</fee:creData>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</domain:creData>
|
||||
</resData>
|
||||
<extension>
|
||||
<fee:creData xmlns:fee="urn:ietf:params:xml:ns:fee-0.12">
|
||||
<fee:creData xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee description="create">%FEE%</fee:fee>
|
||||
</fee:creData>
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
<resData>
|
||||
<domain:creData
|
||||
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>%DOMAIN%</domain:name>
|
||||
<domain:name>rich.example</domain:name>
|
||||
<domain:crDate>1999-04-03T22:00:00.0Z</domain:crDate>
|
||||
<domain:exDate>2001-04-03T22:00:00.0Z</domain:exDate>
|
||||
</domain:creData>
|
||||
</resData>
|
||||
<extension>
|
||||
<fee:creData xmlns:fee="urn:ietf:params:xml:ns:fee-0.6">
|
||||
<fee:creData xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee description="create">200.00</fee:fee>
|
||||
<fee:fee description="Early Access Period, fee expires: 1999-04-04T22:00:00.027Z">100.00
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
</result>
|
||||
<extension>
|
||||
<fee:delData
|
||||
xmlns:fee="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:credit description="autoRenewPeriod credit">-11.00</fee:credit>
|
||||
</fee:delData>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
</result>
|
||||
<extension>
|
||||
<fee:delData
|
||||
xmlns:fee="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:credit description="addPeriod credit">-123.00</fee:credit>
|
||||
</fee:delData>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<response>
|
||||
<result code="1000">
|
||||
<msg>Command completed successfully</msg>
|
||||
</result>
|
||||
<extension>
|
||||
<fee:delData
|
||||
xmlns:fee="urn:ietf:params:xml:ns:epp:fee-1.0">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:credit description="addPeriod credit">0.00</fee:credit>
|
||||
</fee:delData>
|
||||
</extension>
|
||||
<trID>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
<svTRID>server-trid</svTRID>
|
||||
</trID>
|
||||
</response>
|
||||
</epp>
|
||||
@@ -5,7 +5,7 @@
|
||||
</result>
|
||||
<extension>
|
||||
<fee:delData
|
||||
xmlns:fee="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:credit description="renewPeriod credit">-456.00</fee:credit>
|
||||
</fee:delData>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</domain:renew>
|
||||
</renew>
|
||||
<extension>
|
||||
<fee:renew xmlns:fee="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
<fee:renew xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>%CURRENCY%</fee:currency>
|
||||
<fee:fee>%FEE%</fee:fee>
|
||||
</fee:renew>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</domain:renew>
|
||||
</renew>
|
||||
<extension>
|
||||
<fee:renew xmlns:fee="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
<fee:renew xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee applied="delayed">55.00</fee:fee>
|
||||
</fee:renew>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</domain:renew>
|
||||
</renew>
|
||||
<extension>
|
||||
<fee:renew xmlns:fee="urn:ietf:params:xml:ns:fee-0.6">
|
||||
<fee:renew xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee>55.000</fee:fee>
|
||||
</fee:renew>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</domain:renew>
|
||||
</renew>
|
||||
<extension>
|
||||
<fee:renew xmlns:fee="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
<fee:renew xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee refundable="true" grace-period="P0D" applied="immediate">55.00</fee:fee>
|
||||
</fee:renew>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</domain:renew>
|
||||
</renew>
|
||||
<extension>
|
||||
<fee:renew xmlns:fee="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
<fee:renew xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee grace-period="P1D">55.00</fee:fee>
|
||||
</fee:renew>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</domain:renew>
|
||||
</renew>
|
||||
<extension>
|
||||
<fee:renew xmlns:fee="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
<fee:renew xmlns:fee="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:fee refundable="false">55.00</fee:fee>
|
||||
</fee:renew>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</domain:renData>
|
||||
</resData>
|
||||
<extension>
|
||||
<%FEE_NS%:renData xmlns:%FEE_NS%="urn:ietf:params:xml:ns:fee-%FEE_VERSION%">
|
||||
<%FEE_NS%:renData xmlns:%FEE_NS%="urn:ietf:params:xml:ns:%FEE_VERSION%">
|
||||
<%FEE_NS%:currency>%CURRENCY%</%FEE_NS%:currency>
|
||||
<%FEE_NS%:fee description="renew">%FEE%</%FEE_NS%:fee>
|
||||
</%FEE_NS%:renData>
|
||||
|
||||
@@ -15,4 +15,4 @@
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
</epp>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user