Conform to RDAP Technical Implementation Guide

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=251864499
This commit is contained in:
guyben 2019-06-06 09:18:07 -07:00 committed by jianglai
parent 5e4199fae6
commit c3c3520e04
65 changed files with 869 additions and 709 deletions

View file

@ -86,7 +86,6 @@ public class RdapActionBaseTestCase<A extends RdapActionBase> {
inject.setStaticField(Ofy.class, "clock", clock);
action = TypeUtils.instantiate(rdapActionClass);
action.includeDeletedParam = Optional.empty();
action.registrarParam = Optional.empty();
action.formatOutputParam = Optional.empty();
action.response = response;
action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter(clock);

View file

@ -45,7 +45,12 @@ public final class RdapDataStructuresTest {
@Test
public void testRdapConformance() {
assertThat(RdapConformance.INSTANCE.toJson())
.isEqualTo(createJson("['rdap_level_0','icann_rdap_response_profile_0']"));
.isEqualTo(createJson(
"[",
" 'rdap_level_0',",
" 'icann_rdap_response_profile_0',",
" 'icann_rdap_technical_implementation_guide_0'",
"]"));
}
@Test

View file

@ -273,20 +273,6 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
assertProperResponseForCatLol("cat.lol", "rdap_domain.json");
}
@Test
public void testValidDomain_works_sameRegistrarRequested() {
action.registrarParam = Optional.of("evilregistrar");
login("evilregistrar");
assertProperResponseForCatLol("cat.lol", "rdap_domain.json");
}
@Test
public void testValidDomain_notFound_differentRegistrarRequested() {
action.registrarParam = Optional.of("idnregistrar");
generateActualJson("cat.lol");
assertThat(response.getStatus()).isEqualTo(404);
}
@Test
public void testValidDomain_asAdministrator_works() {
loginAsAdmin();

View file

@ -663,10 +663,11 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
@Test
public void testInvalidWildcard_rejected() {
assertThat(generateActualJson(RequestType.NAME, "exam*ple"))
.isEqualTo(generateExpectedJsonError(
"Suffix after wildcard must be one or more domain"
+ " name labels, e.g. exam*.tld, ns*.example.tld",
422));
.isEqualTo(
generateExpectedJsonError(
"Query can only have a single wildcard, and it must be at the end of a label, but"
+ " was: 'exam*ple'",
422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME, Optional.empty(), 422);
}
@ -674,7 +675,11 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
@Test
public void testMultipleWildcards_rejected() {
assertThat(generateActualJson(RequestType.NAME, "*.*"))
.isEqualTo(generateExpectedJsonError("Only one wildcard allowed", 422));
.isEqualTo(
generateExpectedJsonError(
"Query can only have a single wildcard, and it must be at the end of a label, but"
+ " was: '*.*'",
422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME, Optional.empty(), 422);
}
@ -1297,7 +1302,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
@Test
public void testNameserverMatchWithWildcardAndEmptySuffix_unprocessable() {
rememberWildcardType("ns*.");
rememberWildcardTypeInvalid();
generateActualJson(RequestType.NS_LDH_NAME, "ns*.");
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.empty(), 422);
@ -1331,8 +1336,8 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
metricWildcardType = WildcardType.INVALID;
metricPrefixLength = 0;
generateActualJson(RequestType.NS_LDH_NAME, "ns1.cat.みんな");
assertThat(response.getStatus()).isEqualTo(400);
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.empty(), 400);
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.empty(), 422);
}
@Test

View file

@ -163,76 +163,64 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
return obj;
}
private void runSuccessfulTest(String queryString, String fileName) {
runSuccessfulTest(queryString, "(◕‿◕)", "active", null, fileName);
private void runSuccessfulHandleTest(String handleQuery, String fileName) {
runSuccessfulHandleTest(handleQuery, "(◕‿◕)", "active", null, fileName);
}
private void runSuccessfulTest(String queryString, String fullName, String fileName) {
runSuccessfulTest(queryString, fullName, "active", null, fileName);
private void runSuccessfulHandleTest(String handleQuery, String fullName, String fileName) {
runSuccessfulHandleTest(handleQuery, fullName, "active", null, fileName);
}
private void runSuccessfulTest(
String queryString,
private void runSuccessfulHandleTest(
String handleQuery,
String fullName,
String rdapStatus,
String address,
String fileName) {
assertThat(generateActualJson(queryString))
assertThat(generateActualJson(handleQuery))
.isEqualTo(
generateExpectedJsonWithTopLevelEntries(
queryString, fullName, rdapStatus, address, fileName));
handleQuery, fullName, rdapStatus, address, fileName));
assertThat(response.getStatus()).isEqualTo(200);
}
private void runNotFoundTest(String queryString) {
assertThat(generateActualJson(queryString))
.isEqualTo(generateExpectedJsonError(queryString + " not found", 404));
private void runNotFoundTest(String handleQuery) {
assertThat(generateActualJson(handleQuery))
.isEqualTo(generateExpectedJsonError(handleQuery + " not found", 404));
assertThat(response.getStatus()).isEqualTo(404);
}
@Test
public void testInvalidEntity_returns400() {
assertThat(generateActualJson("invalid/entity/handle")).isEqualTo(
generateExpectedJsonError(
"invalid/entity/handle is not a valid entity handle",
400));
assertThat(response.getStatus()).isEqualTo(400);
public void testUnknownEntity_RoidPattern_notFound() {
runNotFoundTest("_MISSING-ENTITY_");
}
@Test
public void testUnknownEntity_notFound() {
runNotFoundTest("_MISSING-ENTITY_");
public void testUnknownEntity_IanaPattern_notFound() {
runNotFoundTest("123");
}
@Test
public void testUnknownEntity_notRoidNotIana_notFound() {
// Since we allow search by registrar name, every string is a possible name
runNotFoundTest("some,random,string");
}
@Test
public void testValidRegistrantContact_works() {
login("evilregistrar");
runSuccessfulTest(registrant.getRepoId(), "rdap_associated_contact.json");
}
@Test
public void testValidRegistrantContact_found_sameRegistrarRequested() {
login("evilregistrar");
action.registrarParam = Optional.of("evilregistrar");
runSuccessfulTest(registrant.getRepoId(), "rdap_associated_contact.json");
}
@Test
public void testValidRegistrantContact_notFound_differentRegistrarRequested() {
login("evilregistrar");
action.registrarParam = Optional.of("idnregistrar");
runNotFoundTest(registrant.getRepoId());
runSuccessfulHandleTest(registrant.getRepoId(), "rdap_associated_contact.json");
}
@Test
public void testValidRegistrantContact_found_asAdministrator() {
loginAsAdmin();
runSuccessfulTest(registrant.getRepoId(), "rdap_associated_contact.json");
runSuccessfulHandleTest(registrant.getRepoId(), "rdap_associated_contact.json");
}
@Test
public void testValidRegistrantContact_found_notLoggedIn() {
runSuccessfulTest(
runSuccessfulHandleTest(
registrant.getRepoId(),
"(◕‿◕)",
"active",
@ -243,7 +231,7 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
@Test
public void testValidRegistrantContact_found_loggedInAsOtherRegistrar() {
login("otherregistrar");
runSuccessfulTest(
runSuccessfulHandleTest(
registrant.getRepoId(),
"(◕‿◕)",
"active",
@ -254,19 +242,19 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
@Test
public void testValidAdminContact_works() {
login("evilregistrar");
runSuccessfulTest(adminContact.getRepoId(), "rdap_associated_contact.json");
runSuccessfulHandleTest(adminContact.getRepoId(), "rdap_associated_contact.json");
}
@Test
public void testValidTechContact_works() {
login("evilregistrar");
runSuccessfulTest(techContact.getRepoId(), "rdap_associated_contact.json");
runSuccessfulHandleTest(techContact.getRepoId(), "rdap_associated_contact.json");
}
@Test
public void testValidDisconnectedContact_works() {
login("evilregistrar");
runSuccessfulTest(disconnectedContact.getRepoId(), "rdap_contact.json");
runSuccessfulHandleTest(disconnectedContact.getRepoId(), "rdap_contact.json");
}
@Test
@ -297,7 +285,7 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
public void testDeletedContact_found_loggedInAsCorrectRegistrar() {
login("evilregistrar");
action.includeDeletedParam = Optional.of(true);
runSuccessfulTest(
runSuccessfulHandleTest(
deletedContact.getRepoId(),
"",
"inactive",
@ -309,7 +297,7 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
public void testDeletedContact_found_loggedInAsAdmin() {
loginAsAdmin();
action.includeDeletedParam = Optional.of(true);
runSuccessfulTest(
runSuccessfulHandleTest(
deletedContact.getRepoId(),
"",
"inactive",
@ -319,29 +307,26 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
@Test
public void testRegistrar_found() {
runSuccessfulTest("101", "Yes Virginia <script>", "rdap_registrar.json");
runSuccessfulHandleTest("101", "Yes Virginia <script>", "rdap_registrar.json");
}
@Test
public void testRegistrarByName_found() {
assertThat(generateActualJson("IDN%20Registrar"))
.isEqualTo(
generateExpectedJsonWithTopLevelEntries(
"102", "IDN Registrar", "active", null, "rdap_registrar.json"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testRegistrar102_works() {
runSuccessfulTest("102", "IDN Registrar", "rdap_registrar.json");
}
@Test
public void testRegistrar102_found_requestingSameRegistrar() {
action.registrarParam = Optional.of("idnregistrar");
runSuccessfulTest("102", "IDN Registrar", "rdap_registrar.json");
}
@Test
public void testRegistrar102_notFound_requestingOtherRegistrar() {
action.registrarParam = Optional.of("1tldregistrar");
runNotFoundTest("102");
runSuccessfulHandleTest("102", "IDN Registrar", "rdap_registrar.json");
}
@Test
public void testRegistrar103_works() {
runSuccessfulTest("103", "Multilevel Registrar", "rdap_registrar.json");
runSuccessfulHandleTest("103", "Multilevel Registrar", "rdap_registrar.json");
}
@Test
@ -359,7 +344,7 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
public void testRegistrar104_found_deletedFlagWhenLoggedIn() {
login("deletedregistrar");
action.includeDeletedParam = Optional.of(true);
runSuccessfulTest(
runSuccessfulHandleTest(
"104", "Yes Virginia <script>", "inactive", null, "rdap_registrar.json");
}
@ -374,7 +359,7 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
public void testRegistrar104_found_deletedFlagWhenLoggedInAsAdmin() {
loginAsAdmin();
action.includeDeletedParam = Optional.of(true);
runSuccessfulTest(
runSuccessfulHandleTest(
"104", "Yes Virginia <script>", "inactive", null, "rdap_registrar.json");
}

View file

@ -412,7 +412,10 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
public void testNameMatch_suffixRejected() {
assertThat(generateActualJsonWithFullName("exam*ple"))
.isEqualTo(
generateExpectedJsonError("Suffix not allowed after wildcard", 422));
generateExpectedJsonError(
"Query can only have a single wildcard, and it must be at the end of the query,"
+ " but was: 'exam*ple'",
422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(Optional.empty(), 422);
}
@ -421,7 +424,10 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
public void testHandleMatch_suffixRejected() {
assertThat(generateActualJsonWithHandle("exam*ple"))
.isEqualTo(
generateExpectedJsonError("Suffix not allowed after wildcard", 422));
generateExpectedJsonError(
"Query can only have a single wildcard, and it must be at the end of the query,"
+ " but was: 'exam*ple'",
422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(Optional.empty(), 422);
}
@ -429,7 +435,11 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
@Test
public void testMultipleWildcards_rejected() {
assertThat(generateActualJsonWithHandle("*.*"))
.isEqualTo(generateExpectedJsonError("Only one wildcard allowed", 422));
.isEqualTo(
generateExpectedJsonError(
"Query can only have a single wildcard, and it must be at the end of the query,"
+ " but was: '*.*'",
422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(Optional.empty(), 422);
}

View file

@ -235,30 +235,6 @@ public class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameser
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testNameserver_found_sameRegistrarRequested() {
action.registrarParam = Optional.of("TheRegistrar");
assertThat(generateActualJson("ns1.cat.lol"))
.isEqualTo(
generateExpectedJsonWithTopLevelEntries(
"ns1.cat.lol",
ImmutableMap.of(
"HANDLE", "2-ROID",
"ADDRESSTYPE", "v4",
"ADDRESS", "1.2.3.4",
"STATUS", "active"),
"rdap_host.json"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testNameserver_notFound_differentRegistrarRequested() {
action.registrarParam = Optional.of("otherregistrar");
action.includeDeletedParam = Optional.of(false);
generateActualJson("ns1.cat.lol");
assertThat(response.getStatus()).isEqualTo(404);
}
@Test
public void testDeletedNameserver_notFound_includeDeletedNotSpecified() {
generateActualJson("nsdeleted.cat.lol");
@ -322,33 +298,6 @@ public class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameser
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testDeletedNameserver_found_sameRegistrarRequested() {
login("TheRegistrar");
action.registrarParam = Optional.of("TheRegistrar");
action.includeDeletedParam = Optional.of(true);
assertThat(generateActualJson("nsdeleted.cat.lol"))
.isEqualTo(
generateExpectedJsonWithTopLevelEntries(
"nsdeleted.cat.lol",
ImmutableMap.of(
"HANDLE", "A-ROID",
"ADDRESSTYPE", "v4",
"ADDRESS", "1.2.3.4",
"STATUS", "inactive"),
"rdap_host.json"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testDeletedNameserver_notFound_differentRegistrarRequested() {
login("TheRegistrar");
action.registrarParam = Optional.of("otherregistrar");
action.includeDeletedParam = Optional.of(false);
generateActualJson("ns1.cat.lol");
assertThat(response.getStatus()).isEqualTo(404);
}
@Test
public void testMetrics() {
generateActualJson("ns1.cat.lol");

View file

@ -258,9 +258,10 @@ public class RdapNameserverSearchActionTest
assertThat(generateActualJsonWithName("exam*ple"))
.isEqualTo(
generateExpectedJsonError(
"Suffix after wildcard must be one or more domain"
+ " name labels, e.g. exam*.tld, ns*.example.tld",
"Query can only have a single wildcard, and it must be at the end of a label, but"
+ " was: 'exam*ple'",
422));
rememberWildcardTypeInvalid();
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(Optional.empty(), 422);
}
@ -279,7 +280,12 @@ public class RdapNameserverSearchActionTest
@Test
public void testMultipleWildcards_rejected() {
assertThat(generateActualJsonWithName("*.*"))
.isEqualTo(generateExpectedJsonError("Only one wildcard allowed", 422));
.isEqualTo(
generateExpectedJsonError(
"Query can only have a single wildcard, and it must be at the end of a label, but"
+ " was: '*.*'",
422));
rememberWildcardTypeInvalid();
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(Optional.empty(), 422);
}
@ -337,7 +343,7 @@ public class RdapNameserverSearchActionTest
action.registrarParam = Optional.of("unicoderegistrar");
generateActualJsonWithName("ns1.cat.lol");
assertThat(response.getStatus()).isEqualTo(404);
verifyErrorMetrics(Optional.of(0L), 404);
verifyErrorMetrics(Optional.of(1L), 404);
}
@Test
@ -373,13 +379,20 @@ public class RdapNameserverSearchActionTest
}
@Test
public void testNameMatch_ns1_cat_idn_unicode_badRequest() {
// name must use punycode.
generateActualJsonWithName("ns1.cat.みんな");
metricWildcardType = WildcardType.INVALID;
metricPrefixLength = 0;
assertThat(response.getStatus()).isEqualTo(400);
verifyErrorMetrics(Optional.empty(), 400);
public void testNameMatch_ns1_cat_idn_unicode_found() {
assertThat(generateActualJsonWithName("ns1.cat.みんな"))
.isEqualTo(
generateExpectedJsonForNameserver(
"ns1.cat.みんな",
"ns1.cat.xn--q9jyb4c",
"B-ROID",
"v4",
"1.2.3.5",
"rdap_host_unicode.json"));
metricWildcardType = WildcardType.NO_WILDCARD;
metricPrefixLength = 19;
assertThat(response.getStatus()).isEqualTo(200);
verifyMetrics(1);
}
@Test

View file

@ -43,30 +43,34 @@ public class RdapSearchActionTestCase<A extends RdapSearchActionBase>
public void initRdapSearchActionTestCase() {
action.parameterMap = ImmutableListMultimap.of();
action.cursorTokenParam = Optional.empty();
action.registrarParam = Optional.empty();
action.rdapResultSetMaxSize = 4;
action.requestUrl = "https://example.tld" + actionPath;
action.requestPath = actionPath;
}
void rememberWildcardType(String queryString) {
try {
RdapSearchPattern partialStringQuery = RdapSearchPattern.create(queryString, true);
if (!partialStringQuery.getHasWildcard()) {
metricWildcardType = WildcardType.NO_WILDCARD;
} else if (partialStringQuery.getSuffix() == null) {
metricWildcardType = WildcardType.PREFIX;
} else if (partialStringQuery.getInitialString().isEmpty()) {
metricWildcardType = WildcardType.SUFFIX;
} else {
metricWildcardType = WildcardType.PREFIX_AND_SUFFIX;
}
metricPrefixLength = partialStringQuery.getInitialString().length();
} catch (Exception e) {
metricWildcardType = WildcardType.INVALID;
metricPrefixLength = 0;
void rememberWildcardType(WildcardType wildcardType, int prefixLength) {
metricWildcardType = wildcardType;
metricPrefixLength = prefixLength;
}
void rememberWildcardType(String searchQuery) {
int wildcardLocation = searchQuery.indexOf('*');
if (wildcardLocation < 0) {
rememberWildcardType(WildcardType.NO_WILDCARD, searchQuery.length());
} else if (wildcardLocation == searchQuery.length() - 1) {
rememberWildcardType(WildcardType.PREFIX, wildcardLocation);
} else if (wildcardLocation == 0) {
rememberWildcardType(WildcardType.SUFFIX, wildcardLocation);
} else {
rememberWildcardType(WildcardType.PREFIX_AND_SUFFIX, wildcardLocation);
}
}
void rememberWildcardTypeInvalid() {
rememberWildcardType(WildcardType.INVALID, 0);
}
void verifyMetrics(
EndpointType endpointType,
Action.Method requestMethod,

View file

@ -28,7 +28,7 @@ public class RdapSearchPatternTest {
@Test
public void testNoWildcards_ok() {
RdapSearchPattern rdapSearchPattern = RdapSearchPattern.create("example.lol", true);
RdapSearchPattern rdapSearchPattern = RdapSearchPattern.createFromLdhDomainName("example.lol");
assertThat(rdapSearchPattern.getInitialString()).isEqualTo("example.lol");
assertThat(rdapSearchPattern.getHasWildcard()).isFalse();
assertThat(rdapSearchPattern.getSuffix()).isNull();
@ -36,7 +36,7 @@ public class RdapSearchPatternTest {
@Test
public void testWildcardNoTld_ok() {
RdapSearchPattern rdapSearchPattern = RdapSearchPattern.create("exam*", true);
RdapSearchPattern rdapSearchPattern = RdapSearchPattern.createFromLdhDomainName("exam*");
assertThat(rdapSearchPattern.getInitialString()).isEqualTo("exam");
assertThat(rdapSearchPattern.getHasWildcard()).isTrue();
assertThat(rdapSearchPattern.getSuffix()).isNull();
@ -44,32 +44,52 @@ public class RdapSearchPatternTest {
@Test
public void testWildcardTld_ok() {
RdapSearchPattern rdapSearchPattern = RdapSearchPattern.create("exam*.lol", true);
RdapSearchPattern rdapSearchPattern = RdapSearchPattern.createFromLdhDomainName("exam*.lol");
assertThat(rdapSearchPattern.getInitialString()).isEqualTo("exam");
assertThat(rdapSearchPattern.getHasWildcard()).isTrue();
assertThat(rdapSearchPattern.getSuffix()).isEqualTo("lol");
}
@Test
public void testWildcardAtStart_ok() {
RdapSearchPattern rdapSearchPattern = RdapSearchPattern.createFromLdhDomainName("*.lol");
assertThat(rdapSearchPattern.getInitialString()).isEmpty();
assertThat(rdapSearchPattern.getHasWildcard()).isTrue();
assertThat(rdapSearchPattern.getSuffix()).isEqualTo("lol");
}
@Test
public void testWildcardOnly_ok() {
RdapSearchPattern rdapSearchPattern = RdapSearchPattern.createFromLdhDomainName("*");
assertThat(rdapSearchPattern.getInitialString()).isEmpty();
assertThat(rdapSearchPattern.getHasWildcard()).isTrue();
assertThat(rdapSearchPattern.getSuffix()).isNull();
}
@Test
public void testMultipleWildcards_unprocessable() {
assertThrows(
UnprocessableEntityException.class, () -> RdapSearchPattern.create("ex*am*.lol", true));
UnprocessableEntityException.class,
() -> RdapSearchPattern.createFromLdhDomainName("ex*am*.lol"));
}
@Test
public void testWildcardNotAtEnd_unprocessable() {
assertThrows(UnprocessableEntityException.class, () -> RdapSearchPattern.create("ex*am", true));
assertThrows(
UnprocessableEntityException.class,
() -> RdapSearchPattern.createFromLdhDomainName("ex*am"));
}
@Test
public void testWildcardNotAtEndWithTld_unprocessable() {
assertThrows(
UnprocessableEntityException.class, () -> RdapSearchPattern.create("ex*am.lol", true));
UnprocessableEntityException.class,
() -> RdapSearchPattern.createFromLdhDomainName("ex*am.lol"));
}
@Test
public void testShortString_ok() {
RdapSearchPattern rdapSearchPattern = RdapSearchPattern.create("e", true);
RdapSearchPattern rdapSearchPattern = RdapSearchPattern.createFromLdhDomainName("e");
assertThat(rdapSearchPattern.getInitialString()).isEqualTo("e");
assertThat(rdapSearchPattern.getHasWildcard()).isFalse();
assertThat(rdapSearchPattern.getSuffix()).isNull();
@ -78,24 +98,45 @@ public class RdapSearchPatternTest {
@Test
public void testZeroLengthSuffix_unprocessable() {
assertThrows(
UnprocessableEntityException.class, () -> RdapSearchPattern.create("exam*.", true));
}
@Test
public void testDisallowedSuffix_unprocessable() {
assertThrows(
UnprocessableEntityException.class, () -> RdapSearchPattern.create("exam*.lol", false));
UnprocessableEntityException.class,
() -> RdapSearchPattern.createFromLdhDomainName("exam*."));
}
@Test
public void testNextInitialString_alpha() {
RdapSearchPattern rdapSearchPattern = RdapSearchPattern.create("exam*.lol", true);
RdapSearchPattern rdapSearchPattern = RdapSearchPattern.createFromLdhDomainName("exam*.lol");
assertThat(rdapSearchPattern.getNextInitialString()).isEqualTo("exan");
}
@Test
public void testNextInitialString_unicode() {
RdapSearchPattern rdapSearchPattern = RdapSearchPattern.create("cat.みんな", true);
assertThat(rdapSearchPattern.getNextInitialString()).isEqualTo("cat.みんに");
public void testNextInitialString_unicode_translatedToPunycode() {
RdapSearchPattern rdapSearchPattern =
RdapSearchPattern.createFromLdhOrUnicodeDomainName("cat.みんな");
assertThat(rdapSearchPattern.getNextInitialString()).isEqualTo("cat.xn--q9jyb4d");
}
@Test
public void testUnicodeString_noWildcard() {
RdapSearchPattern rdapSearchPattern =
RdapSearchPattern.createFromUnicodeString("unicode みんに string");
assertThat(rdapSearchPattern.getInitialString()).isEqualTo("unicode みんに string");
assertThat(rdapSearchPattern.getHasWildcard()).isFalse();
assertThat(rdapSearchPattern.getSuffix()).isNull();
}
@Test
public void testUnicodeString_withWildcard() {
RdapSearchPattern rdapSearchPattern =
RdapSearchPattern.createFromUnicodeString("unicode みんに string*");
assertThat(rdapSearchPattern.getInitialString()).isEqualTo("unicode みんに string");
assertThat(rdapSearchPattern.getHasWildcard()).isTrue();
assertThat(rdapSearchPattern.getSuffix()).isNull();
}
@Test
public void testUnicodeString_middleWildcard() {
assertThrows(
UnprocessableEntityException.class,
() -> RdapSearchPattern.createFromLdhDomainName("unicode みんに *string"));
}
}

View file

@ -34,7 +34,8 @@ import java.util.Objects;
public class RdapTestHelper {
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private static final Gson GSON =
new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
static JsonElement createJson(String... lines) {
return GSON.fromJson(Joiner.on("\n").join(lines), JsonElement.class);
@ -47,7 +48,7 @@ public class RdapTestHelper {
}
private static JsonObject createTosNotice(String linkBase) {
return new Gson().toJsonTree(
return GSON.toJsonTree(
ImmutableMap.of(
"title", "RDAP Terms of Service",
"description",
@ -90,13 +91,12 @@ public class RdapTestHelper {
notices.add(createTosNotice(linkBase));
notices.add(
new Gson()
.toJsonTree(
ImmutableMap.of(
"description",
ImmutableList.of(
"This response conforms to the RDAP Operational Profile for gTLD"
+ " Registries and Registrars version 1.0"))));
GSON.toJsonTree(
ImmutableMap.of(
"description",
ImmutableList.of(
"This response conforms to the RDAP Operational Profile for gTLD"
+ " Registries and Registrars version 1.0"))));
}
static void addDomainBoilerplateNotices(JsonObject jsonObject, String linkBase) {
@ -107,47 +107,44 @@ public class RdapTestHelper {
notices.add(createTosNotice(linkBase));
notices.add(
new Gson()
.toJsonTree(
ImmutableMap.of(
"description",
ImmutableList.of(
"This response conforms to the RDAP Operational Profile for gTLD"
+ " Registries and Registrars version 1.0"))));
GSON.toJsonTree(
ImmutableMap.of(
"description",
ImmutableList.of(
"This response conforms to the RDAP Operational Profile for gTLD"
+ " Registries and Registrars version 1.0"))));
notices.add(
new Gson()
.toJsonTree(
ImmutableMap.of(
"title",
"Status Codes",
"description",
ImmutableList.of(
"For more information on domain status codes, please visit"
+ " https://icann.org/epp"),
"links",
ImmutableList.of(
ImmutableMap.of(
"value", "https://icann.org/epp",
"rel", "alternate",
"href", "https://icann.org/epp",
"type", "text/html")))));
GSON.toJsonTree(
ImmutableMap.of(
"title",
"Status Codes",
"description",
ImmutableList.of(
"For more information on domain status codes, please visit"
+ " https://icann.org/epp"),
"links",
ImmutableList.of(
ImmutableMap.of(
"value", "https://icann.org/epp",
"rel", "alternate",
"href", "https://icann.org/epp",
"type", "text/html")))));
notices.add(
new Gson()
.toJsonTree(
ImmutableMap.of(
"title",
"RDDS Inaccuracy Complaint Form",
"description",
ImmutableList.of(
"URL of the ICANN RDDS Inaccuracy Complaint Form:"
+ " https://www.icann.org/wicf"),
"links",
ImmutableList.of(
ImmutableMap.of(
"value", "https://www.icann.org/wicf",
"rel", "alternate",
"href", "https://www.icann.org/wicf",
"type", "text/html")))));
GSON.toJsonTree(
ImmutableMap.of(
"title",
"RDDS Inaccuracy Complaint Form",
"description",
ImmutableList.of(
"URL of the ICANN RDDS Inaccuracy Complaint Form:"
+ " https://www.icann.org/wicf"),
"links",
ImmutableList.of(
ImmutableMap.of(
"value", "https://www.icann.org/wicf",
"rel", "alternate",
"href", "https://www.icann.org/wicf",
"type", "text/html")))));
}
static RdapJsonFormatter getTestRdapJsonFormatter(Clock clock) {

View file

@ -1,7 +1,8 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName": "entity",
"handle": "%NAME%",

View file

@ -1,7 +1,8 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName" : "entity",
"handle" : "REDACTED FOR PRIVACY",

View file

@ -1,7 +1,8 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName" : "entity",
"handle" : "%NAME%",

View file

@ -1,7 +1,8 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName" : "entity",
"handle" : "%NAME%",

View file

@ -1,7 +1,8 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName" : "entity",
"handle" : "REDACTED FOR PRIVACY",

View file

@ -4,7 +4,8 @@
"handle": "%DOMAIN_HANDLE_1%",
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"status": [
"client delete prohibited",

View file

@ -1,7 +1,8 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName": "domain",
"handle": "%DOMAIN_HANDLE_1%",

View file

@ -1,7 +1,8 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName": "domain",
"ldhName": "%DOMAIN_PUNYCODE_NAME_1%",

View file

@ -1,7 +1,8 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName": "domain",
"handle": "%DOMAIN_HANDLE_1%",

View file

@ -5,7 +5,8 @@
"handle": "%DOMAIN_HANDLE_1%",
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"status": [
"client delete prohibited",

View file

@ -1,7 +1,8 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName": "domain",
"handle": "%DOMAIN_HANDLE_1%",

View file

@ -83,7 +83,8 @@
],
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices" :
[

View file

@ -84,7 +84,8 @@
],
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices" :
[

View file

@ -84,7 +84,8 @@
],
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices" :
[

View file

@ -1,7 +1,8 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"domainSearchResults": [
{

View file

@ -7,7 +7,8 @@
],
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices": [
{

View file

@ -1,5 +1,9 @@
{
"rdapConformance" : ["rdap_level_0", "icann_rdap_response_profile_0"],
"rdapConformance" : [
"rdap_level_0",
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices" :
[
{

View file

@ -1,5 +1,9 @@
{
"rdapConformance" : ["rdap_level_0", "icann_rdap_response_profile_0"],
"rdapConformance" : [
"rdap_level_0",
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices" :
[
{

View file

@ -1,7 +1,8 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName": "nameserver",
"handle": "%HANDLE%",

View file

@ -1,7 +1,8 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"status": [
"active"

View file

@ -1,7 +1,8 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName": "nameserver",
"handle": "%HANDLE%",

View file

@ -1,7 +1,8 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName": "nameserver",
"handle": "%HANDLE%",

View file

@ -142,9 +142,9 @@
]
}
],
"rdapConformance":
[
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
]
}

View file

@ -110,6 +110,7 @@
],
"rdapConformance":[
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
]
}

View file

@ -101,7 +101,11 @@
]
}
],
"rdapConformance": ["rdap_level_0", "icann_rdap_response_profile_0" ],
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices" :
[
{

View file

@ -116,7 +116,11 @@
]
}
],
"rdapConformance": ["rdap_level_0", "icann_rdap_response_profile_0" ],
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices" :
[
{

View file

@ -69,7 +69,11 @@
]
}
],
"rdapConformance" : ["rdap_level_0", "icann_rdap_response_profile_0"],
"rdapConformance" : [
"rdap_level_0",
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices" :
[
{

View file

@ -230,7 +230,11 @@
]
}
],
"rdapConformance": ["rdap_level_0", "icann_rdap_response_profile_0" ],
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices" :
[
{

View file

@ -91,7 +91,8 @@
],
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices" :
[

View file

@ -134,7 +134,11 @@
]
}
],
"rdapConformance" : ["rdap_level_0", "icann_rdap_response_profile_0"],
"rdapConformance" : [
"rdap_level_0",
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices" :
[
{

View file

@ -234,7 +234,11 @@
"roles": ["registrar"]
}
],
"rdapConformance": ["rdap_level_0", "icann_rdap_response_profile_0" ],
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices":
[
{

View file

@ -1,7 +1,8 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName" : "entity",
"handle" : "%NAME%",

View file

@ -1,7 +1,8 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName" : "entity",
"handle" : "%NAME%",

View file

@ -230,7 +230,11 @@
]
}
],
"rdapConformance": ["rdap_level_0", "icann_rdap_response_profile_0" ],
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices":
[
{

View file

@ -134,7 +134,11 @@
]
}
],
"rdapConformance" : ["rdap_level_0", "icann_rdap_response_profile_0"],
"rdapConformance" : [
"rdap_level_0",
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices" :
[
{

View file

@ -231,7 +231,11 @@
"roles" : ["registrar"]
}
],
"rdapConformance": ["rdap_level_0", "icann_rdap_response_profile_0" ],
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices" :
[
{

View file

@ -234,7 +234,11 @@
"roles" : ["registrar"]
}
],
"rdapConformance": ["rdap_level_0", "icann_rdap_response_profile_0" ],
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices" :
[
{

View file

@ -1 +1 @@
{"key":"value","rdapConformance":["rdap_level_0","icann_rdap_response_profile_0"],"notices":[{"title":"RDAP Terms of Service","links":[{"href":"https:\/\/www.registry.tld\/about\/rdap\/tos.html","rel":"alternate","type":"text\/html","value":"http:\/\/myserver.example.com\/help\/tos"}],"description":["By querying our Domain Database, you are agreeing to comply with these terms so please read them carefully.","Any information provided is 'as is' without any guarantee of accuracy.","Please do not misuse the Domain Database. It is intended solely for query-based access.","Don't use the Domain Database to allow, enable, or otherwise support the transmission of mass unsolicited, commercial advertising or solicitations.","Don't access our Domain Database through the use of high volume, automated electronic processes that send queries or data to the systems of any ICANN-accredited registrar.","You may only use the information contained in the Domain Database for lawful purposes.","Do not compile, repackage, disseminate, or otherwise use the information contained in the Domain Database in its entirety, or in any substantial portion, without our prior written permission.","We may retain certain details about queries to our Domain Database for the purposes of detecting and preventing misuse.","We reserve the right to restrict or deny your access to the database if we suspect that you have failed to comply with these terms.","We reserve the right to modify this agreement at any time."]}]}
{"key":"value","rdapConformance":["rdap_level_0","icann_rdap_response_profile_0","icann_rdap_technical_implementation_guide_0"],"notices":[{"title":"RDAP Terms of Service","links":[{"href":"https:\/\/www.registry.tld\/about\/rdap\/tos.html","rel":"alternate","type":"text\/html","value":"http:\/\/myserver.example.com\/help\/tos"}],"description":["By querying our Domain Database, you are agreeing to comply with these terms so please read them carefully.","Any information provided is 'as is' without any guarantee of accuracy.","Please do not misuse the Domain Database. It is intended solely for query-based access.","Don't use the Domain Database to allow, enable, or otherwise support the transmission of mass unsolicited, commercial advertising or solicitations.","Don't access our Domain Database through the use of high volume, automated electronic processes that send queries or data to the systems of any ICANN-accredited registrar.","You may only use the information contained in the Domain Database for lawful purposes.","Do not compile, repackage, disseminate, or otherwise use the information contained in the Domain Database in its entirety, or in any substantial portion, without our prior written permission.","We may retain certain details about queries to our Domain Database for the purposes of detecting and preventing misuse.","We reserve the right to restrict or deny your access to the database if we suspect that you have failed to comply with these terms.","We reserve the right to modify this agreement at any time."]}]}

View file

@ -1,9 +1,9 @@
{
"key" : "value",
"rdapConformance" :
[
"rdapConformance" : [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices" :
[

View file

@ -1,9 +1,9 @@
{
"key": "value",
"rdapConformance":
[
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0"
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"notices":
[