mirror of
https://github.com/google/nomulus.git
synced 2025-04-29 19:47:51 +02:00
Add Java code for storing and using IDN tables per-TLD (#1977)
This includes changes to make sure that we use the proper per-TLD IDN tables as well as setting/updating/removing them via the Create/Update TLD commands.
This commit is contained in:
parent
547fdaf87d
commit
a72f408366
10 changed files with 176 additions and 36 deletions
|
@ -176,8 +176,7 @@ public class DomainFlowUtils {
|
||||||
CharMatcher.inRange('a', 'z').or(CharMatcher.inRange('0', '9').or(CharMatcher.anyOf("-.")));
|
CharMatcher.inRange('a', 'z').or(CharMatcher.inRange('0', '9').or(CharMatcher.anyOf("-.")));
|
||||||
|
|
||||||
/** Default validator used to determine if an IDN name can be provisioned on a TLD. */
|
/** Default validator used to determine if an IDN name can be provisioned on a TLD. */
|
||||||
private static final IdnLabelValidator IDN_LABEL_VALIDATOR =
|
private static final IdnLabelValidator IDN_LABEL_VALIDATOR = new IdnLabelValidator();
|
||||||
IdnLabelValidator.createDefaultIdnLabelValidator();
|
|
||||||
|
|
||||||
/** The maximum number of DS records allowed on a domain. */
|
/** The maximum number of DS records allowed on a domain. */
|
||||||
private static final int MAX_DS_RECORDS_PER_DOMAIN = 8;
|
private static final int MAX_DS_RECORDS_PER_DOMAIN = 8;
|
||||||
|
|
|
@ -52,6 +52,7 @@ import google.registry.model.tld.label.PremiumList;
|
||||||
import google.registry.model.tld.label.ReservedList;
|
import google.registry.model.tld.label.ReservedList;
|
||||||
import google.registry.persistence.VKey;
|
import google.registry.persistence.VKey;
|
||||||
import google.registry.persistence.converter.JodaMoneyType;
|
import google.registry.persistence.converter.JodaMoneyType;
|
||||||
|
import google.registry.tldconfig.idn.IdnTableEnum;
|
||||||
import google.registry.util.Idn;
|
import google.registry.util.Idn;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -487,6 +488,9 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
*/
|
*/
|
||||||
List<VKey<AllocationToken>> defaultPromoTokens;
|
List<VKey<AllocationToken>> defaultPromoTokens;
|
||||||
|
|
||||||
|
/** A set of allowed {@link IdnTableEnum}s for this TLD, or empty if we should use the default. */
|
||||||
|
Set<IdnTableEnum> idnTables;
|
||||||
|
|
||||||
public String getTldStr() {
|
public String getTldStr() {
|
||||||
return tldStr;
|
return tldStr;
|
||||||
}
|
}
|
||||||
|
@ -694,6 +698,10 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
return nullToEmptyImmutableCopy(defaultPromoTokens);
|
return nullToEmptyImmutableCopy(defaultPromoTokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ImmutableSet<IdnTableEnum> getIdnTables() {
|
||||||
|
return nullToEmptyImmutableCopy(idnTables);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Builder asBuilder() {
|
public Builder asBuilder() {
|
||||||
return new Builder(clone(this));
|
return new Builder(clone(this));
|
||||||
|
@ -992,6 +1000,11 @@ public class Registry extends ImmutableObject implements Buildable, UnsafeSerial
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder setIdnTables(ImmutableSet<IdnTableEnum> idnTables) {
|
||||||
|
getInstance().idnTables = idnTables;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Registry build() {
|
public Registry build() {
|
||||||
final Registry instance = getInstance();
|
final Registry instance = getInstance();
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
// Copyright 2023 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.persistence.converter;
|
||||||
|
|
||||||
|
import google.registry.tldconfig.idn.IdnTableEnum;
|
||||||
|
import javax.persistence.AttributeConverter;
|
||||||
|
import javax.persistence.Converter;
|
||||||
|
|
||||||
|
/** JPA {@link AttributeConverter} for storing/retrieving {@link IdnTableEnum}s. */
|
||||||
|
@Converter(autoApply = true)
|
||||||
|
public class IdnTableEnumSetConverter extends StringSetConverterBase<IdnTableEnum> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String toString(IdnTableEnum element) {
|
||||||
|
return element.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
IdnTableEnum fromString(String value) {
|
||||||
|
return IdnTableEnum.valueOf(value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,8 +17,8 @@ package google.registry.tldconfig.idn;
|
||||||
import static google.registry.tldconfig.idn.IdnTableEnum.EXTENDED_LATIN;
|
import static google.registry.tldconfig.idn.IdnTableEnum.EXTENDED_LATIN;
|
||||||
import static google.registry.tldconfig.idn.IdnTableEnum.JA;
|
import static google.registry.tldconfig.idn.IdnTableEnum.JA;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import google.registry.model.tld.Registry;
|
||||||
import google.registry.util.Idn;
|
import google.registry.util.Idn;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@ -26,23 +26,8 @@ import java.util.Optional;
|
||||||
public final class IdnLabelValidator {
|
public final class IdnLabelValidator {
|
||||||
|
|
||||||
/** Most TLDs will use this generic list of IDN tables. */
|
/** Most TLDs will use this generic list of IDN tables. */
|
||||||
private static final ImmutableList<IdnTableEnum> DEFAULT_IDN_TABLES =
|
private static final ImmutableSet<IdnTableEnum> DEFAULT_IDN_TABLES =
|
||||||
ImmutableList.of(EXTENDED_LATIN, JA);
|
ImmutableSet.of(EXTENDED_LATIN, JA);
|
||||||
|
|
||||||
private static final ImmutableMap<String, ImmutableList<IdnTableEnum>>
|
|
||||||
DEFAULT_IDN_TABLE_LISTS_PER_TLD =
|
|
||||||
ImmutableMap.of("xn--q9jyb4c", ImmutableList.of(EXTENDED_LATIN, JA));
|
|
||||||
|
|
||||||
/** Some TLDs have their own IDN tables, configured here. */
|
|
||||||
private ImmutableMap<String, ImmutableList<IdnTableEnum>> idnTableListsPerTld;
|
|
||||||
|
|
||||||
IdnLabelValidator(ImmutableMap<String, ImmutableList<IdnTableEnum>> indTableListsPerTld) {
|
|
||||||
this.idnTableListsPerTld = indTableListsPerTld;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IdnLabelValidator createDefaultIdnLabelValidator() {
|
|
||||||
return new IdnLabelValidator(DEFAULT_IDN_TABLE_LISTS_PER_TLD);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns name of first matching {@link IdnTable} if domain label is valid for the given TLD.
|
* Returns name of first matching {@link IdnTable} if domain label is valid for the given TLD.
|
||||||
|
@ -50,10 +35,13 @@ public final class IdnLabelValidator {
|
||||||
* <p>A label is valid if it is considered valid by at least one configured IDN table for that
|
* <p>A label is valid if it is considered valid by at least one configured IDN table for that
|
||||||
* TLD. If no match is found, an absent value is returned.
|
* TLD. If no match is found, an absent value is returned.
|
||||||
*/
|
*/
|
||||||
public Optional<String> findValidIdnTableForTld(String label, String tld) {
|
public Optional<String> findValidIdnTableForTld(String label, String tldStr) {
|
||||||
String unicodeString = Idn.toUnicode(label);
|
String unicodeString = Idn.toUnicode(label);
|
||||||
for (IdnTableEnum idnTable :
|
Registry tld = Registry.get(tldStr); // uses the cache
|
||||||
Optional.ofNullable(idnTableListsPerTld.get(tld)).orElse(DEFAULT_IDN_TABLES)) {
|
ImmutableSet<IdnTableEnum> idnTablesForTld = tld.getIdnTables();
|
||||||
|
ImmutableSet<IdnTableEnum> idnTables =
|
||||||
|
idnTablesForTld.isEmpty() ? DEFAULT_IDN_TABLES : idnTablesForTld;
|
||||||
|
for (IdnTableEnum idnTable : idnTables) {
|
||||||
if (idnTable.getTable().isValidLabel(unicodeString)) {
|
if (idnTable.getTable().isValidLabel(unicodeString)) {
|
||||||
return Optional.of(idnTable.getTable().getName());
|
return Optional.of(idnTable.getTable().getName());
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
package google.registry.tools;
|
package google.registry.tools;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||||
import static google.registry.tools.UpdateOrDeleteAllocationTokensCommand.getTokenKeys;
|
import static google.registry.tools.UpdateOrDeleteAllocationTokensCommand.getTokenKeys;
|
||||||
import static google.registry.util.CollectionUtils.findDuplicates;
|
import static google.registry.util.CollectionUtils.findDuplicates;
|
||||||
import static google.registry.util.CollectionUtils.isNullOrEmpty;
|
import static google.registry.util.CollectionUtils.isNullOrEmpty;
|
||||||
|
@ -34,9 +35,11 @@ import google.registry.model.tld.Registry.TldState;
|
||||||
import google.registry.model.tld.Registry.TldType;
|
import google.registry.model.tld.Registry.TldType;
|
||||||
import google.registry.model.tld.label.PremiumList;
|
import google.registry.model.tld.label.PremiumList;
|
||||||
import google.registry.model.tld.label.PremiumListDao;
|
import google.registry.model.tld.label.PremiumListDao;
|
||||||
|
import google.registry.tldconfig.idn.IdnTableEnum;
|
||||||
import google.registry.tools.params.OptionalStringParameter;
|
import google.registry.tools.params.OptionalStringParameter;
|
||||||
import google.registry.tools.params.TransitionListParameter.BillingCostTransitions;
|
import google.registry.tools.params.TransitionListParameter.BillingCostTransitions;
|
||||||
import google.registry.tools.params.TransitionListParameter.TldStateTransitions;
|
import google.registry.tools.params.TransitionListParameter.TldStateTransitions;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -244,6 +247,15 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
|
||||||
+ " present default tokens.")
|
+ " present default tokens.")
|
||||||
List<String> defaultTokens;
|
List<String> defaultTokens;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Parameter(
|
||||||
|
names = "--idn_tables",
|
||||||
|
description =
|
||||||
|
"A comma-separated list of the IDN tables to use for this TLD. Specify an empty list to"
|
||||||
|
+ " remove any previously-set tables and to use the default. All elements must be"
|
||||||
|
+ " IdnTableEnum values")
|
||||||
|
List<String> idnTables;
|
||||||
|
|
||||||
/** Returns the existing registry (for update) or null (for creates). */
|
/** Returns the existing registry (for update) or null (for creates). */
|
||||||
@Nullable
|
@Nullable
|
||||||
abstract Registry getOldRegistry(String tld);
|
abstract Registry getOldRegistry(String tld);
|
||||||
|
@ -392,6 +404,23 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
|
||||||
builder.setDefaultPromoTokens(getTokenKeys(defaultTokens, null));
|
builder.setDefaultPromoTokens(getTokenKeys(defaultTokens, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (idnTables != null) {
|
||||||
|
if (idnTables.equals(ImmutableList.of(""))) {
|
||||||
|
builder.setIdnTables(ImmutableSet.of());
|
||||||
|
} else {
|
||||||
|
ImmutableSet<String> upperCaseIdnTables =
|
||||||
|
idnTables.stream().map(String::toUpperCase).collect(toImmutableSet());
|
||||||
|
ImmutableSet<String> validIdnStringValues =
|
||||||
|
Arrays.stream(IdnTableEnum.values()).map(Enum::name).collect(toImmutableSet());
|
||||||
|
checkArgument(
|
||||||
|
validIdnStringValues.containsAll(upperCaseIdnTables),
|
||||||
|
"IDN tables %s contained invalid value(s). Possible values: %s",
|
||||||
|
upperCaseIdnTables,
|
||||||
|
validIdnStringValues);
|
||||||
|
builder.setIdnTables(
|
||||||
|
upperCaseIdnTables.stream().map(IdnTableEnum::valueOf).collect(toImmutableSet()));
|
||||||
|
}
|
||||||
|
}
|
||||||
// Update the Registry object.
|
// Update the Registry object.
|
||||||
setCommandSpecificProperties(builder);
|
setCommandSpecificProperties(builder);
|
||||||
stageEntityChange(oldRegistry, builder.build());
|
stageEntityChange(oldRegistry, builder.build());
|
||||||
|
|
|
@ -91,6 +91,7 @@
|
||||||
<class>google.registry.persistence.converter.DatabaseMigrationScheduleTransitionConverter</class>
|
<class>google.registry.persistence.converter.DatabaseMigrationScheduleTransitionConverter</class>
|
||||||
<class>google.registry.persistence.converter.DateTimeConverter</class>
|
<class>google.registry.persistence.converter.DateTimeConverter</class>
|
||||||
<class>google.registry.persistence.converter.DurationConverter</class>
|
<class>google.registry.persistence.converter.DurationConverter</class>
|
||||||
|
<class>google.registry.persistence.converter.IdnTableEnumSetConverter</class>
|
||||||
<class>google.registry.persistence.converter.InetAddressSetConverter</class>
|
<class>google.registry.persistence.converter.InetAddressSetConverter</class>
|
||||||
<class>google.registry.persistence.converter.LocalDateConverter</class>
|
<class>google.registry.persistence.converter.LocalDateConverter</class>
|
||||||
<class>google.registry.persistence.converter.PostalInfoChoiceListConverter</class>
|
<class>google.registry.persistence.converter.PostalInfoChoiceListConverter</class>
|
||||||
|
|
|
@ -15,17 +15,26 @@
|
||||||
package google.registry.tldconfig.idn;
|
package google.registry.tldconfig.idn;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth8.assertThat;
|
import static com.google.common.truth.Truth8.assertThat;
|
||||||
|
import static google.registry.testing.DatabaseHelper.createTld;
|
||||||
|
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||||
|
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
/** Unit tests for {@link IdnLabelValidator}. */
|
/** Unit tests for {@link IdnLabelValidator}. */
|
||||||
class IdnLabelValidatorTest {
|
class IdnLabelValidatorTest {
|
||||||
|
|
||||||
private IdnLabelValidator idnLabelValidator = IdnLabelValidator.createDefaultIdnLabelValidator();
|
@RegisterExtension
|
||||||
|
final JpaIntegrationTestExtension jpa =
|
||||||
|
new JpaTestExtensions.Builder().buildIntegrationTestExtension();
|
||||||
|
|
||||||
private void doJapaneseLanguageTests(String tld) {
|
private IdnLabelValidator idnLabelValidator = new IdnLabelValidator();
|
||||||
|
|
||||||
|
private void doJapaneseAndLatinLanguageTests(String tld) {
|
||||||
|
createTld(tld);
|
||||||
assertThat(idnLabelValidator.findValidIdnTableForTld("foo", tld)).isPresent();
|
assertThat(idnLabelValidator.findValidIdnTableForTld("foo", tld)).isPresent();
|
||||||
assertThat(idnLabelValidator.findValidIdnTableForTld("12379foar", tld)).isPresent();
|
assertThat(idnLabelValidator.findValidIdnTableForTld("12379foar", tld)).isPresent();
|
||||||
assertThat(idnLabelValidator.findValidIdnTableForTld("みんな", tld)).isPresent();
|
assertThat(idnLabelValidator.findValidIdnTableForTld("みんな", tld)).isPresent();
|
||||||
|
@ -84,26 +93,29 @@ class IdnLabelValidatorTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testMinna() {
|
void testMinna() {
|
||||||
doJapaneseLanguageTests("xn--q9jyb4c");
|
doJapaneseAndLatinLanguageTests("xn--q9jyb4c");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFoo() {
|
void testFoo() {
|
||||||
doJapaneseLanguageTests("foo");
|
doJapaneseAndLatinLanguageTests("foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSoy() {
|
void testSoy() {
|
||||||
doJapaneseLanguageTests("soy");
|
doJapaneseAndLatinLanguageTests("soy");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testOverridenTables() {
|
void testPerTldConfig() {
|
||||||
// Set .tld to have only the extended latin table and not japanese.
|
persistResource(
|
||||||
idnLabelValidator =
|
createTld("tld")
|
||||||
new IdnLabelValidator(
|
.asBuilder()
|
||||||
ImmutableMap.of("tld", ImmutableList.of(IdnTableEnum.EXTENDED_LATIN)));
|
.setIdnTables(ImmutableSet.of(IdnTableEnum.EXTENDED_LATIN))
|
||||||
|
.build());
|
||||||
assertThat(idnLabelValidator.findValidIdnTableForTld("foo", "tld")).isPresent();
|
assertThat(idnLabelValidator.findValidIdnTableForTld("foo", "tld")).isPresent();
|
||||||
|
assertThat(idnLabelValidator.findValidIdnTableForTld("abcdefghæ", "tld")).isPresent();
|
||||||
|
// Extended Latin shouldn't include Japanese characters
|
||||||
assertThat(idnLabelValidator.findValidIdnTableForTld("みんな", "tld")).isEmpty();
|
assertThat(idnLabelValidator.findValidIdnTableForTld("みんな", "tld")).isEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Range;
|
import com.google.common.collect.Range;
|
||||||
import google.registry.model.domain.token.AllocationToken;
|
import google.registry.model.domain.token.AllocationToken;
|
||||||
import google.registry.model.tld.Registry;
|
import google.registry.model.tld.Registry;
|
||||||
|
import google.registry.tldconfig.idn.IdnTableEnum;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import org.joda.money.Money;
|
import org.joda.money.Money;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
@ -544,6 +545,35 @@ class CreateTldCommandTest extends CommandTestCase<CreateTldCommand> {
|
||||||
assertThat(Registry.get("xn--q9jyb4c").getDriveFolderId()).isNull();
|
assertThat(Registry.get("xn--q9jyb4c").getDriveFolderId()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSuccess_setsIdnTables() throws Exception {
|
||||||
|
runCommandForced(
|
||||||
|
"--idn_tables=extended_latin,ja",
|
||||||
|
"--roid_suffix=ASDF",
|
||||||
|
"--dns_writers=VoidDnsWriter",
|
||||||
|
"xn--q9jyb4c");
|
||||||
|
assertThat(Registry.get("xn--q9jyb4c").getIdnTables())
|
||||||
|
.containsExactly(IdnTableEnum.EXTENDED_LATIN, IdnTableEnum.JA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFailure_invalidIdnTable() throws Exception {
|
||||||
|
IllegalArgumentException thrown =
|
||||||
|
assertThrows(
|
||||||
|
IllegalArgumentException.class,
|
||||||
|
() ->
|
||||||
|
runCommandForced(
|
||||||
|
"--idn_tables=extended_latin,bad_value",
|
||||||
|
"--roid_suffix=ASDF",
|
||||||
|
"--dns_writers=VoidDnsWriter",
|
||||||
|
"xn--q9jyb4c"));
|
||||||
|
assertThat(thrown)
|
||||||
|
.hasMessageThat()
|
||||||
|
.isEqualTo(
|
||||||
|
"IDN tables [EXTENDED_LATIN, BAD_VALUE] contained invalid value(s). Possible values:"
|
||||||
|
+ " [EXTENDED_LATIN, UNCONFUSABLE_LATIN, JA]");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFailure_setPremiumListThatDoesntExist() {
|
void testFailure_setPremiumListThatDoesntExist() {
|
||||||
IllegalArgumentException thrown =
|
IllegalArgumentException thrown =
|
||||||
|
|
|
@ -39,6 +39,7 @@ import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.ImmutableSortedMap;
|
import com.google.common.collect.ImmutableSortedMap;
|
||||||
import google.registry.model.domain.token.AllocationToken;
|
import google.registry.model.domain.token.AllocationToken;
|
||||||
import google.registry.model.tld.Registry;
|
import google.registry.model.tld.Registry;
|
||||||
|
import google.registry.tldconfig.idn.IdnTableEnum;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import org.joda.money.Money;
|
import org.joda.money.Money;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
@ -1053,6 +1054,38 @@ class UpdateTldCommandTest extends CommandTestCase<UpdateTldCommand> {
|
||||||
assertThat(Registry.get("xn--q9jyb4c").getDriveFolderId()).isNull();
|
assertThat(Registry.get("xn--q9jyb4c").getDriveFolderId()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSuccess_setsIdnTables() throws Exception {
|
||||||
|
assertThat(Registry.get("xn--q9jyb4c").getIdnTables()).isEmpty();
|
||||||
|
runCommandForced("--idn_tables=extended_latin,ja", "xn--q9jyb4c");
|
||||||
|
assertThat(Registry.get("xn--q9jyb4c").getIdnTables())
|
||||||
|
.containsExactly(IdnTableEnum.EXTENDED_LATIN, IdnTableEnum.JA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSuccess_removesIndTables() throws Exception {
|
||||||
|
persistResource(
|
||||||
|
Registry.get("xn--q9jyb4c")
|
||||||
|
.asBuilder()
|
||||||
|
.setIdnTables(ImmutableSet.of(IdnTableEnum.EXTENDED_LATIN, IdnTableEnum.JA))
|
||||||
|
.build());
|
||||||
|
runCommandForced("--idn_tables=", "xn--q9jyb4c");
|
||||||
|
assertThat(Registry.get("xn--q9jyb4c").getIdnTables()).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFailure_invalidIdnTable() throws Exception {
|
||||||
|
IllegalArgumentException thrown =
|
||||||
|
assertThrows(
|
||||||
|
IllegalArgumentException.class,
|
||||||
|
() -> runCommandForced("--idn_tables=extended_latin,bad_value", "xn--q9jyb4c"));
|
||||||
|
assertThat(thrown)
|
||||||
|
.hasMessageThat()
|
||||||
|
.isEqualTo(
|
||||||
|
"IDN tables [EXTENDED_LATIN, BAD_VALUE] contained invalid value(s). Possible values:"
|
||||||
|
+ " [EXTENDED_LATIN, UNCONFUSABLE_LATIN, JA]");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFailure_setPremiumListThatDoesntExist() {
|
void testFailure_setPremiumListThatDoesntExist() {
|
||||||
IllegalArgumentException thrown =
|
IllegalArgumentException thrown =
|
||||||
|
|
|
@ -724,6 +724,7 @@
|
||||||
drive_folder_id text,
|
drive_folder_id text,
|
||||||
eap_fee_schedule hstore not null,
|
eap_fee_schedule hstore not null,
|
||||||
escrow_enabled boolean not null,
|
escrow_enabled boolean not null,
|
||||||
|
idn_tables text[],
|
||||||
invoicing_enabled boolean not null,
|
invoicing_enabled boolean not null,
|
||||||
lordn_username text,
|
lordn_username text,
|
||||||
num_dns_publish_locks int4 not null,
|
num_dns_publish_locks int4 not null,
|
||||||
|
|
Loading…
Add table
Reference in a new issue