Reimplement the RDAP Json creation using Jsonables

Currently we try to reimplemnet the same behavior of the existing code as much
as possible.

We only fix issues that go against the RFC7483, but we don't yet update the
code to follow the latest (15feb19) RDAP Response Profile. That will require a
much bigger change especially for the test files, so it'll wait for a followup
CL.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=246948018
This commit is contained in:
guyben 2019-05-06 20:25:56 -07:00 committed by jianglai
parent 5e2a20cdcf
commit 7202a38f8b
85 changed files with 2589 additions and 2367 deletions

View file

@ -19,15 +19,13 @@ import static com.google.common.truth.Truth.assertThat;
import static google.registry.request.Action.Method.GET;
import static google.registry.request.Action.Method.HEAD;
import static google.registry.testing.DatastoreHelper.createTld;
import static google.registry.testing.TestDataHelper.loadFile;
import static org.mockito.Mockito.verify;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import google.registry.rdap.RdapJsonFormatter.BoilerplateType;
import google.registry.rdap.RdapMetrics.EndpointType;
import google.registry.rdap.RdapMetrics.SearchType;
import google.registry.rdap.RdapMetrics.WildcardType;
import google.registry.rdap.RdapObjectClasses.BoilerplateType;
import google.registry.rdap.RdapObjectClasses.ReplyPayloadBase;
import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
import google.registry.request.Action;
import google.registry.request.auth.Auth;
@ -59,7 +57,7 @@ public class RdapActionBaseTest extends RdapActionBaseTestCase<RdapActionBaseTes
}
@Override
public ImmutableMap<String, Object> getJsonObjectForResource(
public ReplyPayloadBase getJsonObjectForResource(
String pathSearchString, boolean isHeadRequest) {
if (pathSearchString.equals("IllegalArgumentException")) {
throw new IllegalArgumentException();
@ -67,46 +65,36 @@ public class RdapActionBaseTest extends RdapActionBaseTestCase<RdapActionBaseTes
if (pathSearchString.equals("RuntimeException")) {
throw new RuntimeException();
}
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
builder.put("key", "value");
rdapJsonFormatter.addTopLevelEntries(
builder,
BoilerplateType.OTHER,
ImmutableList.of(),
ImmutableList.of(),
"http://myserver.example.com/");
return builder.build();
return new ReplyPayloadBase(BoilerplateType.OTHER) {
@JsonableElement public String key = "value";
};
}
}
@Before
public void setUp() {
createTld("thing");
action.fullServletPath = "http://myserver.example.com" + actionPath;
action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter();
}
@Test
public void testIllegalValue_showsReadableTypeName() {
assertThat(generateActualJson("IllegalArgumentException")).isEqualTo(JSONValue.parse(
"{\"lang\":\"en\", \"errorCode\":400, \"title\":\"Bad Request\","
+ "\"rdapConformance\":[\"icann_rdap_response_profile_0\"],"
+ "\"description\":[\"Not a valid human-readable string\"]}"));
assertThat(generateActualJson("IllegalArgumentException")).isEqualTo(generateExpectedJsonError(
"Not a valid human-readable string",
400));
assertThat(response.getStatus()).isEqualTo(400);
}
@Test
public void testRuntimeException_returns500Error() {
assertThat(generateActualJson("RuntimeException")).isEqualTo(JSONValue.parse(
"{\"lang\":\"en\", \"errorCode\":500, \"title\":\"Internal Server Error\","
+ "\"rdapConformance\":[\"icann_rdap_response_profile_0\"],"
+ "\"description\":[\"An error was encountered\"]}"));
assertThat(generateActualJson("RuntimeException"))
.isEqualTo(generateExpectedJsonError("An error was encountered", 500));
assertThat(response.getStatus()).isEqualTo(500);
}
@Test
public void testValidName_works() {
assertThat(generateActualJson("no.thing")).isEqualTo(JSONValue.parse(
loadFile(this.getClass(), "rdapjson_toplevel.json")));
assertThat(generateActualJson("no.thing")).isEqualTo(loadJsonFile("rdapjson_toplevel.json"));
assertThat(response.getStatus()).isEqualTo(200);
}
@ -173,18 +161,14 @@ public class RdapActionBaseTest extends RdapActionBaseTestCase<RdapActionBaseTes
.build());
}
private String loadFileWithoutTrailingNewline(String fileName) {
String contents = loadFile(this.getClass(), fileName);
return contents.endsWith("\n") ? contents.substring(0, contents.length() - 1) : contents;
}
@Test
public void testUnformatted() {
action.requestPath = actionPath + "no.thing";
action.requestMethod = GET;
action.run();
assertThat(response.getPayload())
.isEqualTo(loadFileWithoutTrailingNewline("rdap_unformatted_output.json"));
String payload = response.getPayload();
assertThat(payload).doesNotContain("\n");
assertThat(JSONValue.parse(payload)).isEqualTo(loadJsonFile("rdapjson_toplevel.json"));
}
@Test
@ -193,7 +177,8 @@ public class RdapActionBaseTest extends RdapActionBaseTestCase<RdapActionBaseTes
action.requestMethod = GET;
action.formatOutputParam = Optional.of(true);
action.run();
assertThat(response.getPayload())
.isEqualTo(loadFileWithoutTrailingNewline("rdap_formatted_output.json"));
String payload = response.getPayload();
assertThat(payload).contains("\n");
assertThat(JSONValue.parse(payload)).isEqualTo(loadJsonFile("rdapjson_toplevel.json"));
}
}

View file

@ -14,16 +14,19 @@
package google.registry.rdap;
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.rdap.RdapAuthorization.Role.ADMINISTRATOR;
import static google.registry.rdap.RdapAuthorization.Role.PUBLIC;
import static google.registry.rdap.RdapAuthorization.Role.REGISTRAR;
import static google.registry.request.Action.Method.GET;
import static google.registry.request.Action.Method.HEAD;
import static google.registry.request.auth.AuthenticatedRegistrarAccessor.Role.OWNER;
import static google.registry.testing.TestDataHelper.loadFile;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.google.appengine.api.users.User;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSetMultimap;
import google.registry.model.ofy.Ofy;
import google.registry.request.Action;
@ -37,8 +40,10 @@ import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse;
import google.registry.testing.InjectRule;
import google.registry.util.TypeUtils;
import java.util.Map;
import java.util.Optional;
import org.joda.time.DateTime;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.junit.Before;
import org.junit.Rule;
@ -99,7 +104,6 @@ public class RdapActionBaseTestCase<A extends RdapActionBase> {
action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter();
action.rdapMetrics = rdapMetrics;
action.requestMethod = Action.Method.GET;
action.fullServletPath = "https://example.tld/rdap";
action.rdapWhoisServer = null;
logout();
}
@ -126,18 +130,80 @@ public class RdapActionBaseTestCase<A extends RdapActionBase> {
metricRole = ADMINISTRATOR;
}
protected Object generateActualJson(String domainName) {
protected JSONObject generateActualJson(String domainName) {
action.requestPath = actionPath + domainName;
action.requestMethod = GET;
action.run();
return JSONValue.parse(response.getPayload());
return (JSONObject) JSONValue.parse(response.getPayload());
}
protected String generateHeadPayload(String domainName) {
action.requestPath = actionPath + domainName;
action.fullServletPath = "http://myserver.example.com" + actionPath;
action.requestMethod = HEAD;
action.run();
return response.getPayload();
}
/**
* Loads a resource testdata JSON file, and applies substitutions.
*
* <p>{@code loadJsonFile("filename.json", "NANE", "something", "ID", "other")} is the same as
* {@code loadJsonFile("filename.json", ImmutableMap.of("NANE", "something", "ID", "other"))}.
*
* @param filename the name of the file from the testdata directory
* @param keysAndValues alternating substitution key and value. The substitutions are applied to
* the file before parsing it to JSON.
*/
protected JSONObject loadJsonFile(String filename, String... keysAndValues) {
checkArgument(keysAndValues.length % 2 == 0);
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<>();
for (int i = 0; i < keysAndValues.length; i += 2) {
if (keysAndValues[i + 1] != null) {
builder.put(keysAndValues[i], keysAndValues[i + 1]);
}
}
return loadJsonFile(filename, builder.build());
}
/**
* Loads a resource testdata JSON file, and applies substitutions.
*
* @param filename the name of the file from the testdata directory
* @param substitutions map of substitutions to apply to the file. The substitutions are applied
* to the file before parsing it to JSON.
*/
protected JSONObject loadJsonFile(String filename, Map<String, String> substitutions) {
return (JSONObject) JSONValue.parse(loadFile(this.getClass(), filename, substitutions));
}
protected JSONObject generateExpectedJsonError(
String description,
int code) {
String title;
switch (code) {
case 404:
title = "Not Found";
break;
case 500:
title = "Internal Server Error";
break;
case 501:
title = "Not Implemented";
break;
case 400:
title = "Bad Request";
break;
case 422:
title = "Unprocessable Entity";
break;
default:
title = "ERR";
break;
}
return loadJsonFile(
"rdap_error.json",
"DESCRIPTION", description,
"TITLE", title,
"CODE", String.valueOf(code));
}
}

View file

@ -0,0 +1,177 @@
// Copyright 2019 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.rdap;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.rdap.RdapTestHelper.createJson;
import com.google.common.collect.ImmutableSet;
import google.registry.rdap.RdapDataStructures.Event;
import google.registry.rdap.RdapDataStructures.EventAction;
import google.registry.rdap.RdapDataStructures.EventWithoutActor;
import google.registry.rdap.RdapDataStructures.LanguageIdentifier;
import google.registry.rdap.RdapDataStructures.Link;
import google.registry.rdap.RdapDataStructures.Notice;
import google.registry.rdap.RdapDataStructures.ObjectClassName;
import google.registry.rdap.RdapDataStructures.Port43WhoisServer;
import google.registry.rdap.RdapDataStructures.PublicId;
import google.registry.rdap.RdapDataStructures.RdapConformance;
import google.registry.rdap.RdapDataStructures.RdapStatus;
import google.registry.rdap.RdapDataStructures.Remark;
import org.joda.time.DateTime;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public final class RdapDataStructuresTest {
private void assertRestrictedNames(Object object, String... names) {
assertThat(AbstractJsonableObject.getNameRestriction(object.getClass()).get())
.containsExactlyElementsIn(ImmutableSet.copyOf(names));
}
@Test
public void testRdapConformance() {
assertThat(RdapConformance.INSTANCE.toJson())
.isEqualTo(createJson("['icann_rdap_response_profile_0']"));
}
@Test
public void testLink() {
Link link =
Link.builder()
.setHref("myHref")
.setRel("myRel")
.setTitle("myTitle")
.setType("myType")
.build();
assertThat(link.toJson())
.isEqualTo(createJson("{'href':'myHref','rel':'myRel','title':'myTitle','type':'myType'}"));
assertRestrictedNames(link, "links[]");
}
@Test
public void testNotice() {
Notice notice = Notice.builder()
.setDescription("AAA", "BBB")
.setTitle("myTitle")
.addLink(Link.builder().setHref("myHref").setTitle("myLink").build())
.setType(Notice.Type.RESULT_TRUNCATED_AUTHORIZATION)
.build();
assertThat(notice.toJson())
.isEqualTo(
createJson(
"{",
" 'title':'myTitle',",
" 'type':'result set truncated due to authorization',",
" 'description':['AAA','BBB'],",
" 'links':[{'href':'myHref','title':'myLink'}]",
"}"));
assertRestrictedNames(notice, "notices[]");
}
@Test
public void testRemark() {
Remark remark = Remark.builder()
.setDescription("AAA", "BBB")
.setTitle("myTitle")
.addLink(Link.builder().setHref("myHref").setTitle("myLink").build())
.setType(Remark.Type.OBJECT_TRUNCATED_AUTHORIZATION)
.build();
assertThat(remark.toJson())
.isEqualTo(
createJson(
"{",
" 'title':'myTitle',",
" 'type':'object truncated due to authorization',",
" 'description':['AAA','BBB'],",
" 'links':[{'href':'myHref','title':'myLink'}]",
"}"));
assertRestrictedNames(remark, "remarks[]");
}
@Test
public void testLanguage() {
assertThat(LanguageIdentifier.EN.toJson()).isEqualTo(createJson("'en'"));
assertRestrictedNames(LanguageIdentifier.EN, "lang");
}
@Test
public void testEvent() {
Event event =
Event.builder()
.setEventAction(EventAction.REGISTRATION)
.setEventActor("Event Actor")
.setEventDate(DateTime.parse("2012-04-03T14:54Z"))
.addLink(Link.builder().setHref("myHref").build())
.build();
assertThat(event.toJson())
.isEqualTo(
createJson(
"{",
" 'eventAction':'registration',",
" 'eventActor':'Event Actor',",
" 'eventDate':'2012-04-03T14:54:00.000Z',",
" 'links':[{'href':'myHref'}]",
"}"));
assertRestrictedNames(event, "events[]");
}
@Test
public void testEventWithoutActor() {
EventWithoutActor event =
EventWithoutActor.builder()
.setEventAction(EventAction.REGISTRATION)
.setEventDate(DateTime.parse("2012-04-03T14:54Z"))
.addLink(Link.builder().setHref("myHref").build())
.build();
assertThat(event.toJson())
.isEqualTo(
createJson(
"{",
" 'eventAction':'registration',",
" 'eventDate':'2012-04-03T14:54:00.000Z',",
" 'links':[{'href':'myHref'}]",
"}"));
assertRestrictedNames(event, "asEventActor[]");
}
@Test
public void testRdapStatus() {
assertThat(RdapStatus.ACTIVE.toJson()).isEqualTo(createJson("'active'"));
assertRestrictedNames(RdapStatus.ACTIVE, "status[]");
}
@Test
public void testPort43() {
Port43WhoisServer port43 = Port43WhoisServer.create("myServer");
assertThat(port43.toJson()).isEqualTo(createJson("'myServer'"));
assertRestrictedNames(port43, "port43");
}
@Test
public void testPublicId() {
PublicId publicId = PublicId.create(PublicId.Type.IANA_REGISTRAR_ID, "myId");
assertThat(publicId.toJson())
.isEqualTo(createJson("{'identifier':'myId','type':'IANA Registrar ID'}"));
assertRestrictedNames(publicId, "publicIds[]");
}
@Test
public void testObjectClassName() {
assertThat(ObjectClassName.DOMAIN.toJson()).isEqualTo(createJson("'domain'"));
assertRestrictedNames(ObjectClassName.DOMAIN, "objectClassName");
}
}

View file

@ -24,7 +24,6 @@ import static google.registry.testing.FullFieldsTestEntityHelper.makeDomainBase;
import static google.registry.testing.FullFieldsTestEntityHelper.makeHistoryEntry;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts;
import static google.registry.testing.TestDataHelper.loadFile;
import static org.mockito.Mockito.verify;
import com.google.common.collect.ImmutableList;
@ -47,7 +46,6 @@ import java.util.Map;
import java.util.Optional;
import javax.annotation.Nullable;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@ -230,24 +228,15 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
clock.nowUtc().minusMonths(6)));
}
private Object generateExpectedJson(
String name,
String punycodeName,
String handle,
String expectedOutputFile) {
return generateExpectedJson(
name, punycodeName, handle, null, null, null, null, expectedOutputFile);
}
private Object generateExpectedJson(
private JSONObject generateExpectedJson(
String expectedOutputFile,
String name,
String punycodeName,
String handle,
@Nullable List<String> contactRoids,
@Nullable List<String> nameserverRoids,
@Nullable List<String> nameserverNames,
@Nullable String registrarName,
String expectedOutputFile) {
@Nullable String registrarName) {
ImmutableMap.Builder<String, String> substitutionsBuilder = new ImmutableMap.Builder<>();
substitutionsBuilder.put("NAME", name);
substitutionsBuilder.put("PUNYCODENAME", (punycodeName == null) ? name : punycodeName);
@ -282,11 +271,10 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
substitutionsBuilder.put("NAMESERVER2NAME", "ns2.cat.lol");
substitutionsBuilder.put("NAMESERVER2PUNYCODENAME", "ns2.cat.lol");
}
return JSONValue.parse(
loadFile(this.getClass(), expectedOutputFile, substitutionsBuilder.build()));
return loadJsonFile(expectedOutputFile, substitutionsBuilder.build());
}
private Object generateExpectedJsonWithTopLevelEntries(
private JSONObject generateExpectedJsonWithTopLevelEntries(
String name,
String punycodeName,
String handle,
@ -304,7 +292,7 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
registrarName,
expectedOutputFile);
}
private Object generateExpectedJsonWithTopLevelEntries(
private JSONObject generateExpectedJsonWithTopLevelEntries(
String name,
String punycodeName,
String handle,
@ -313,34 +301,23 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
@Nullable List<String> nameserverNames,
@Nullable String registrarName,
String expectedOutputFile) {
Object obj =
JSONObject obj =
generateExpectedJson(
expectedOutputFile,
name,
punycodeName,
handle,
contactRoids,
nameserverRoids,
nameserverNames,
registrarName,
expectedOutputFile);
if (obj instanceof Map) {
registrarName);
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) obj;
ImmutableMap.Builder<String, Object> builder =
RdapTestHelper.getBuilderExcluding(
map, ImmutableSet.of("rdapConformance", "notices", "remarks"));
builder.put("rdapConformance", ImmutableList.of("icann_rdap_response_profile_0"));
RdapTestHelper.getBuilderExcluding(map, ImmutableSet.of("notices"));
RdapTestHelper.addDomainBoilerplateNotices(
builder,
false,
RdapTestHelper.createNotices(
"https://example.tld/rdap/",
(contactRoids == null)
? RdapTestHelper.ContactNoticeType.DOMAIN
: RdapTestHelper.ContactNoticeType.NONE,
map.get("notices")));
builder, RdapTestHelper.createNotices("https://example.tld/rdap/", map.get("notices")));
obj = new JSONObject(builder.build());
}
return obj;
}
@ -361,9 +338,7 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
"cat.lol",
null,
"C-LOL",
expectedOutputFile.equals("rdap_domain.json")
? ImmutableList.of("4-ROID", "6-ROID", "2-ROID")
: null,
ImmutableList.of("4-ROID", "6-ROID", "2-ROID"),
ImmutableList.of("8-ROID", "A-ROID"),
"Yes Virginia <script>",
expectedOutputFile));
@ -374,12 +349,10 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
public void testInvalidDomain_returns400() {
assertJsonEqual(
generateActualJson("invalid/domain/name"),
generateExpectedJson(
generateExpectedJsonError(
"invalid/domain/name is not a valid domain name: Domain names can only contain a-z,"
+ " 0-9, '.' and '-'",
null,
"1",
"rdap_error_400.json"));
400));
assertThat(response.getStatus()).isEqualTo(400);
}
@ -387,12 +360,10 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
public void testUnknownDomain_returns400() {
assertJsonEqual(
generateActualJson("missingdomain.com"),
generateExpectedJson(
generateExpectedJsonError(
"missingdomain.com is not a valid domain name: Domain name is under tld com which"
+ " doesn't exist",
null,
"1",
"rdap_error_400.json"));
400));
assertThat(response.getStatus()).isEqualTo(400);
}
@ -424,28 +395,28 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
@Test
public void testValidDomain_notLoggedIn_noContacts() {
assertProperResponseForCatLol("cat.lol", "rdap_domain_no_contacts.json");
assertProperResponseForCatLol("cat.lol", "rdap_domain_no_contacts_with_remark.json");
}
@Test
public void testValidDomain_loggedInAsOtherRegistrar_noContacts() {
login("idnregistrar");
assertProperResponseForCatLol("cat.lol", "rdap_domain_no_contacts.json");
assertProperResponseForCatLol("cat.lol", "rdap_domain_no_contacts_with_remark.json");
}
@Test
public void testUpperCase_ignored() {
assertProperResponseForCatLol("CaT.lOl", "rdap_domain_no_contacts.json");
assertProperResponseForCatLol("CaT.lOl", "rdap_domain_no_contacts_with_remark.json");
}
@Test
public void testTrailingDot_ignored() {
assertProperResponseForCatLol("cat.lol.", "rdap_domain_no_contacts.json");
assertProperResponseForCatLol("cat.lol.", "rdap_domain_no_contacts_with_remark.json");
}
@Test
public void testQueryParameter_ignored() {
assertProperResponseForCatLol("cat.lol?key=value", "rdap_domain_no_contacts.json");
assertProperResponseForCatLol("cat.lol?key=value", "rdap_domain_no_contacts_with_remark.json");
}
@Test
@ -525,7 +496,7 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
public void testDeletedDomain_notFound() {
assertJsonEqual(
generateActualJson("dodo.lol"),
generateExpectedJson("dodo.lol not found", null, "1", "rdap_error_404.json"));
generateExpectedJsonError("dodo.lol not found", 404));
assertThat(response.getStatus()).isEqualTo(404);
}

View file

@ -28,7 +28,6 @@ import static google.registry.testing.FullFieldsTestEntityHelper.makeDomainBase;
import static google.registry.testing.FullFieldsTestEntityHelper.makeHistoryEntry;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts;
import static google.registry.testing.TestDataHelper.loadFile;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
@ -90,11 +89,11 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
enum RequestType { NONE, NAME, NS_LDH_NAME, NS_IP }
private Object generateActualJson(RequestType requestType, String paramValue) {
private JSONObject generateActualJson(RequestType requestType, String paramValue) {
return generateActualJson(requestType, paramValue, null);
}
private Object generateActualJson(
private JSONObject generateActualJson(
RequestType requestType, String paramValue, String cursor) {
action.requestPath = actionPath;
action.requestMethod = POST;
@ -136,7 +135,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
}
}
action.run();
return JSONValue.parse(response.getPayload());
return (JSONObject) JSONValue.parse(response.getPayload());
}
private HostResource addHostToMap(HostResource host) {
@ -363,27 +362,25 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
action.requestMethod = POST;
}
private Object generateExpectedJsonForTwoDomains() {
private JSONObject generateExpectedJsonForTwoDomains() {
return generateExpectedJsonForTwoDomains("cat.example", "21-EXAMPLE", "cat.lol", "C-LOL");
}
private Object generateExpectedJsonForTwoDomains(
private JSONObject generateExpectedJsonForTwoDomains(
String domain1Name,
String domain1Handle,
String domain2Name,
String domain2Handle) {
return JSONValue.parse(loadFile(
this.getClass(),
return loadJsonFile(
"rdap_domains_two.json",
ImmutableMap.of(
"TYPE", "domain name",
"DOMAINNAME1", domain1Name,
"DOMAINHANDLE1", domain1Handle,
"DOMAINNAME2", domain2Name,
"DOMAINHANDLE2", domain2Handle)));
"TYPE", "domain name",
"DOMAINNAME1", domain1Name,
"DOMAINHANDLE1", domain1Handle,
"DOMAINNAME2", domain2Name,
"DOMAINHANDLE2", domain2Handle);
}
private Object generateExpectedJsonForFourDomains(
private JSONObject generateExpectedJsonForFourDomains(
String domain1Name,
String domain1Handle,
String domain2Name,
@ -406,7 +403,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
expectedOutputFile);
}
private Object generateExpectedJsonForFourDomains(
private JSONObject generateExpectedJsonForFourDomains(
String domain1Name,
String domain1Handle,
String domain2Name,
@ -417,33 +414,25 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
String domain4Handle,
String nextQuery,
String expectedOutputFile) {
return JSONValue.parse(
loadFile(
this.getClass(),
expectedOutputFile,
new ImmutableMap.Builder<String, String>()
.put("TYPE", "domain name")
.put("DOMAINPUNYCODENAME1", domain1Name)
.put("DOMAINNAME1", IDN.toUnicode(domain1Name))
.put("DOMAINHANDLE1", domain1Handle)
.put("DOMAINPUNYCODENAME2", domain2Name)
.put("DOMAINNAME2", IDN.toUnicode(domain2Name))
.put("DOMAINHANDLE2", domain2Handle)
.put("DOMAINPUNYCODENAME3", domain3Name)
.put("DOMAINNAME3", IDN.toUnicode(domain3Name))
.put("DOMAINHANDLE3", domain3Handle)
.put("DOMAINPUNYCODENAME4", domain4Name)
.put("DOMAINNAME4", IDN.toUnicode(domain4Name))
.put("DOMAINHANDLE4", domain4Handle)
.put("NEXT_QUERY", nextQuery)
.build()));
return loadJsonFile(
expectedOutputFile,
"TYPE", "domain name",
"DOMAINPUNYCODENAME1", domain1Name,
"DOMAINNAME1", IDN.toUnicode(domain1Name),
"DOMAINHANDLE1", domain1Handle,
"DOMAINPUNYCODENAME2", domain2Name,
"DOMAINNAME2", IDN.toUnicode(domain2Name),
"DOMAINHANDLE2", domain2Handle,
"DOMAINPUNYCODENAME3", domain3Name,
"DOMAINNAME3", IDN.toUnicode(domain3Name),
"DOMAINHANDLE3", domain3Handle,
"DOMAINPUNYCODENAME4", domain4Name,
"DOMAINNAME4", IDN.toUnicode(domain4Name),
"DOMAINHANDLE4", domain4Handle,
"NEXT_QUERY", nextQuery);
}
private Object generateExpectedJson(String name, String expectedOutputFile) {
return generateExpectedJson(name, null, null, null, null, null, expectedOutputFile);
}
private Object generateExpectedJson(
private JSONObject generateExpectedJson(
String name,
String punycodeName,
String handle,
@ -476,11 +465,10 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
if (registrarName != null) {
substitutionsBuilder.put("REGISTRARNAME", registrarName);
}
return JSONValue.parse(
loadFile(this.getClass(), expectedOutputFile, substitutionsBuilder.build()));
return loadJsonFile(expectedOutputFile, substitutionsBuilder.build());
}
private Object generateExpectedJsonForDomain(
private JSONObject generateExpectedJsonForDomain(
String name,
String punycodeName,
String handle,
@ -488,7 +476,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
@Nullable List<String> nameservers,
@Nullable String registrarName,
String expectedOutputFile) {
Object obj =
JSONObject obj =
generateExpectedJson(
name,
punycodeName,
@ -497,6 +485,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
nameservers,
registrarName,
expectedOutputFile);
obj.remove("rdapConformance");
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
builder.put("domainSearchResults", ImmutableList.of(obj));
builder.put("rdapConformance", ImmutableList.of("icann_rdap_response_profile_0"));
@ -560,7 +549,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
persistResources(domainsBuilder.build());
}
private Object readMultiDomainFile(
private JSONObject readMultiDomainFile(
String fileName,
String domainName1,
String domainHandle1,
@ -583,7 +572,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
"none");
}
private Object readMultiDomainFile(
private JSONObject readMultiDomainFile(
String fileName,
String domainName1,
String domainHandle1,
@ -594,30 +583,24 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
String domainName4,
String domainHandle4,
String nextQuery) {
return JSONValue.parse(loadFile(
this.getClass(),
return loadJsonFile(
fileName,
new ImmutableMap.Builder<String, String>()
.put("DOMAINNAME1", domainName1)
.put("DOMAINHANDLE1", domainHandle1)
.put("DOMAINNAME2", domainName2)
.put("DOMAINHANDLE2", domainHandle2)
.put("DOMAINNAME3", domainName3)
.put("DOMAINHANDLE3", domainHandle3)
.put("DOMAINNAME4", domainName4)
.put("DOMAINHANDLE4", domainHandle4)
.put("NEXT_QUERY", nextQuery)
.build()));
"DOMAINNAME1", domainName1,
"DOMAINHANDLE1", domainHandle1,
"DOMAINNAME2", domainName2,
"DOMAINHANDLE2", domainHandle2,
"DOMAINNAME3", domainName3,
"DOMAINHANDLE3", domainHandle3,
"DOMAINNAME4", domainName4,
"DOMAINHANDLE4", domainHandle4,
"NEXT_QUERY", nextQuery);
}
private void checkNumberOfDomainsInResult(Object obj, int expected) {
private void checkNumberOfDomainsInResult(JSONObject obj, int expected) {
assertThat(obj).isInstanceOf(Map.class);
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) obj;
@SuppressWarnings("unchecked")
List<Object> domains = (List<Object>) map.get("domainSearchResults");
List<Object> domains = (List<Object>) obj.get("domainSearchResults");
assertThat(domains).hasSize(expected);
}
@ -717,7 +700,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
RequestType requestType, String queryString, String errorMessage) {
rememberWildcardType(queryString);
assertThat(generateActualJson(requestType, queryString))
.isEqualTo(generateExpectedJson(errorMessage, "rdap_error_404.json"));
.isEqualTo(generateExpectedJsonError(errorMessage, 404));
assertThat(response.getStatus()).isEqualTo(404);
}
@ -801,7 +784,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
int expectedPageCount =
(expectedNames.size() + action.rdapResultSetMaxSize - 1) / action.rdapResultSetMaxSize;
for (int pageNum = 0; pageNum < expectedPageCount; pageNum++) {
Object results = generateActualJson(requestType, paramValue, cursor);
JSONObject results = generateActualJson(requestType, paramValue, cursor);
assertThat(response.getStatus()).isEqualTo(200);
String linkToNext = RdapTestHelper.getLinkToNext(results);
if (pageNum == expectedPageCount - 1) {
@ -811,7 +794,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
int pos = linkToNext.indexOf("cursor=");
assertThat(pos).isAtLeast(0);
cursor = URLDecoder.decode(linkToNext.substring(pos + 7), "UTF-8");
Object searchResults = ((JSONObject) results).get("domainSearchResults");
Object searchResults = results.get("domainSearchResults");
assertThat(searchResults).isInstanceOf(JSONArray.class);
assertThat(((JSONArray) searchResults)).hasSize(action.rdapResultSetMaxSize);
for (Object item : ((JSONArray) searchResults)) {
@ -838,9 +821,9 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
@Test
public void testInvalidRequest_rejected() {
assertThat(generateActualJson(RequestType.NONE, null))
.isEqualTo(generateExpectedJson(
.isEqualTo(generateExpectedJsonError(
"You must specify either name=XXXX, nsLdhName=YYYY or nsIp=ZZZZ",
"rdap_error_400.json"));
400));
assertThat(response.getStatus()).isEqualTo(400);
verifyErrorMetrics(SearchType.NONE, Optional.empty(), 400);
}
@ -848,10 +831,10 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
@Test
public void testInvalidWildcard_rejected() {
assertThat(generateActualJson(RequestType.NAME, "exam*ple"))
.isEqualTo(generateExpectedJson(
.isEqualTo(generateExpectedJsonError(
"Suffix after wildcard must be one or more domain"
+ " name labels, e.g. exam*.tld, ns*.example.tld",
"rdap_error_422.json"));
422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME, Optional.empty(), 422);
}
@ -859,7 +842,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
@Test
public void testMultipleWildcards_rejected() {
assertThat(generateActualJson(RequestType.NAME, "*.*"))
.isEqualTo(generateExpectedJson("Only one wildcard allowed", "rdap_error_422.json"));
.isEqualTo(generateExpectedJsonError("Only one wildcard allowed", 422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME, Optional.empty(), 422);
}
@ -869,10 +852,10 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
rememberWildcardType("*");
assertThat(generateActualJson(RequestType.NAME, "*"))
.isEqualTo(
generateExpectedJson(
generateExpectedJsonError(
"Initial search string is required for wildcard domain searches without a TLD"
+ " suffix",
"rdap_error_422.json"));
422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME, Optional.empty(), 422);
}
@ -882,10 +865,10 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
rememberWildcardType("a*");
assertThat(generateActualJson(RequestType.NAME, "a*"))
.isEqualTo(
generateExpectedJson(
generateExpectedJsonError(
"Initial search string must be at least 2 characters for wildcard domain searches"
+ " without a TLD suffix",
"rdap_error_422.json"));
422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME, Optional.empty(), 422);
}
@ -1226,7 +1209,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
// There are enough domains to fill a full result set; deleted domains are ignored.
createManyDomainsAndHosts(4, 4, 2);
rememberWildcardType("domain*.lol");
Object obj = generateActualJson(RequestType.NAME, "domain*.lol");
JSONObject obj = generateActualJson(RequestType.NAME, "domain*.lol");
assertThat(response.getStatus()).isEqualTo(200);
checkNumberOfDomainsInResult(obj, 4);
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(16L));
@ -1237,7 +1220,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
// There are not enough domains to fill a full result set.
createManyDomainsAndHosts(3, 20, 2);
rememberWildcardType("domain*.lol");
Object obj = generateActualJson(RequestType.NAME, "domain*.lol");
JSONObject obj = generateActualJson(RequestType.NAME, "domain*.lol");
assertThat(response.getStatus()).isEqualTo(200);
checkNumberOfDomainsInResult(obj, 3);
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(60L));
@ -1682,7 +1665,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
// each one references the nameserver.
createManyDomainsAndHosts(3, 1, 40);
rememberWildcardType("ns1.domain1.lol");
Object obj = generateActualJson(RequestType.NS_LDH_NAME, "ns1.domain1.lol");
JSONObject obj = generateActualJson(RequestType.NS_LDH_NAME, "ns1.domain1.lol");
assertThat(response.getStatus()).isEqualTo(200);
checkNumberOfDomainsInResult(obj, 3);
verifyMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(3L), Optional.of(1L));
@ -1693,7 +1676,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
// Same as above, except with a wildcard (that still only finds one nameserver).
createManyDomainsAndHosts(3, 1, 40);
rememberWildcardType("ns1.domain1.l*");
Object obj = generateActualJson(RequestType.NS_LDH_NAME, "ns1.domain1.l*");
JSONObject obj = generateActualJson(RequestType.NS_LDH_NAME, "ns1.domain1.l*");
assertThat(response.getStatus()).isEqualTo(200);
checkNumberOfDomainsInResult(obj, 3);
verifyMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(3L), Optional.of(1L));
@ -1707,7 +1690,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
// have more than that number of nameservers for an effective test.
createManyDomainsAndHosts(3, 1, 39);
rememberWildcardType("ns*.domain1.lol");
Object obj = generateActualJson(RequestType.NS_LDH_NAME, "ns*.domain1.lol");
JSONObject obj = generateActualJson(RequestType.NS_LDH_NAME, "ns*.domain1.lol");
assertThat(response.getStatus()).isEqualTo(200);
checkNumberOfDomainsInResult(obj, 3);
verifyMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(3L), Optional.of(39L));

View file

@ -24,7 +24,6 @@ import static google.registry.testing.FullFieldsTestEntityHelper.makeDomainBase;
import static google.registry.testing.FullFieldsTestEntityHelper.makeHostResource;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts;
import static google.registry.testing.TestDataHelper.loadFile;
import static org.mockito.Mockito.verify;
import com.google.common.collect.ImmutableList;
@ -41,7 +40,7 @@ import google.registry.request.Action;
import java.util.Map;
import java.util.Optional;
import javax.annotation.Nullable;
import org.json.simple.JSONValue;
import org.json.simple.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -132,51 +131,27 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
clock.nowUtc().minusMonths(6));
}
private Object generateExpectedJson(String handle, String expectedOutputFile) {
return generateExpectedJson(handle, "(◕‿◕)", "", expectedOutputFile);
}
private Object generateExpectedJson(
String handle,
String status,
String expectedOutputFile) {
return generateExpectedJson(handle, "(◕‿◕)", status, expectedOutputFile);
}
private Object generateExpectedJson(
String handle,
String fullName,
String status,
String expectedOutputFile) {
return generateExpectedJson(
handle, fullName, status, null, expectedOutputFile);
}
private Object generateExpectedJson(
String handle,
String fullName,
String status,
@Nullable String address,
String expectedOutputFile) {
return JSONValue.parse(
loadFile(
this.getClass(),
expectedOutputFile,
new ImmutableMap.Builder<String, String>()
.put("NAME", handle)
.put("FULLNAME", fullName)
.put("ADDRESS", (address == null) ? "\"1 Smiley Row\", \"Suite みんな\"" : address)
.put("EMAIL", "lol@cat.みんな")
.put("TYPE", "entity")
.put("STATUS", status)
.build()));
return loadJsonFile(
expectedOutputFile,
"NAME", handle,
"FULLNAME", fullName,
"ADDRESS", (address == null) ? "\"1 Smiley Row\", \"Suite みんな\"" : address,
"EMAIL", "lol@cat.みんな",
"TYPE", "entity",
"STATUS", status);
}
private Object generateExpectedJsonWithTopLevelEntries(
String handle,
String expectedOutputFile) {
return generateExpectedJsonWithTopLevelEntries(
handle, "(◕‿◕)", "active", null, false, expectedOutputFile);
handle, "(◕‿◕)", "active", null, expectedOutputFile);
}
private Object generateExpectedJsonWithTopLevelEntries(
@ -184,35 +159,26 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
String fullName,
String status,
String address,
boolean addNoPersonalDataRemark,
String expectedOutputFile) {
Object obj = generateExpectedJson(handle, fullName, status, address, expectedOutputFile);
if (obj instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) obj;
ImmutableMap.Builder<String, Object> builder =
RdapTestHelper.getBuilderExcluding(
map, ImmutableSet.of("rdapConformance", "notices", "remarks"));
builder.put("rdapConformance", ImmutableList.of("icann_rdap_response_profile_0"));
RdapTestHelper.getBuilderExcluding(map, ImmutableSet.of("notices"));
RdapTestHelper.addNonDomainBoilerplateNotices(
builder,
RdapTestHelper.createNotices(
"https://example.tld/rdap/",
addNoPersonalDataRemark
? RdapTestHelper.ContactNoticeType.CONTACT
: RdapTestHelper.ContactNoticeType.NONE,
map.get("notices")));
obj = builder.build();
builder, RdapTestHelper.createNotices("https://example.tld/rdap/", map.get("notices")));
obj = new JSONObject(builder.build());
}
return obj;
}
private void runSuccessfulTest(String queryString, String fileName) {
runSuccessfulTest(queryString, "(◕‿◕)", "active", null, false, fileName);
runSuccessfulTest(queryString, "(◕‿◕)", "active", null, fileName);
}
private void runSuccessfulTest(String queryString, String fullName, String fileName) {
runSuccessfulTest(queryString, fullName, "active", null, false, fileName);
runSuccessfulTest(queryString, fullName, "active", null, fileName);
}
private void runSuccessfulTest(
@ -220,27 +186,26 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
String fullName,
String rdapStatus,
String address,
boolean addNoPersonalDataRemark,
String fileName) {
assertThat(generateActualJson(queryString))
.isEqualTo(
generateExpectedJsonWithTopLevelEntries(
queryString, fullName, rdapStatus, address, addNoPersonalDataRemark, fileName));
queryString, fullName, rdapStatus, address, fileName));
assertThat(response.getStatus()).isEqualTo(200);
}
private void runNotFoundTest(String queryString) {
assertThat(generateActualJson(queryString))
.isEqualTo(generateExpectedJson(queryString + " not found", "", "rdap_error_404.json"));
.isEqualTo(generateExpectedJsonError(queryString + " not found", 404));
assertThat(response.getStatus()).isEqualTo(404);
}
@Test
public void testInvalidEntity_returns400() {
assertThat(generateActualJson("invalid/entity/handle")).isEqualTo(
generateExpectedJson(
generateExpectedJsonError(
"invalid/entity/handle is not a valid entity handle",
"rdap_error_400.json"));
400));
assertThat(response.getStatus()).isEqualTo(400);
}
@ -282,7 +247,6 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
"(◕‿◕)",
"active",
null,
true,
"rdap_associated_contact_no_personal_data.json");
}
@ -294,7 +258,6 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
"(◕‿◕)",
"active",
null,
true,
"rdap_associated_contact_no_personal_data.json");
}
@ -349,7 +312,6 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
"",
"inactive",
"",
false,
"rdap_contact_deleted.json");
}
@ -362,7 +324,6 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
"",
"inactive",
"",
false,
"rdap_contact_deleted.json");
}
@ -409,7 +370,7 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
login("deletedregistrar");
action.includeDeletedParam = Optional.of(true);
runSuccessfulTest(
"104", "Yes Virginia <script>", "inactive", null, false, "rdap_registrar.json");
"104", "Yes Virginia <script>", "inactive", null, "rdap_registrar.json");
}
@Test
@ -424,7 +385,7 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
loginAsAdmin();
action.includeDeletedParam = Optional.of(true);
runSuccessfulTest(
"104", "Yes Virginia <script>", "inactive", null, false, "rdap_registrar.json");
"104", "Yes Virginia <script>", "inactive", null, "rdap_registrar.json");
}
@Test

View file

@ -14,7 +14,6 @@
package google.registry.rdap;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.request.Action.Method.GET;
import static google.registry.testing.DatastoreHelper.createTld;
@ -27,7 +26,6 @@ import static google.registry.testing.FullFieldsTestEntityHelper.makeContactReso
import static google.registry.testing.FullFieldsTestEntityHelper.makeHistoryEntry;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts;
import static google.registry.testing.TestDataHelper.loadFile;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
@ -70,11 +68,11 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
private Registrar registrarInactive;
private Registrar registrarTest;
private Object generateActualJsonWithFullName(String fn) {
private JSONObject generateActualJsonWithFullName(String fn) {
return generateActualJsonWithFullName(fn, null);
}
private Object generateActualJsonWithFullName(String fn, String cursor) {
private JSONObject generateActualJsonWithFullName(String fn, String cursor) {
metricSearchType = SearchType.BY_FULL_NAME;
action.fnParam = Optional.of(fn);
if (cursor == null) {
@ -85,14 +83,14 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
action.cursorTokenParam = Optional.of(cursor);
}
action.run();
return JSONValue.parse(response.getPayload());
return (JSONObject) JSONValue.parse(response.getPayload());
}
private Object generateActualJsonWithHandle(String handle) {
private JSONObject generateActualJsonWithHandle(String handle) {
return generateActualJsonWithHandle(handle, null);
}
private Object generateActualJsonWithHandle(String handle, String cursor) {
private JSONObject generateActualJsonWithHandle(String handle, String cursor) {
metricSearchType = SearchType.BY_HANDLE;
action.handleParam = Optional.of(handle);
if (cursor == null) {
@ -103,7 +101,7 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
action.cursorTokenParam = Optional.of(cursor);
}
action.run();
return JSONValue.parse(response.getPayload());
return (JSONObject) JSONValue.parse(response.getPayload());
}
@Before
@ -158,18 +156,17 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
action.subtypeParam = Optional.empty();
}
private Object generateExpectedJson(String expectedOutputFile) {
return JSONValue.parse(
loadFile(this.getClass(), expectedOutputFile, ImmutableMap.of("TYPE", "entity")));
private JSONObject generateExpectedJson(String expectedOutputFile) {
return loadJsonFile(expectedOutputFile, "TYPE", "entity");
}
private Object generateExpectedJson(
private JSONObject generateExpectedJson(
String handle,
String expectedOutputFile) {
return generateExpectedJson(handle, null, "active", null, null, expectedOutputFile);
}
private Object generateExpectedJson(
private JSONObject generateExpectedJson(
String handle,
@Nullable String fullName,
String status,
@ -189,20 +186,19 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
}
builder.put("TYPE", "entity");
builder.put("STATUS", status);
String substitutedFile = loadFile(this.getClass(), expectedOutputFile, builder.build());
Object jsonObject = JSONValue.parse(substitutedFile);
checkNotNull(jsonObject, "substituted file is not valid JSON: %s", substitutedFile);
return jsonObject;
return loadJsonFile(expectedOutputFile, builder.build());
}
private Object generateExpectedJsonForEntity(
private JSONObject generateExpectedJsonForEntity(
String handle,
String fullName,
String status,
@Nullable String email,
@Nullable String address,
String expectedOutputFile) {
Object obj = generateExpectedJson(handle, fullName, status, email, address, expectedOutputFile);
JSONObject obj =
generateExpectedJson(handle, fullName, status, email, address, expectedOutputFile);
obj.remove("rdapConformance");
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
builder.put("entitySearchResults", ImmutableList.of(obj));
builder.put("rdapConformance", ImmutableList.of("icann_rdap_response_profile_0"));
@ -244,10 +240,20 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
}
private void verifyMetrics(long numContactsRetrieved) {
verifyMetrics(Optional.of(numContactsRetrieved));
verifyMetrics(numContactsRetrieved, IncompletenessWarningType.COMPLETE);
}
private void verifyMetrics(
long numContactsRetrieved, IncompletenessWarningType incompletenessWarningType) {
verifyMetrics(Optional.of(numContactsRetrieved), incompletenessWarningType);
}
private void verifyMetrics(Optional<Long> numContactsRetrieved) {
verifyMetrics(numContactsRetrieved, IncompletenessWarningType.COMPLETE);
}
private void verifyMetrics(
Optional<Long> numContactsRetrieved, IncompletenessWarningType incompletenessWarningType) {
verifyMetrics(
EndpointType.ENTITIES,
GET,
@ -256,7 +262,7 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
Optional.empty(),
Optional.empty(),
numContactsRetrieved,
IncompletenessWarningType.COMPLETE);
incompletenessWarningType);
}
private void verifyErrorMetrics(long numContactsRetrieved) {
@ -269,14 +275,11 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
verifyMetrics(numContactsRetrieved);
}
private void checkNumberOfEntitiesInResult(Object obj, int expected) {
private void checkNumberOfEntitiesInResult(JSONObject obj, int expected) {
assertThat(obj).isInstanceOf(Map.class);
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) obj;
@SuppressWarnings("unchecked")
List<Object> entities = (List<Object>) map.get("entitySearchResults");
List<Object> entities = (List<Object>) obj.get("entitySearchResults");
assertThat(entities).hasSize(expected);
}
@ -318,7 +321,7 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
private void runNotFoundNameTest(String queryString) {
rememberWildcardType(queryString);
assertThat(generateActualJsonWithFullName(queryString))
.isEqualTo(generateExpectedJson("No entities found", "rdap_error_404.json"));
.isEqualTo(generateExpectedJsonError("No entities found", 404));
assertThat(response.getStatus()).isEqualTo(404);
}
@ -359,7 +362,7 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
private void runNotFoundHandleTest(String queryString) {
rememberWildcardType(queryString);
assertThat(generateActualJsonWithHandle(queryString))
.isEqualTo(generateExpectedJson("No entities found", "rdap_error_404.json"));
.isEqualTo(generateExpectedJsonError("No entities found", 404));
assertThat(response.getStatus()).isEqualTo(404);
}
@ -381,7 +384,7 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
int expectedPageCount =
(expectedNames.size() + action.rdapResultSetMaxSize - 1) / action.rdapResultSetMaxSize;
for (int pageNum = 0; pageNum < expectedPageCount; pageNum++) {
Object results =
JSONObject results =
(queryType == QueryType.FULL_NAME)
? generateActualJsonWithFullName(paramValue, cursor)
: generateActualJsonWithHandle(paramValue, cursor);
@ -394,7 +397,7 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
int pos = linkToNext.indexOf("cursor=");
assertThat(pos).isAtLeast(0);
cursor = URLDecoder.decode(linkToNext.substring(pos + 7), "UTF-8");
Object searchResults = ((JSONObject) results).get("entitySearchResults");
Object searchResults = results.get("entitySearchResults");
assertThat(searchResults).isInstanceOf(JSONArray.class);
assertThat(((JSONArray) searchResults)).hasSize(action.rdapResultSetMaxSize);
for (Object item : ((JSONArray) searchResults)) {
@ -429,8 +432,8 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
action.run();
assertThat(JSONValue.parse(response.getPayload()))
.isEqualTo(
generateExpectedJson(
"You must specify either fn=XXXX or handle=YYYY", "rdap_error_400.json"));
generateExpectedJsonError(
"You must specify either fn=XXXX or handle=YYYY", 400));
assertThat(response.getStatus()).isEqualTo(400);
verifyErrorMetrics(Optional.empty(), 400);
}
@ -439,7 +442,7 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
public void testNameMatch_suffixRejected() {
assertThat(generateActualJsonWithFullName("exam*ple"))
.isEqualTo(
generateExpectedJson("Suffix not allowed after wildcard", "rdap_error_422.json"));
generateExpectedJsonError("Suffix not allowed after wildcard", 422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(Optional.empty(), 422);
}
@ -448,7 +451,7 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
public void testHandleMatch_suffixRejected() {
assertThat(generateActualJsonWithHandle("exam*ple"))
.isEqualTo(
generateExpectedJson("Suffix not allowed after wildcard", "rdap_error_422.json"));
generateExpectedJsonError("Suffix not allowed after wildcard", 422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(Optional.empty(), 422);
}
@ -456,7 +459,7 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
@Test
public void testMultipleWildcards_rejected() {
assertThat(generateActualJsonWithHandle("*.*"))
.isEqualTo(generateExpectedJson("Only one wildcard allowed", "rdap_error_422.json"));
.isEqualTo(generateExpectedJsonError("Only one wildcard allowed", 422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(Optional.empty(), 422);
}
@ -466,9 +469,9 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
rememberWildcardType("*");
assertThat(generateActualJsonWithHandle("*"))
.isEqualTo(
generateExpectedJson(
generateExpectedJsonError(
"Initial search string must be at least 2 characters",
"rdap_error_422.json"));
422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(Optional.empty(), 422);
}
@ -478,9 +481,9 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
rememberWildcardType("a*");
assertThat(generateActualJsonWithHandle("a*"))
.isEqualTo(
generateExpectedJson(
generateExpectedJsonError(
"Initial search string must be at least 2 characters",
"rdap_error_422.json"));
422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(Optional.empty(), 422);
}
@ -490,9 +493,9 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
action.subtypeParam = Optional.of("Space Aliens");
assertThat(generateActualJsonWithFullName("Blinky (赤ベイ)"))
.isEqualTo(
generateExpectedJson(
generateExpectedJsonError(
"Subtype parameter must specify contacts, registrars or all",
"rdap_error_400.json"));
400));
assertThat(response.getStatus()).isEqualTo(400);
metricSearchType = SearchType.NONE; // Error occurs before search type is set.
verifyErrorMetrics(Optional.empty(), 400);
@ -700,7 +703,7 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
generateExpectedJson(
"fn=Entity+*&cursor=YzpFbnRpdHkgNA%3D%3D", "rdap_truncated_contacts.json"));
assertThat(response.getStatus()).isEqualTo(200);
verifyMetrics(5);
verifyMetrics(5, IncompletenessWarningType.TRUNCATED);
}
@Test
@ -714,7 +717,7 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
"fn=Entity+*&cursor=YzpFbnRpdHkgNA%3D%3D", "rdap_truncated_contacts.json"));
assertThat(response.getStatus()).isEqualTo(200);
// For contacts, we only need to fetch one result set's worth (plus one).
verifyMetrics(5);
verifyMetrics(5, IncompletenessWarningType.TRUNCATED);
}
@Test
@ -755,7 +758,7 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
generateExpectedJson(
"fn=Entity+*&cursor=cjpFbnRpdHkgNA%3D%3D", "rdap_truncated_registrars.json"));
assertThat(response.getStatus()).isEqualTo(200);
verifyMetrics(0);
verifyMetrics(0, IncompletenessWarningType.TRUNCATED);
}
@Test
@ -767,7 +770,7 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
generateExpectedJson(
"fn=Entity+*&cursor=cjpFbnRpdHkgNA%3D%3D", "rdap_truncated_registrars.json"));
assertThat(response.getStatus()).isEqualTo(200);
verifyMetrics(0);
verifyMetrics(0, IncompletenessWarningType.TRUNCATED);
}
@Test
@ -828,7 +831,7 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
generateExpectedJson(
"fn=Entity+*&cursor=cjpFbnRpdHkgNA%3D%3D", "rdap_truncated_mixed_entities.json"));
assertThat(response.getStatus()).isEqualTo(200);
verifyMetrics(3);
verifyMetrics(3, IncompletenessWarningType.TRUNCATED);
}
@Test
@ -1234,10 +1237,10 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
public void testHandleMatchMix_found_truncated() {
createManyContactsAndRegistrars(30, 0, registrarTest);
rememberWildcardType("00*");
Object obj = generateActualJsonWithHandle("00*");
JSONObject obj = generateActualJsonWithHandle("00*");
assertThat(response.getStatus()).isEqualTo(200);
checkNumberOfEntitiesInResult(obj, 4);
verifyMetrics(5);
verifyMetrics(5, IncompletenessWarningType.TRUNCATED);
}
@Test

View file

@ -15,16 +15,13 @@
package google.registry.rdap;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.TestDataHelper.loadFile;
import static org.mockito.Mockito.verify;
import com.google.common.collect.ImmutableMap;
import google.registry.rdap.RdapMetrics.EndpointType;
import google.registry.rdap.RdapMetrics.SearchType;
import google.registry.rdap.RdapMetrics.WildcardType;
import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
import google.registry.request.Action;
import org.json.simple.JSONValue;
import org.junit.Test;
/** Unit tests for {@link RdapHelpAction}. */
@ -34,44 +31,38 @@ public class RdapHelpActionTest extends RdapActionBaseTestCase<RdapHelpAction> {
super(RdapHelpAction.class);
}
private Object generateExpectedJson(String name, String expectedOutputFile) {
return JSONValue.parse(
loadFile(this.getClass(), expectedOutputFile, ImmutableMap.of("NAME", name)));
}
@Test
public void testHelpActionMaliciousPath_notFound() {
assertThat(generateActualJson("../passwd")).isEqualTo(
generateExpectedJson(
"no help found for ../passwd", "rdap_error_404.json"));
assertThat(generateActualJson("../passwd"))
.isEqualTo(generateExpectedJsonError("no help found for ../passwd", 404));
assertThat(response.getStatus()).isEqualTo(404);
}
@Test
public void testHelpActionUnknownPath_notFound() {
assertThat(generateActualJson("hlarg")).isEqualTo(
generateExpectedJson("no help found for hlarg", "rdap_error_404.json"));
generateExpectedJsonError("no help found for hlarg", 404));
assertThat(response.getStatus()).isEqualTo(404);
}
@Test
public void testHelpActionDefault_getsIndex() {
assertThat(generateActualJson(""))
.isEqualTo(generateExpectedJson("", "rdap_help_index.json"));
.isEqualTo(loadJsonFile("rdap_help_index.json"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testHelpActionSlash_getsIndex() {
assertThat(generateActualJson("/"))
.isEqualTo(generateExpectedJson("", "rdap_help_index.json"));
.isEqualTo(loadJsonFile("rdap_help_index.json"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testHelpActionTos_works() {
assertThat(generateActualJson("/tos"))
.isEqualTo(generateExpectedJson("", "rdap_help_tos.json"));
.isEqualTo(loadJsonFile("rdap_help_tos.json"));
assertThat(response.getStatus()).isEqualTo(200);
}

View file

@ -27,10 +27,10 @@ import static google.registry.testing.TestDataHelper.loadFile;
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.googlecode.objectify.Key;
import google.registry.config.RdapNoticeDescriptor;
import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DesignatedContact;
import google.registry.model.domain.DomainBase;
@ -44,12 +44,14 @@ import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.rdap.RdapJsonFormatter.OutputDataType;
import google.registry.rdap.RdapObjectClasses.BoilerplateType;
import google.registry.rdap.RdapObjectClasses.ReplyPayloadBase;
import google.registry.rdap.RdapObjectClasses.TopLevelReplyObject;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import google.registry.testing.InjectRule;
import java.util.Optional;
import org.joda.time.DateTime;
import org.json.simple.JSONValue;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@ -84,8 +86,6 @@ public class RdapJsonFormatterTest {
private ContactResource contactResourceTech;
private ContactResource contactResourceNotLinked;
private static final String LINK_BASE = "http://myserver.example.com/";
private static final String LINK_BASE_NO_TRAILING_SLASH = "http://myserver.example.com";
// Do not set a port43 whois server, as per Gustavo Lozano.
private static final String WHOIS_SERVER = null;
@ -307,415 +307,316 @@ public class RdapJsonFormatterTest {
.build());
}
private Object loadJson(String expectedFileName) {
return JSONValue.parse(loadFile(this.getClass(), expectedFileName));
private JsonElement loadJson(String expectedFileName) {
return new Gson().fromJson(loadFile(this.getClass(), expectedFileName), JsonElement.class);
}
@Test
public void testRegistrar() {
assertThat(rdapJsonFormatter.makeRdapJsonForRegistrar(
registrar, false, LINK_BASE, WHOIS_SERVER, clock.nowUtc(), OutputDataType.FULL))
assertThat(
rdapJsonFormatter
.makeRdapJsonForRegistrar(
registrar, WHOIS_SERVER, clock.nowUtc(), OutputDataType.FULL)
.toJson())
.isEqualTo(loadJson("rdapjson_registrar.json"));
}
@Test
public void testRegistrar_summary() {
assertThat(rdapJsonFormatter.makeRdapJsonForRegistrar(
registrar, false, LINK_BASE, WHOIS_SERVER, clock.nowUtc(), OutputDataType.SUMMARY))
assertThat(
rdapJsonFormatter
.makeRdapJsonForRegistrar(
registrar, WHOIS_SERVER, clock.nowUtc(), OutputDataType.SUMMARY)
.toJson())
.isEqualTo(loadJson("rdapjson_registrar_summary.json"));
}
@Test
public void testHost_ipv4() {
assertThat(rdapJsonFormatter.makeRdapJsonForHost(
hostResourceIpv4,
false,
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL))
assertThat(
rdapJsonFormatter
.makeRdapJsonForHost(
hostResourceIpv4, WHOIS_SERVER, clock.nowUtc(), OutputDataType.FULL)
.toJson())
.isEqualTo(loadJson("rdapjson_host_ipv4.json"));
}
@Test
public void testHost_ipv6() {
assertThat(rdapJsonFormatter.makeRdapJsonForHost(
hostResourceIpv6,
false,
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL))
assertThat(
rdapJsonFormatter
.makeRdapJsonForHost(
hostResourceIpv6, WHOIS_SERVER, clock.nowUtc(), OutputDataType.FULL)
.toJson())
.isEqualTo(loadJson("rdapjson_host_ipv6.json"));
}
@Test
public void testHost_both() {
assertThat(rdapJsonFormatter.makeRdapJsonForHost(
hostResourceBoth,
false,
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL))
assertThat(
rdapJsonFormatter
.makeRdapJsonForHost(
hostResourceBoth, WHOIS_SERVER, clock.nowUtc(), OutputDataType.FULL)
.toJson())
.isEqualTo(loadJson("rdapjson_host_both.json"));
}
@Test
public void testHost_both_summary() {
assertThat(rdapJsonFormatter.makeRdapJsonForHost(
hostResourceBoth,
false,
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.SUMMARY))
assertThat(
rdapJsonFormatter
.makeRdapJsonForHost(
hostResourceBoth, WHOIS_SERVER, clock.nowUtc(), OutputDataType.SUMMARY)
.toJson())
.isEqualTo(loadJson("rdapjson_host_both_summary.json"));
}
@Test
public void testHost_noAddresses() {
assertThat(rdapJsonFormatter.makeRdapJsonForHost(
hostResourceNoAddresses,
false,
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL))
assertThat(
rdapJsonFormatter
.makeRdapJsonForHost(
hostResourceNoAddresses, WHOIS_SERVER, clock.nowUtc(), OutputDataType.FULL)
.toJson())
.isEqualTo(loadJson("rdapjson_host_no_addresses.json"));
}
@Test
public void testHost_notLinked() {
assertThat(rdapJsonFormatter.makeRdapJsonForHost(
hostResourceNotLinked,
false,
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL))
assertThat(
rdapJsonFormatter
.makeRdapJsonForHost(
hostResourceNotLinked, WHOIS_SERVER, clock.nowUtc(), OutputDataType.FULL)
.toJson())
.isEqualTo(loadJson("rdapjson_host_not_linked.json"));
}
@Test
public void testHost_superordinateHasPendingTransfer() {
assertThat(rdapJsonFormatter.makeRdapJsonForHost(
hostResourceSuperordinatePendingTransfer,
false,
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL))
.isEqualTo(loadJson("rdapjson_host_pending_transfer.json"));
assertThat(
rdapJsonFormatter
.makeRdapJsonForHost(
hostResourceSuperordinatePendingTransfer,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL)
.toJson())
.isEqualTo(loadJson("rdapjson_host_pending_transfer.json"));
}
@Test
public void testRegistrant() {
assertThat(
rdapJsonFormatter.makeRdapJsonForContact(
contactResourceRegistrant,
false,
Optional.of(DesignatedContact.Type.REGISTRANT),
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar")))
rdapJsonFormatter
.makeRdapJsonForContact(
contactResourceRegistrant,
Optional.of(DesignatedContact.Type.REGISTRANT),
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar"))
.toJson())
.isEqualTo(loadJson("rdapjson_registrant.json"));
}
@Test
public void testRegistrant_summary() {
assertThat(
rdapJsonFormatter.makeRdapJsonForContact(
contactResourceRegistrant,
false,
Optional.of(DesignatedContact.Type.REGISTRANT),
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.SUMMARY,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar")))
rdapJsonFormatter
.makeRdapJsonForContact(
contactResourceRegistrant,
Optional.of(DesignatedContact.Type.REGISTRANT),
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.SUMMARY,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar"))
.toJson())
.isEqualTo(loadJson("rdapjson_registrant_summary.json"));
}
@Test
public void testRegistrant_loggedOut() {
assertThat(
rdapJsonFormatter.makeRdapJsonForContact(
contactResourceRegistrant,
false,
Optional.of(DesignatedContact.Type.REGISTRANT),
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.PUBLIC_AUTHORIZATION))
rdapJsonFormatter
.makeRdapJsonForContact(
contactResourceRegistrant,
Optional.of(DesignatedContact.Type.REGISTRANT),
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.PUBLIC_AUTHORIZATION)
.toJson())
.isEqualTo(loadJson("rdapjson_registrant_logged_out.json"));
}
@Test
public void testRegistrant_baseHasNoTrailingSlash() {
// First, make sure we have a trailing slash at the end by default!
// This test tries to change the default state, if the default doesn't have a /, then this test
// doesn't help.
assertThat(rdapJsonFormatter.fullServletPath).endsWith("/");
rdapJsonFormatter.fullServletPath =
rdapJsonFormatter.fullServletPath.substring(
0, rdapJsonFormatter.fullServletPath.length() - 1);
assertThat(
rdapJsonFormatter.makeRdapJsonForContact(
contactResourceRegistrant,
false,
Optional.of(DesignatedContact.Type.REGISTRANT),
LINK_BASE_NO_TRAILING_SLASH,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar")))
rdapJsonFormatter
.makeRdapJsonForContact(
contactResourceRegistrant,
Optional.of(DesignatedContact.Type.REGISTRANT),
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar"))
.toJson())
.isEqualTo(loadJson("rdapjson_registrant.json"));
}
@Test
public void testRegistrant_noBase() {
assertThat(
rdapJsonFormatter.makeRdapJsonForContact(
contactResourceRegistrant,
false,
Optional.of(DesignatedContact.Type.REGISTRANT),
null,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar")))
.isEqualTo(loadJson("rdapjson_registrant_nobase.json"));
}
@Test
public void testAdmin() {
assertThat(
rdapJsonFormatter.makeRdapJsonForContact(
contactResourceAdmin,
false,
Optional.of(DesignatedContact.Type.ADMIN),
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar")))
rdapJsonFormatter
.makeRdapJsonForContact(
contactResourceAdmin,
Optional.of(DesignatedContact.Type.ADMIN),
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar"))
.toJson())
.isEqualTo(loadJson("rdapjson_admincontact.json"));
}
@Test
public void testTech() {
assertThat(
rdapJsonFormatter.makeRdapJsonForContact(
contactResourceTech,
false,
Optional.of(DesignatedContact.Type.TECH),
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar")))
rdapJsonFormatter
.makeRdapJsonForContact(
contactResourceTech,
Optional.of(DesignatedContact.Type.TECH),
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar"))
.toJson())
.isEqualTo(loadJson("rdapjson_techcontact.json"));
}
@Test
public void testRolelessContact() {
assertThat(
rdapJsonFormatter.makeRdapJsonForContact(
contactResourceTech,
false,
Optional.empty(),
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar")))
rdapJsonFormatter
.makeRdapJsonForContact(
contactResourceTech,
Optional.empty(),
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar"))
.toJson())
.isEqualTo(loadJson("rdapjson_rolelesscontact.json"));
}
@Test
public void testUnlinkedContact() {
assertThat(
rdapJsonFormatter.makeRdapJsonForContact(
contactResourceNotLinked,
false,
Optional.empty(),
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar")))
rdapJsonFormatter
.makeRdapJsonForContact(
contactResourceNotLinked,
Optional.empty(),
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar"))
.toJson())
.isEqualTo(loadJson("rdapjson_unlinkedcontact.json"));
}
@Test
public void testDomain_full() {
assertThat(rdapJsonFormatter.makeRdapJsonForDomain(
domainBaseFull,
false,
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar")))
assertThat(
rdapJsonFormatter
.makeRdapJsonForDomain(
domainBaseFull,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar"))
.toJson())
.isEqualTo(loadJson("rdapjson_domain_full.json"));
}
@Test
public void testDomain_summary() {
assertThat(rdapJsonFormatter.makeRdapJsonForDomain(
domainBaseFull,
false,
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.SUMMARY,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar")))
assertThat(
rdapJsonFormatter
.makeRdapJsonForDomain(
domainBaseFull,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.SUMMARY,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar"))
.toJson())
.isEqualTo(loadJson("rdapjson_domain_summary.json"));
}
@Test
public void testDomain_logged_out() {
assertThat(rdapJsonFormatter.makeRdapJsonForDomain(
domainBaseFull,
false,
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.PUBLIC_AUTHORIZATION))
assertThat(
rdapJsonFormatter
.makeRdapJsonForDomain(
domainBaseFull,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.PUBLIC_AUTHORIZATION)
.toJson())
.isEqualTo(loadJson("rdapjson_domain_logged_out.json"));
}
@Test
public void testDomain_noNameserversNoTransfers() {
assertThat(rdapJsonFormatter.makeRdapJsonForDomain(
domainBaseNoNameserversNoTransfers,
false,
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar")))
assertThat(
rdapJsonFormatter
.makeRdapJsonForDomain(
domainBaseNoNameserversNoTransfers,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
RdapAuthorization.create(RdapAuthorization.Role.REGISTRAR, "unicoderegistrar"))
.toJson())
.isEqualTo(loadJson("rdapjson_domain_no_nameservers.json"));
}
@Test
public void testError() {
assertThat(
rdapJsonFormatter
.makeError(SC_BAD_REQUEST, "Invalid Domain Name", "Not a valid domain name"))
RdapObjectClasses.ErrorResponse.create(
SC_BAD_REQUEST, "Invalid Domain Name", "Not a valid domain name")
.toJson())
.isEqualTo(loadJson("rdapjson_error.json"));
}
@Test
public void testHelp_absoluteHtmlUrl() {
assertThat(RdapJsonFormatter.makeRdapJsonNotice(
RdapNoticeDescriptor.builder()
.setTitle("RDAP Help")
.setDescription(ImmutableList.of(
"RDAP Help Topics (use /help/topic for information)",
"syntax",
"tos (Terms of Service)"))
.setLinkValueSuffix("help/index")
.setLinkHrefUrlString(LINK_BASE + "about/rdap/index.html")
.build(),
LINK_BASE))
.isEqualTo(loadJson("rdapjson_notice_alternate_link.json"));
}
@Test
public void testHelp_relativeHtmlUrlWithStartingSlash() {
assertThat(RdapJsonFormatter.makeRdapJsonNotice(
RdapNoticeDescriptor.builder()
.setTitle("RDAP Help")
.setDescription(ImmutableList.of(
"RDAP Help Topics (use /help/topic for information)",
"syntax",
"tos (Terms of Service)"))
.setLinkValueSuffix("help/index")
.setLinkHrefUrlString("/about/rdap/index.html")
.build(),
LINK_BASE))
.isEqualTo(loadJson("rdapjson_notice_alternate_link.json"));
}
@Test
public void testHelp_relativeHtmlUrlWithoutStartingSlash() {
assertThat(RdapJsonFormatter.makeRdapJsonNotice(
RdapNoticeDescriptor.builder()
.setTitle("RDAP Help")
.setDescription(ImmutableList.of(
"RDAP Help Topics (use /help/topic for information)",
"syntax",
"tos (Terms of Service)"))
.setLinkValueSuffix("help/index")
.setLinkHrefUrlString("about/rdap/index.html")
.build(),
LINK_BASE))
.isEqualTo(loadJson("rdapjson_notice_alternate_link.json"));
}
@Test
public void testHelp_noHtmlUrl() {
assertThat(RdapJsonFormatter.makeRdapJsonNotice(
RdapNoticeDescriptor.builder()
.setTitle("RDAP Help")
.setDescription(ImmutableList.of(
"RDAP Help Topics (use /help/topic for information)",
"syntax",
"tos (Terms of Service)"))
.setLinkValueSuffix("help/index")
.build(),
LINK_BASE))
.isEqualTo(loadJson("rdapjson_notice_self_link.json"));
}
@Test
public void testTopLevel() {
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
builder.put("key", "value");
rdapJsonFormatter.addTopLevelEntries(
builder,
RdapJsonFormatter.BoilerplateType.OTHER,
ImmutableList.of(),
ImmutableList.of(),
LINK_BASE);
assertThat(builder.build()).isEqualTo(loadJson("rdapjson_toplevel.json"));
}
@Test
public void testTopLevel_withTermsOfService() {
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
builder.put("key", "value");
rdapJsonFormatter.addTopLevelEntries(
builder,
RdapJsonFormatter.BoilerplateType.OTHER,
ImmutableList.of(rdapJsonFormatter.getJsonHelpNotice("/tos", LINK_BASE)),
ImmutableList.of(),
LINK_BASE);
assertThat(builder.build()).isEqualTo(loadJson("rdapjson_toplevel.json"));
assertThat(
TopLevelReplyObject.create(
new ReplyPayloadBase(BoilerplateType.OTHER) {
@JsonableElement public String key = "value";
},
rdapJsonFormatter.createTosNotice())
.toJson())
.isEqualTo(loadJson("rdapjson_toplevel.json"));
}
@Test
public void testTopLevel_domain() {
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
builder.put("key", "value");
rdapJsonFormatter.addTopLevelEntries(
builder,
RdapJsonFormatter.BoilerplateType.DOMAIN,
ImmutableList.of(),
ImmutableList.of(),
LINK_BASE);
assertThat(builder.build()).isEqualTo(loadJson("rdapjson_toplevel_domain.json"));
}
@Test
public void testTopLevel_domainWithTermsOfService() {
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
builder.put("key", "value");
rdapJsonFormatter.addTopLevelEntries(
builder,
RdapJsonFormatter.BoilerplateType.DOMAIN,
ImmutableList.of(rdapJsonFormatter.getJsonHelpNotice("/tos", LINK_BASE)),
ImmutableList.of(),
LINK_BASE);
assertThat(builder.build()).isEqualTo(loadJson("rdapjson_toplevel_domain.json"));
assertThat(
TopLevelReplyObject.create(
new ReplyPayloadBase(BoilerplateType.DOMAIN) {
@JsonableElement public String key = "value";
},
rdapJsonFormatter.createTosNotice())
.toJson())
.isEqualTo(loadJson("rdapjson_toplevel_domain.json"));
}
}

View file

@ -19,7 +19,6 @@ import static google.registry.testing.DatastoreHelper.createTld;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.FullFieldsTestEntityHelper.makeAndPersistHostResource;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
import static google.registry.testing.TestDataHelper.loadFile;
import static org.mockito.Mockito.verify;
import com.google.common.collect.ImmutableList;
@ -34,7 +33,7 @@ import google.registry.request.Action;
import java.util.Map;
import java.util.Optional;
import javax.annotation.Nullable;
import org.json.simple.JSONValue;
import org.json.simple.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -92,10 +91,9 @@ public class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameser
if (!punycodeSet) {
builder.put("PUNYCODENAME", name);
}
return JSONValue.parse(loadFile(
this.getClass(),
return loadJsonFile(
expectedOutputFile,
builder.build()));
builder.build());
}
private Object generateExpectedJsonWithTopLevelEntries(
@ -114,9 +112,8 @@ public class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameser
builder,
RdapTestHelper.createNotices(
"https://example.tld/rdap/",
RdapTestHelper.ContactNoticeType.NONE,
map.get("notices")));
obj = builder.build();
obj = new JSONObject(builder.build());
}
return obj;
}
@ -125,17 +122,16 @@ public class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameser
public void testInvalidNameserver_returns400() {
assertThat(generateActualJson("invalid/host/name"))
.isEqualTo(
generateExpectedJson(
generateExpectedJsonError(
"invalid/host/name is not a valid nameserver: Invalid host name",
null,
"rdap_error_400.json"));
400));
assertThat(response.getStatus()).isEqualTo(400);
}
@Test
public void testUnknownNameserver_returns404() {
assertThat(generateActualJson("ns1.missing.com")).isEqualTo(
generateExpectedJson("ns1.missing.com not found", null, "rdap_error_404.json"));
generateExpectedJsonError("ns1.missing.com not found", 404));
assertThat(response.getStatus()).isEqualTo(404);
}

View file

@ -26,7 +26,6 @@ import static google.registry.testing.FullFieldsTestEntityHelper.makeDomainBase;
import static google.registry.testing.FullFieldsTestEntityHelper.makeHostResource;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts;
import static google.registry.testing.TestDataHelper.loadFile;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
@ -43,7 +42,6 @@ import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
import google.registry.testing.FakeResponse;
import java.net.URLDecoder;
import java.util.Optional;
import javax.annotation.Nullable;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
@ -65,11 +63,11 @@ public class RdapNameserverSearchActionTest
private HostResource hostNs1CatLol;
private HostResource hostNs2CatLol;
private Object generateActualJsonWithName(String name) {
private JSONObject generateActualJsonWithName(String name) {
return generateActualJsonWithName(name, null);
}
private Object generateActualJsonWithName(String name, String cursor) {
private JSONObject generateActualJsonWithName(String name, String cursor) {
metricSearchType = SearchType.BY_NAMESERVER_NAME;
rememberWildcardType(name);
action.nameParam = Optional.of(name);
@ -81,14 +79,14 @@ public class RdapNameserverSearchActionTest
action.cursorTokenParam = Optional.of(cursor);
}
action.run();
return JSONValue.parse(response.getPayload());
return (JSONObject) JSONValue.parse(response.getPayload());
}
private Object generateActualJsonWithIp(String ipString) {
private JSONObject generateActualJsonWithIp(String ipString) {
return generateActualJsonWithIp(ipString, null);
}
private Object generateActualJsonWithIp(String ipString, String cursor) {
private JSONObject generateActualJsonWithIp(String ipString, String cursor) {
metricSearchType = SearchType.BY_NAMESERVER_ADDRESS;
action.parameterMap = ImmutableListMultimap.of("ip", ipString);
action.ipParam = Optional.of(ipString);
@ -100,7 +98,7 @@ public class RdapNameserverSearchActionTest
action.cursorTokenParam = Optional.of(cursor);
}
action.run();
return JSONValue.parse(response.getPayload());
return (JSONObject) JSONValue.parse(response.getPayload());
}
@Before
@ -156,59 +154,30 @@ public class RdapNameserverSearchActionTest
action.nameParam = Optional.empty();
}
private Object generateExpectedJson(String expectedOutputFile) {
return generateExpectedJson(null, null, null, null, null, expectedOutputFile);
}
private Object generateExpectedJson(String name, String expectedOutputFile) {
return generateExpectedJson(name, null, null, null, null, expectedOutputFile);
}
private Object generateExpectedJson(
@Nullable String name,
@Nullable String punycodeName,
@Nullable String handle,
@Nullable String ipAddressType,
@Nullable String ipAddress,
String expectedOutputFile) {
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<>();
if (name != null) {
builder.put("NAME", name);
}
if ((name != null) || (punycodeName != null)) {
builder.put("PUNYCODENAME", (punycodeName == null) ? name : punycodeName);
}
if (handle != null) {
builder.put("HANDLE", handle);
}
if (ipAddressType != null) {
builder.put("ADDRESSTYPE", ipAddressType);
}
if (ipAddress != null) {
builder.put("ADDRESS", ipAddress);
}
builder.put("STATUS", "active");
builder.put("TYPE", "nameserver");
return JSONValue.parse(
loadFile(this.getClass(), expectedOutputFile, builder.build()));
}
private Object generateExpectedJsonForNameserver(
private JSONObject generateExpectedJsonForNameserver(
String name,
String punycodeName,
String handle,
String ipAddressType,
String ipAddress,
String expectedOutputFile) {
Object obj =
generateExpectedJson(
name, punycodeName, handle, ipAddressType, ipAddress, expectedOutputFile);
JSONObject obj =
loadJsonFile(
expectedOutputFile,
"NAME", name,
"PUNYCODENAME", punycodeName,
"HANDLE", handle,
"ADDRESSTYPE", ipAddressType,
"ADDRESS", ipAddress,
"STATUS", "active",
"TYPE", "nameserver");
obj.remove("rdapConformance");
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
builder.put("nameserverSearchResults", ImmutableList.of(obj));
builder.put("rdapConformance", ImmutableList.of("icann_rdap_response_profile_0"));
RdapTestHelper.addNonDomainBoilerplateNotices(
builder, RdapTestHelper.createNotices("https://example.tld/rdap/"));
return builder.build();
return new JSONObject(builder.build());
}
private void createManyHosts(int numHosts) {
@ -234,6 +203,11 @@ public class RdapNameserverSearchActionTest
.build());
}
private void verifyMetrics(
long numHostsRetrieved, IncompletenessWarningType incompletenessWarningType) {
verifyMetrics(Optional.of(numHostsRetrieved), incompletenessWarningType);
}
private void verifyMetrics(long numHostsRetrieved) {
verifyMetrics(Optional.of(numHostsRetrieved), IncompletenessWarningType.COMPLETE);
}
@ -274,8 +248,9 @@ public class RdapNameserverSearchActionTest
action.run();
assertThat(JSONValue.parse(response.getPayload()))
.isEqualTo(
generateExpectedJson(
"You must specify either name=XXXX or ip=YYYY", "rdap_error_400.json"));
generateExpectedJsonError(
"You must specify either name=XXXX or ip=YYYY",
400));
assertThat(response.getStatus()).isEqualTo(400);
verifyErrorMetrics(Optional.empty(), 400);
}
@ -284,10 +259,10 @@ public class RdapNameserverSearchActionTest
public void testInvalidSuffix_rejected() {
assertThat(generateActualJsonWithName("exam*ple"))
.isEqualTo(
generateExpectedJson(
generateExpectedJsonError(
"Suffix after wildcard must be one or more domain"
+ " name labels, e.g. exam*.tld, ns*.example.tld",
"rdap_error_422.json"));
422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(Optional.empty(), 422);
}
@ -296,9 +271,9 @@ public class RdapNameserverSearchActionTest
public void testNonexistentDomainSuffix_unprocessable() {
assertThat(generateActualJsonWithName("exam*.foo.bar"))
.isEqualTo(
generateExpectedJson(
generateExpectedJsonError(
"A suffix after a wildcard in a nameserver lookup must be an in-bailiwick domain",
"rdap_error_422.json"));
422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(Optional.empty(), 422);
}
@ -306,7 +281,7 @@ public class RdapNameserverSearchActionTest
@Test
public void testMultipleWildcards_rejected() {
assertThat(generateActualJsonWithName("*.*"))
.isEqualTo(generateExpectedJson("Only one wildcard allowed", "rdap_error_422.json"));
.isEqualTo(generateExpectedJsonError("Only one wildcard allowed", 422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(Optional.empty(), 422);
}
@ -315,8 +290,8 @@ public class RdapNameserverSearchActionTest
public void testNoCharactersToMatch_rejected() {
assertThat(generateActualJsonWithName("*"))
.isEqualTo(
generateExpectedJson(
"Initial search string must be at least 2 characters", "rdap_error_422.json"));
generateExpectedJsonError(
"Initial search string must be at least 2 characters", 422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(Optional.empty(), 422);
}
@ -325,8 +300,8 @@ public class RdapNameserverSearchActionTest
public void testFewerThanTwoCharactersToMatch_rejected() {
assertThat(generateActualJsonWithName("a*"))
.isEqualTo(
generateExpectedJson(
"Initial search string must be at least 2 characters", "rdap_error_422.json"));
generateExpectedJsonError(
"Initial search string must be at least 2 characters", 422));
assertThat(response.getStatus()).isEqualTo(422);
verifyErrorMetrics(Optional.empty(), 422);
}
@ -491,7 +466,7 @@ public class RdapNameserverSearchActionTest
public void testNameMatch_nsstar_found() {
generateActualJsonWithName("ns*");
assertThat(response.getStatus()).isEqualTo(200);
verifyMetrics(5);
verifyMetrics(5, IncompletenessWarningType.TRUNCATED);
}
@Test
@ -505,7 +480,7 @@ public class RdapNameserverSearchActionTest
public void testNameMatch_ns1_castar_found() {
generateActualJsonWithName("ns1.ca*");
assertThat(response.getStatus()).isEqualTo(200);
verifyMetrics(5);
verifyMetrics(5, IncompletenessWarningType.TRUNCATED);
}
@Test
@ -519,7 +494,7 @@ public class RdapNameserverSearchActionTest
public void testNameMatch_nontruncatedResultSet() {
createManyHosts(4);
assertThat(generateActualJsonWithName("nsx*.cat.lol"))
.isEqualTo(generateExpectedJson("rdap_nontruncated_hosts.json"));
.isEqualTo(loadJsonFile("rdap_nontruncated_hosts.json"));
assertThat(response.getStatus()).isEqualTo(200);
verifyMetrics(4);
}
@ -529,10 +504,10 @@ public class RdapNameserverSearchActionTest
createManyHosts(5);
assertThat(generateActualJsonWithName("nsx*.cat.lol"))
.isEqualTo(
generateExpectedJson(
"name=nsx*.cat.lol&cursor=bnN4NC5jYXQubG9s", "rdap_truncated_hosts.json"));
loadJsonFile(
"rdap_truncated_hosts.json", "QUERY", "name=nsx*.cat.lol&cursor=bnN4NC5jYXQubG9s"));
assertThat(response.getStatus()).isEqualTo(200);
verifyMetrics(5);
verifyMetrics(5, IncompletenessWarningType.TRUNCATED);
}
@Test
@ -540,11 +515,11 @@ public class RdapNameserverSearchActionTest
createManyHosts(9);
assertThat(generateActualJsonWithName("nsx*.cat.lol"))
.isEqualTo(
generateExpectedJson(
"name=nsx*.cat.lol&cursor=bnN4NC5jYXQubG9s", "rdap_truncated_hosts.json"));
loadJsonFile(
"rdap_truncated_hosts.json", "QUERY", "name=nsx*.cat.lol&cursor=bnN4NC5jYXQubG9s"));
assertThat(response.getStatus()).isEqualTo(200);
// When searching names, we look for additional matches, in case some are not visible.
verifyMetrics(9);
verifyMetrics(9, IncompletenessWarningType.TRUNCATED);
}
@Test
@ -568,7 +543,7 @@ public class RdapNameserverSearchActionTest
public void testNameMatchDeletedHost_notFound() {
persistResource(hostNs1CatLol.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
assertThat(generateActualJsonWithName("ns1.cat.lol"))
.isEqualTo(generateExpectedJson("No nameservers found", "rdap_error_404.json"));
.isEqualTo(generateExpectedJsonError("No nameservers found", 404));
assertThat(response.getStatus()).isEqualTo(404);
verifyErrorMetrics();
}
@ -577,7 +552,7 @@ public class RdapNameserverSearchActionTest
public void testNameMatchDeletedHostWithWildcard_notFound() {
persistResource(hostNs1CatLol.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
assertThat(generateActualJsonWithName("cat.lo*"))
.isEqualTo(generateExpectedJson("No nameservers found", "rdap_error_404.json"));
.isEqualTo(generateExpectedJsonError("No nameservers found", 404));
assertThat(response.getStatus()).isEqualTo(404);
verifyErrorMetrics();
}
@ -669,7 +644,7 @@ public class RdapNameserverSearchActionTest
int expectedPageCount =
(expectedNames.size() + action.rdapResultSetMaxSize - 1) / action.rdapResultSetMaxSize;
for (int pageNum = 0; pageNum < expectedPageCount; pageNum++) {
Object results =
JSONObject results =
byName
? generateActualJsonWithName(paramValue, cursor)
: generateActualJsonWithIp(paramValue, cursor);
@ -682,7 +657,7 @@ public class RdapNameserverSearchActionTest
int pos = linkToNext.indexOf("cursor=");
assertThat(pos).isAtLeast(0);
cursor = URLDecoder.decode(linkToNext.substring(pos + 7), "UTF-8");
Object searchResults = ((JSONObject) results).get("nameserverSearchResults");
Object searchResults = results.get("nameserverSearchResults");
assertThat(searchResults).isInstanceOf(JSONArray.class);
assertThat(((JSONArray) searchResults)).hasSize(action.rdapResultSetMaxSize);
for (Object item : ((JSONArray) searchResults)) {
@ -776,7 +751,7 @@ public class RdapNameserverSearchActionTest
@Test
public void testAddressMatchV6Address_foundMultiple() {
assertThat(generateActualJsonWithIp("bad:f00d:cafe::15:beef"))
.isEqualTo(generateExpectedJson("rdap_multiple_hosts.json"));
.isEqualTo(loadJsonFile("rdap_multiple_hosts.json"));
assertThat(response.getStatus()).isEqualTo(200);
verifyMetrics(2);
}
@ -792,7 +767,7 @@ public class RdapNameserverSearchActionTest
public void testAddressMatchDeletedHost_notFound() {
persistResource(hostNs1CatLol.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
assertThat(generateActualJsonWithIp("1.2.3.4"))
.isEqualTo(generateExpectedJson("No nameservers found", "rdap_error_404.json"));
.isEqualTo(generateExpectedJsonError("No nameservers found", 404));
assertThat(response.getStatus()).isEqualTo(404);
verifyErrorMetrics();
}
@ -801,7 +776,7 @@ public class RdapNameserverSearchActionTest
public void testAddressMatch_nontruncatedResultSet() {
createManyHosts(4);
assertThat(generateActualJsonWithIp("5.5.5.1"))
.isEqualTo(generateExpectedJson("rdap_nontruncated_hosts.json"));
.isEqualTo(loadJsonFile("rdap_nontruncated_hosts.json"));
assertThat(response.getStatus()).isEqualTo(200);
verifyMetrics(4);
}
@ -811,10 +786,10 @@ public class RdapNameserverSearchActionTest
createManyHosts(5);
assertThat(generateActualJsonWithIp("5.5.5.1"))
.isEqualTo(
generateExpectedJson(
"ip=5.5.5.1&cursor=MTctUk9JRA%3D%3D", "rdap_truncated_hosts.json"));
loadJsonFile(
"rdap_truncated_hosts.json", "QUERY", "ip=5.5.5.1&cursor=MTctUk9JRA%3D%3D"));
assertThat(response.getStatus()).isEqualTo(200);
verifyMetrics(5);
verifyMetrics(5, IncompletenessWarningType.TRUNCATED);
}
@Test
@ -822,12 +797,12 @@ public class RdapNameserverSearchActionTest
createManyHosts(9);
assertThat(generateActualJsonWithIp("5.5.5.1"))
.isEqualTo(
generateExpectedJson(
"ip=5.5.5.1&cursor=MTctUk9JRA%3D%3D", "rdap_truncated_hosts.json"));
loadJsonFile(
"rdap_truncated_hosts.json", "QUERY", "ip=5.5.5.1&cursor=MTctUk9JRA%3D%3D"));
assertThat(response.getStatus()).isEqualTo(200);
// When searching by address and not including deleted, we don't need to search for extra
// matches.
verifyMetrics(5);
verifyMetrics(5, IncompletenessWarningType.TRUNCATED);
}
@Test

View file

@ -16,9 +16,12 @@ package google.registry.rdap;
import static com.google.common.truth.Truth.assertThat;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import google.registry.config.RdapNoticeDescriptor;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@ -28,6 +31,12 @@ import org.json.simple.JSONObject;
public class RdapTestHelper {
private static final Gson GSON = new GsonBuilder().create();
static JsonElement createJson(String... lines) {
return GSON.fromJson(Joiner.on("\n").join(lines), JsonElement.class);
}
enum ContactNoticeType {
NONE,
DOMAIN,
@ -46,48 +55,13 @@ public class RdapTestHelper {
}
static ImmutableList<ImmutableMap<String, Object>> createNotices(String linkBase) {
return createNotices(linkBase, ContactNoticeType.NONE, null);
return createNotices(linkBase, null);
}
static ImmutableList<ImmutableMap<String, Object>> createNotices(
String linkBase, ContactNoticeType contactNoticeType, @Nullable Object otherNotices) {
String linkBase, @Nullable Object otherNotices) {
ImmutableList.Builder<ImmutableMap<String, Object>> noticesBuilder =
getBuilderWithOthersAdded(otherNotices);
switch (contactNoticeType) {
case DOMAIN:
noticesBuilder.add(
ImmutableMap.of(
"title", "Contacts Hidden",
"description",
ImmutableList.of("Domain contacts are visible only to the owning registrar."),
"type", "object truncated due to unexplainable reasons"));
break;
case CONTACT:
noticesBuilder.add(
ImmutableMap.of(
"title",
"Data Policy",
"description",
ImmutableList.of(
"Some of the data in this object has been removed.",
"Contact personal data is visible only to the owning registrar."),
"type",
"object truncated due to authorization",
"links",
ImmutableList.of(
ImmutableMap.of(
"value",
"https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
"rel",
"alternate",
"href",
"https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
"type",
"text/html"))));
break;
default:
break;
}
noticesBuilder.add(
ImmutableMap.of(
"title", "RDAP Terms of Service",
@ -142,28 +116,13 @@ public class RdapTestHelper {
}
static void addDomainBoilerplateNotices(ImmutableMap.Builder<String, Object> builder) {
addDomainBoilerplateNotices(builder, false, null);
addDomainBoilerplateNotices(builder, null);
}
static void addDomainBoilerplateNotices(
ImmutableMap.Builder<String, Object> builder, @Nullable Object otherNotices) {
addDomainBoilerplateNotices(builder, false, otherNotices);
}
static void addDomainBoilerplateNotices(
ImmutableMap.Builder<String, Object> builder,
boolean addNoContactRemark,
@Nullable Object otherNotices) {
ImmutableList.Builder<ImmutableMap<String, Object>> noticesBuilder =
getBuilderWithOthersAdded(otherNotices);
if (addNoContactRemark) {
noticesBuilder.add(
ImmutableMap.of(
"title", "Contacts Hidden",
"description",
ImmutableList.of("Domain contacts are visible only to the owning registrar."),
"type", "object truncated due to unexplainable reasons"));
}
noticesBuilder.add(
ImmutableMap.of(
"description",
@ -214,57 +173,31 @@ public class RdapTestHelper {
static RdapJsonFormatter getTestRdapJsonFormatter() {
RdapJsonFormatter rdapJsonFormatter = new RdapJsonFormatter();
rdapJsonFormatter.rdapTosPath = "/tos";
rdapJsonFormatter.rdapHelpMap =
ImmutableMap.of(
"/",
RdapNoticeDescriptor.builder()
.setTitle("RDAP Help")
.setDescription(
ImmutableList.of(
"domain/XXXX",
"nameserver/XXXX",
"entity/XXXX",
"domains?name=XXXX",
"domains?nsLdhName=XXXX",
"domains?nsIp=XXXX",
"nameservers?name=XXXX",
"nameservers?ip=XXXX",
"entities?fn=XXXX",
"entities?handle=XXXX",
"help/XXXX"))
.setLinkValueSuffix("help/")
.setLinkHrefUrlString("https://github.com/google/nomulus/blob/master/docs/rdap.md")
.build(),
"/tos",
RdapNoticeDescriptor.builder()
.setTitle("RDAP Terms of Service")
.setDescription(
ImmutableList.of(
"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."))
.setLinkValueSuffix("help/tos")
.setLinkHrefUrlString("https://www.registry.tld/about/rdap/tos.html")
.build());
rdapJsonFormatter.fullServletPath = "https://example.tld/rdap/";
rdapJsonFormatter.rdapTos =
ImmutableList.of(
"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.");
rdapJsonFormatter.rdapTosStaticUrl = "https://www.registry.tld/about/rdap/tos.html";
return rdapJsonFormatter;
}

View file

@ -1,4 +1,7 @@
{
"rdapConformance": [
"icann_rdap_response_profile_0"
],
"objectClassName" : "entity",
"handle" : "%NAME%",
"status" : ["active", "associated"],

View file

@ -1,4 +1,7 @@
{
"rdapConformance": [
"icann_rdap_response_profile_0"
],
"objectClassName" : "entity",
"handle" : "%NAME%",
"status" : ["active", "associated", "removed"],
@ -21,5 +24,23 @@
"eventAction": "last update of RDAP database",
"eventDate": "2000-01-01T00:00:00.000Z"
}
],
"remarks": [
{
"title": "Redacted for Privacy",
"type": "object redacted due to authorization",
"links": [
{
"type":"text\/html",
"value": "https:\/\/github.com\/google\/nomulus\/blob\/master\/docs\/rdap.md#authentication",
"href": "https:\/\/github.com\/google\/nomulus\/blob\/master\/docs\/rdap.md#authentication",
"rel": "alternate"
}
],
"description": [
"Some of the data in this object has been removed.",
"Contact personal data is visible only to the owning registrar."
]
}
]
}

View file

@ -1,4 +1,7 @@
{
"rdapConformance": [
"icann_rdap_response_profile_0"
],
"objectClassName" : "entity",
"handle" : "%NAME%",
"status" : ["%STATUS%"],

View file

@ -1,4 +1,7 @@
{
"rdapConformance": [
"icann_rdap_response_profile_0"
],
"objectClassName" : "entity",
"handle" : "%NAME%",
"status" : ["inactive"],

View file

@ -1,4 +1,7 @@
{
"rdapConformance": [
"icann_rdap_response_profile_0"
],
"objectClassName" : "entity",
"handle" : "%NAME%",
"status" : ["active", "removed"],
@ -24,12 +27,12 @@
],
"remarks": [
{
"title": "Data Policy",
"title": "Redacted for Privacy",
"description": [
"Some of the data in this object has been removed.",
"Contact personal data is visible only to the owning registrar."
],
"type": "object truncated due to authorization",
"type": "object redacted due to authorization",
"links" :
[
{

View file

@ -1,4 +1,7 @@
{
"rdapConformance": [
"icann_rdap_response_profile_0"
],
"status": [
"client delete prohibited",
"client renew prohibited",

View file

@ -1,4 +1,7 @@
{
"rdapConformance": [
"icann_rdap_response_profile_0"
],
"status": [
"client delete prohibited",
"client renew prohibited",

View file

@ -1,4 +1,7 @@
{
"rdapConformance": [
"icann_rdap_response_profile_0"
],
"status": [
"client delete prohibited",
"client renew prohibited",

View file

@ -1,262 +0,0 @@
{
"objectClassName": "domain",
"handle": "%HANDLE%",
"ldhName": "%NAME%",
"status": [
"client delete prohibited",
"client renew prohibited",
"client transfer prohibited",
"server update prohibited"
],
"links": [
{
"href": "https://example.tld/rdap/domain/%NAME%",
"type": "application/rdap+json",
"rel": "self",
"value": "https://example.tld/rdap/domain/%NAME%"
}
],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "2000-01-01T00:00:00.000Z"
},
{
"eventAction": "expiration",
"eventDate": "2110-10-08T00:44:59.000Z"
},
{
"eventAction": "last update of RDAP database",
"eventDate": "2000-01-01T00:00:00.000Z"
}
],
"nameservers": [
{
"status": [
"active",
"associated"
],
"handle": "%NAMESERVER1ROID%",
"links": [
{
"href": "https://example.tld/rdap/nameserver/%NAMESERVER1NAME%",
"type": "application/rdap+json",
"rel": "self",
"value": "https://example.tld/rdap/nameserver/%NAMESERVER1NAME%"
}
],
"ldhName": "%NAMESERVER1NAME%",
"ipAddresses": {
"v4": [
"%NAMESERVER1ADDRESS%"
]
},
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
},
{
"eventAction": "last update of RDAP database",
"eventDate": "2000-01-01T00:00:00.000Z"
}
],
"objectClassName": "nameserver",
"entities": [
{
"objectClassName": "entity",
"status": [ "active" ],
"handle": "1",
"roles": [ "registrar" ],
"links": [
{
"href": "https://example.tld/rdap/entity/1",
"type": "application/rdap+json",
"rel": "self",
"value": "https://example.tld/rdap/entity/1"
}
],
"vcardArray" : [
"vcard",
[
["version", {}, "text", "4.0"],
["fn", {}, "text", "The Registrar"],
[
"adr",
{},
"text",
[
"",
"",
"123 Example Boulevard",
"Williamsburg",
"NY",
"11211",
"United States"
]
],
["tel", {"type":["voice"]}, "uri", "tel:+1.2223334444"],
["email", {}, "text", "the.registrar@example.com"]
]
],
"publicIds" : [
{
"type": "IANA Registrar ID",
"identifier":"1"
}
],
"remarks": [
{
"title": "Incomplete Data",
"description": [
"Summary data only. For complete data, send a specific query for the object."
],
"type": "object truncated due to unexplainable reasons"
}
]
}
]
},
{
"status": [
"active",
"associated"
],
"handle": "%NAMESERVER2ROID%",
"links": [
{
"href": "https://example.tld/rdap/nameserver/%NAMESERVER2NAME%",
"type": "application/rdap+json",
"rel": "self",
"value": "https://example.tld/rdap/nameserver/%NAMESERVER2NAME%"
}
],
"ldhName": "%NAMESERVER2NAME%",
"ipAddresses": {
"v6": [
"%NAMESERVER2ADDRESS%"
]
},
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1998-01-01T00:00:00.000Z"
},
{
"eventAction": "last update of RDAP database",
"eventDate": "2000-01-01T00:00:00.000Z"
}
],
"objectClassName": "nameserver",
"entities": [
{
"objectClassName": "entity",
"status": [ "active" ],
"handle": "1",
"roles": [ "registrar" ],
"links": [
{
"href": "https://example.tld/rdap/entity/1",
"type": "application/rdap+json",
"rel": "self",
"value": "https://example.tld/rdap/entity/1"
}
],
"vcardArray" : [
"vcard",
[
["version", {}, "text", "4.0"],
["fn", {}, "text", "The Registrar"],
[
"adr",
{},
"text",
[
"",
"",
"123 Example Boulevard",
"Williamsburg",
"NY",
"11211",
"United States"
]
],
["tel", {"type":["voice"]}, "uri", "tel:+1.2223334444"],
["email", {}, "text", "the.registrar@example.com"]
]
],
"publicIds" : [
{
"type": "IANA Registrar ID",
"identifier":"1"
}
],
"remarks": [
{
"title": "Incomplete Data",
"description": [
"Summary data only. For complete data, send a specific query for the object."
],
"type": "object truncated due to unexplainable reasons"
}
]
}
]
}
],
"entities": [
{
"objectClassName" : "entity",
"handle" : "1",
"status" : ["active"],
"roles" : ["registrar"],
"links" :
[
{
"value" : "https://example.tld/rdap/entity/1",
"rel" : "self",
"href" : "https://example.tld/rdap/entity/1",
"type" : "application/rdap+json"
}
],
"publicIds" :
[
{
"type" : "IANA Registrar ID",
"identifier" : "1"
}
],
"vcardArray" :
[
"vcard",
[
["version", {}, "text", "4.0"],
["fn", {}, "text", "%REGISTRARNAME%"],
["adr", {}, "text", [
"",
"",
"123 Example Boulevard <script>",
"Williamsburg <script>",
"NY",
"11211",
"United States"]],
["tel", {"type" : ["voice"]}, "uri", "tel:+1.2125551212"],
["tel", {"type" : ["fax"]}, "uri", "tel:+1.2125551213"],
["email", {}, "text", "contact-us@example.com"]
]
],
"remarks": [
{
"title": "Incomplete Data",
"description": [
"Summary data only. For complete data, send a specific query for the object."
],
"type": "object truncated due to unexplainable reasons"
}
]
}
]
}

View file

@ -2,6 +2,9 @@
"objectClassName": "domain",
"handle": "%HANDLE%",
"ldhName": "%NAME%",
"rdapConformance": [
"icann_rdap_response_profile_0"
],
"status": [
"client delete prohibited",
"client renew prohibited",

View file

@ -1,4 +1,7 @@
{
"rdapConformance": [
"icann_rdap_response_profile_0"
],
"status": [
"client delete prohibited",
"client renew prohibited",

View file

@ -1,4 +1,7 @@
{
"rdapConformance": [
"icann_rdap_response_profile_0"
],
"objectClassName": "domain",
"handle": "%HANDLE%",
"ldhName": "%PUNYCODENAME%",

View file

@ -0,0 +1,36 @@
{
"lang": "en",
"errorCode": %CODE%,
"title": "%TITLE%",
"description": [
"%DESCRIPTION%"
],
"rdapConformance": [
"icann_rdap_response_profile_0"
],
"notices": [
{
"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."
],
"links": [
{
"href": "https://www.registry.tld/about/rdap/tos.html",
"rel": "alternate",
"type": "text/html",
"value": "https://example.tld/rdap/help/tos"
}
],
"title": "RDAP Terms of Service"
}
]
}

View file

@ -1,11 +0,0 @@
{
"lang": "en",
"errorCode": 400,
"title": "Bad Request",
"description": [
"%NAME%"
],
"rdapConformance": [
"icann_rdap_response_profile_0"
]
}

View file

@ -1,11 +0,0 @@
{
"lang": "en",
"errorCode": 404,
"title": "Not Found",
"description": [
"%NAME%"
],
"rdapConformance": [
"icann_rdap_response_profile_0"
]
}

View file

@ -1,11 +0,0 @@
{
"lang": "en",
"errorCode": 422,
"title": "Unprocessable Entity",
"description": [
"%NAME%"
],
"rdapConformance": [
"icann_rdap_response_profile_0"
]
}

View file

@ -1,11 +0,0 @@
{
"lang": "en",
"errorCode": 501,
"title": "Not Implemented",
"description": [
"%NAME%"
],
"rdapConformance": [
"icann_rdap_response_profile_0"
]
}

View file

@ -1,14 +0,0 @@
{
"key" : "value",
"rdapConformance" : [ "icann_rdap_response_profile_0" ],
"notices" : [ {
"title" : "RDAP Terms of Service",
"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." ],
"links" : [ {
"value" : "http://myserver.example.com/help/tos",
"rel" : "alternate",
"href" : "https://www.registry.tld/about/rdap/tos.html",
"type" : "text/html"
} ]
} ]
}

View file

@ -21,7 +21,7 @@
"links" :
[
{
"value" : "https://example.tld/rdap/help/%NAME%",
"value" : "https://example.tld/rdap/help",
"rel" : "alternate",
"type" : "text/html",
"href" : "https://github.com/google/nomulus/blob/master/docs/rdap.md"

View file

@ -1,4 +1,7 @@
{
"rdapConformance": [
"icann_rdap_response_profile_0"
],
"status": [
"%STATUS%"
],

View file

@ -1,4 +1,7 @@
{
"rdapConformance": [
"icann_rdap_response_profile_0"
],
"status": [
"active"
],

View file

@ -1,4 +1,7 @@
{
"rdapConformance": [
"icann_rdap_response_profile_0"
],
"status": [
"active",
"associated"

View file

@ -1,4 +1,7 @@
{
"rdapConformance": [
"icann_rdap_response_profile_0"
],
"status": [
"active"
],

View file

@ -1,4 +1,7 @@
{
"rdapConformance": [
"icann_rdap_response_profile_0"
],
"objectClassName" : "entity",
"handle" : "%NAME%",
"status" : ["%STATUS%"],

View file

@ -1,4 +1,7 @@
{
"rdapConformance": [
"icann_rdap_response_profile_0"
],
"objectClassName" : "entity",
"handle" : "%NAME%",
"status" : ["%STATUS%"],

View file

@ -337,7 +337,7 @@
{
"type" : "application/rdap+json",
"rel" : "next",
"href" : "https://example.tld/rdap/nameservers?%NAME%"
"href" : "https://example.tld/rdap/nameservers?%QUERY%"
}
]
},

View file

@ -1 +1 @@
{"key":"value","rdapConformance":["icann_rdap_response_profile_0"],"notices":[{"title":"RDAP Terms of Service","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."],"links":[{"value":"http:\/\/myserver.example.com\/help\/tos","rel":"alternate","href":"https:\/\/www.registry.tld\/about\/rdap\/tos.html","type":"text\/html"}]}]}
{"key":"value","rdapConformance":["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."]}]}

View file

@ -6,9 +6,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/4-ROID",
"value" : "https://example.tld/rdap/entity/4-ROID",
"rel" : "self",
"href" : "http://myserver.example.com/entity/4-ROID",
"href" : "https://example.tld/rdap/entity/4-ROID",
"type" : "application/rdap+json"
}
],

View file

@ -13,9 +13,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/domain/cat.xn--q9jyb4c",
"value" : "https://example.tld/rdap/domain/cat.xn--q9jyb4c",
"rel" : "self",
"href" : "http://myserver.example.com/domain/cat.xn--q9jyb4c",
"href" : "https://example.tld/rdap/domain/cat.xn--q9jyb4c",
"type" : "application/rdap+json"
}
],
@ -54,9 +54,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/nameserver/ns1.cat.xn--q9jyb4c",
"value" : "https://example.tld/rdap/nameserver/ns1.cat.xn--q9jyb4c",
"rel" : "self",
"href" : "http://myserver.example.com/nameserver/ns1.cat.xn--q9jyb4c",
"href" : "https://example.tld/rdap/nameserver/ns1.cat.xn--q9jyb4c",
"type" : "application/rdap+json"
}
],
@ -84,9 +84,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/1",
"value" : "https://example.tld/rdap/entity/1",
"rel" : "self",
"href" : "http://myserver.example.com/entity/1",
"href" : "https://example.tld/rdap/entity/1",
"type" : "application/rdap+json"
}
],
@ -137,9 +137,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/nameserver/ns2.cat.xn--q9jyb4c",
"value" : "https://example.tld/rdap/nameserver/ns2.cat.xn--q9jyb4c",
"rel" : "self",
"href" : "http://myserver.example.com/nameserver/ns2.cat.xn--q9jyb4c",
"href" : "https://example.tld/rdap/nameserver/ns2.cat.xn--q9jyb4c",
"type" : "application/rdap+json"
}
],
@ -167,9 +167,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/1",
"value" : "https://example.tld/rdap/entity/1",
"rel" : "self",
"href" : "http://myserver.example.com/entity/1",
"href" : "https://example.tld/rdap/entity/1",
"type" : "application/rdap+json"
}
],
@ -222,9 +222,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/4-ROID",
"value" : "https://example.tld/rdap/entity/4-ROID",
"rel" : "self",
"href" : "http://myserver.example.com/entity/4-ROID",
"href" : "https://example.tld/rdap/entity/4-ROID",
"type" : "application/rdap+json"
}
],
@ -271,9 +271,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/6-ROID",
"value" : "https://example.tld/rdap/entity/6-ROID",
"rel" : "self",
"href" : "http://myserver.example.com/entity/6-ROID",
"href" : "https://example.tld/rdap/entity/6-ROID",
"type" : "application/rdap+json"
}
],
@ -320,9 +320,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/2-ROID",
"value" : "https://example.tld/rdap/entity/2-ROID",
"rel" : "self",
"href" : "http://myserver.example.com/entity/2-ROID",
"href" : "https://example.tld/rdap/entity/2-ROID",
"type" : "application/rdap+json"
}
],
@ -345,7 +345,7 @@
["fn", {}, "text", "(◕‿◕)"],
["org", {}, "text", "GOOGLE INCORPORATED <script>"],
["tel", {"type" : ["voice"]}, "uri", "tel:+1.2126660420"],
["tel", {"type" : ["fax"]}, "uri", "tel:+1.2126660420"]
["tel", {"type" : ["fax"]}, "uri", "tel:+1.2126660420"],
["email", {}, "text", "lol@cat.みんな"]
]
]
@ -358,9 +358,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/1",
"value" : "https://example.tld/rdap/entity/1",
"rel" : "self",
"href" : "http://myserver.example.com/entity/1",
"href" : "https://example.tld/rdap/entity/1",
"type" : "application/rdap+json"
}
],

View file

@ -13,9 +13,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/domain/cat.xn--q9jyb4c",
"value" : "https://example.tld/rdap/domain/cat.xn--q9jyb4c",
"rel" : "self",
"href" : "http://myserver.example.com/domain/cat.xn--q9jyb4c",
"href" : "https://example.tld/rdap/domain/cat.xn--q9jyb4c",
"type" : "application/rdap+json"
}
],
@ -54,9 +54,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/nameserver/ns1.cat.xn--q9jyb4c",
"value" : "https://example.tld/rdap/nameserver/ns1.cat.xn--q9jyb4c",
"rel" : "self",
"href" : "http://myserver.example.com/nameserver/ns1.cat.xn--q9jyb4c",
"href" : "https://example.tld/rdap/nameserver/ns1.cat.xn--q9jyb4c",
"type" : "application/rdap+json"
}
],
@ -84,9 +84,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/1",
"value" : "https://example.tld/rdap/entity/1",
"rel" : "self",
"href" : "http://myserver.example.com/entity/1",
"href" : "https://example.tld/rdap/entity/1",
"type" : "application/rdap+json"
}
],
@ -137,9 +137,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/nameserver/ns2.cat.xn--q9jyb4c",
"value" : "https://example.tld/rdap/nameserver/ns2.cat.xn--q9jyb4c",
"rel" : "self",
"href" : "http://myserver.example.com/nameserver/ns2.cat.xn--q9jyb4c",
"href" : "https://example.tld/rdap/nameserver/ns2.cat.xn--q9jyb4c",
"type" : "application/rdap+json"
}
],
@ -167,9 +167,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/1",
"value" : "https://example.tld/rdap/entity/1",
"rel" : "self",
"href" : "http://myserver.example.com/entity/1",
"href" : "https://example.tld/rdap/entity/1",
"type" : "application/rdap+json"
}
],
@ -221,9 +221,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/1",
"value" : "https://example.tld/rdap/entity/1",
"rel" : "self",
"href" : "http://myserver.example.com/entity/1",
"href" : "https://example.tld/rdap/entity/1",
"type" : "application/rdap+json"
}
],

View file

@ -14,9 +14,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/domain/fish.xn--q9jyb4c",
"value" : "https://example.tld/rdap/domain/fish.xn--q9jyb4c",
"rel" : "self",
"href" : "http://myserver.example.com/domain/fish.xn--q9jyb4c",
"href" : "https://example.tld/rdap/domain/fish.xn--q9jyb4c",
"type" : "application/rdap+json"
}
],
@ -45,9 +45,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/4-ROID",
"value" : "https://example.tld/rdap/entity/4-ROID",
"rel" : "self",
"href" : "http://myserver.example.com/entity/4-ROID",
"href" : "https://example.tld/rdap/entity/4-ROID",
"type" : "application/rdap+json"
}
],
@ -94,9 +94,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/6-ROID",
"value" : "https://example.tld/rdap/entity/6-ROID",
"rel" : "self",
"href" : "http://myserver.example.com/entity/6-ROID",
"href" : "https://example.tld/rdap/entity/6-ROID",
"type" : "application/rdap+json"
}
],
@ -143,9 +143,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/2-ROID",
"value" : "https://example.tld/rdap/entity/2-ROID",
"rel" : "self",
"href" : "http://myserver.example.com/entity/2-ROID",
"href" : "https://example.tld/rdap/entity/2-ROID",
"type" : "application/rdap+json"
}
],
@ -181,9 +181,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/1",
"value" : "https://example.tld/rdap/entity/1",
"rel" : "self",
"href" : "http://myserver.example.com/entity/1",
"href" : "https://example.tld/rdap/entity/1",
"type" : "application/rdap+json"
}
],

View file

@ -13,9 +13,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/domain/cat.xn--q9jyb4c",
"value" : "https://example.tld/rdap/domain/cat.xn--q9jyb4c",
"rel" : "self",
"href" : "http://myserver.example.com/domain/cat.xn--q9jyb4c",
"href" : "https://example.tld/rdap/domain/cat.xn--q9jyb4c",
"type" : "application/rdap+json"
}
],

View file

@ -1,9 +1,5 @@
{
"rdapConformance" :
[
"icann_rdap_response_profile_0"
],
"lang" : "en"
"lang" : "en",
"errorCode" : 400,
"title" : "Invalid Domain Name",
"description" :

View file

@ -7,9 +7,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/nameserver/ns3.cat.xn--q9jyb4c",
"value" : "https://example.tld/rdap/nameserver/ns3.cat.xn--q9jyb4c",
"rel" : "self",
"href" : "http://myserver.example.com/nameserver/ns3.cat.xn--q9jyb4c",
"href" : "https://example.tld/rdap/nameserver/ns3.cat.xn--q9jyb4c",
"type" : "application/rdap+json"
}
],
@ -38,9 +38,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/1",
"value" : "https://example.tld/rdap/entity/1",
"rel" : "self",
"href" : "http://myserver.example.com/entity/1",
"href" : "https://example.tld/rdap/entity/1",
"type" : "application/rdap+json"
}
],

View file

@ -7,9 +7,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/nameserver/ns3.cat.xn--q9jyb4c",
"value" : "https://example.tld/rdap/nameserver/ns3.cat.xn--q9jyb4c",
"rel" : "self",
"href" : "http://myserver.example.com/nameserver/ns3.cat.xn--q9jyb4c",
"href" : "https://example.tld/rdap/nameserver/ns3.cat.xn--q9jyb4c",
"type" : "application/rdap+json"
}
],
@ -36,9 +36,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/1",
"value" : "https://example.tld/rdap/entity/1",
"rel" : "self",
"href" : "http://myserver.example.com/entity/1",
"href" : "https://example.tld/rdap/entity/1",
"type" : "application/rdap+json"
}
],

View file

@ -7,9 +7,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/nameserver/ns1.cat.xn--q9jyb4c",
"value" : "https://example.tld/rdap/nameserver/ns1.cat.xn--q9jyb4c",
"rel" : "self",
"href" : "http://myserver.example.com/nameserver/ns1.cat.xn--q9jyb4c",
"href" : "https://example.tld/rdap/nameserver/ns1.cat.xn--q9jyb4c",
"type" : "application/rdap+json"
}
],
@ -37,9 +37,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/1",
"value" : "https://example.tld/rdap/entity/1",
"rel" : "self",
"href" : "http://myserver.example.com/entity/1",
"href" : "https://example.tld/rdap/entity/1",
"type" : "application/rdap+json"
}
],

View file

@ -7,9 +7,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/nameserver/ns2.cat.xn--q9jyb4c",
"value" : "https://example.tld/rdap/nameserver/ns2.cat.xn--q9jyb4c",
"rel" : "self",
"href" : "http://myserver.example.com/nameserver/ns2.cat.xn--q9jyb4c",
"href" : "https://example.tld/rdap/nameserver/ns2.cat.xn--q9jyb4c",
"type" : "application/rdap+json"
}
],
@ -37,9 +37,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/1",
"value" : "https://example.tld/rdap/entity/1",
"rel" : "self",
"href" : "http://myserver.example.com/entity/1",
"href" : "https://example.tld/rdap/entity/1",
"type" : "application/rdap+json"
}
],

View file

@ -7,9 +7,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/nameserver/ns4.cat.xn--q9jyb4c",
"value" : "https://example.tld/rdap/nameserver/ns4.cat.xn--q9jyb4c",
"rel" : "self",
"href" : "http://myserver.example.com/nameserver/ns4.cat.xn--q9jyb4c",
"href" : "https://example.tld/rdap/nameserver/ns4.cat.xn--q9jyb4c",
"type" : "application/rdap+json"
}
],
@ -33,9 +33,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/1",
"value" : "https://example.tld/rdap/entity/1",
"rel" : "self",
"href" : "http://myserver.example.com/entity/1",
"href" : "https://example.tld/rdap/entity/1",
"type" : "application/rdap+json"
}
],

View file

@ -7,9 +7,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/nameserver/ns5.cat.xn--q9jyb4c",
"value" : "https://example.tld/rdap/nameserver/ns5.cat.xn--q9jyb4c",
"rel" : "self",
"href" : "http://myserver.example.com/nameserver/ns5.cat.xn--q9jyb4c",
"href" : "https://example.tld/rdap/nameserver/ns5.cat.xn--q9jyb4c",
"type" : "application/rdap+json"
}
],
@ -33,9 +33,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/1",
"value" : "https://example.tld/rdap/entity/1",
"rel" : "self",
"href" : "http://myserver.example.com/entity/1",
"href" : "https://example.tld/rdap/entity/1",
"type" : "application/rdap+json"
}
],

View file

@ -7,9 +7,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/nameserver/ns1.dog.xn--q9jyb4c",
"value" : "https://example.tld/rdap/nameserver/ns1.dog.xn--q9jyb4c",
"rel" : "self",
"href" : "http://myserver.example.com/nameserver/ns1.dog.xn--q9jyb4c",
"href" : "https://example.tld/rdap/nameserver/ns1.dog.xn--q9jyb4c",
"type" : "application/rdap+json"
}
],
@ -33,9 +33,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/1",
"value" : "https://example.tld/rdap/entity/1",
"rel" : "self",
"href" : "http://myserver.example.com/entity/1",
"href" : "https://example.tld/rdap/entity/1",
"type" : "application/rdap+json"
}
],

View file

@ -9,10 +9,10 @@
"links" :
[
{
"value" : "http://myserver.example.com/help/index",
"value" : "https://example.tld/rdap/help/index",
"rel" : "alternate",
"type" : "text/html",
"href" : "http://myserver.example.com/about/rdap/index.html"
"href" : "https://example.tld/rdap/about/rdap/index.html"
}
]
}

View file

@ -9,10 +9,10 @@
"links" :
[
{
"value" : "http://myserver.example.com/help/index",
"value" : "https://example.tld/rdap/help/index",
"rel" : "self",
"type" : "application/rdap+json",
"href" : "http://myserver.example.com/help/index",
"href" : "https://example.tld/rdap/help/index"
}
]
}

View file

@ -6,9 +6,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/2-ROID",
"value" : "https://example.tld/rdap/entity/2-ROID",
"rel" : "self",
"href" : "http://myserver.example.com/entity/2-ROID",
"href" : "https://example.tld/rdap/entity/2-ROID",
"type" : "application/rdap+json"
}
],

View file

@ -6,9 +6,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/2-ROID",
"value" : "https://example.tld/rdap/entity/2-ROID",
"rel" : "self",
"href" : "http://myserver.example.com/entity/2-ROID",
"href" : "https://example.tld/rdap/entity/2-ROID",
"type" : "application/rdap+json"
}
],
@ -25,12 +25,12 @@
],
"remarks": [
{
"title": "Data Policy",
"title": "Redacted for Privacy",
"description": [
"Some of the data in this object has been removed.",
"Contact personal data is visible only to the owning registrar."
],
"type": "object truncated due to authorization",
"type": "object redacted due to authorization",
"links" :
[
{

View file

@ -6,9 +6,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/2-ROID",
"value" : "https://example.tld/rdap/entity/2-ROID",
"rel" : "self",
"href" : "http://myserver.example.com/entity/2-ROID",
"href" : "https://example.tld/rdap/entity/2-ROID",
"type" : "application/rdap+json"
}
],

View file

@ -6,9 +6,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/2-ROID",
"value" : "https://example.tld/rdap/entity/2-ROID",
"rel" : "self",
"href" : "http://myserver.example.com/entity/2-ROID",
"href" : "https://example.tld/rdap/entity/2-ROID",
"type" : "application/rdap+json"
}
],
@ -33,12 +33,12 @@
"type": "object truncated due to unexplainable reasons"
},
{
"title": "Data Policy",
"title": "Redacted for Privacy",
"description": [
"Some of the data in this object has been removed.",
"Contact personal data is visible only to the owning registrar."
],
"type": "object truncated due to authorization",
"type": "object redacted due to authorization",
"links" :
[
{

View file

@ -6,9 +6,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/1",
"value" : "https://example.tld/rdap/entity/1",
"rel" : "self",
"href" : "http://myserver.example.com/entity/1",
"href" : "https://example.tld/rdap/entity/1",
"type" : "application/rdap+json"
}
],
@ -68,7 +68,7 @@
["tel", {"type" : ["voice"]}, "uri", "tel:+1.2125551215"],
["email", {}, "text", "janedoe@example.com"]
]
],
]
},
{
"objectClassName" : "entity",
@ -83,7 +83,7 @@
["tel", {"type" : ["fax"]}, "uri", "tel:+1.2125551213"],
["email", {}, "text", "johndoe@example.com"]
]
],
]
},
{
"objectClassName" : "entity",
@ -99,7 +99,7 @@
["tel", {"type" : ["fax"]}, "uri", "tel:+1.2125551218"],
["email", {}, "text", "playdoe@example.com"]
]
],
]
}
]
}

View file

@ -6,9 +6,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/1",
"value" : "https://example.tld/rdap/entity/1",
"rel" : "self",
"href" : "http://myserver.example.com/entity/1",
"href" : "https://example.tld/rdap/entity/1",
"type" : "application/rdap+json"
}
],

View file

@ -5,9 +5,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/6-ROID",
"value" : "https://example.tld/rdap/entity/6-ROID",
"rel" : "self",
"href" : "http://myserver.example.com/entity/6-ROID",
"href" : "https://example.tld/rdap/entity/6-ROID",
"type" : "application/rdap+json"
}
],

View file

@ -6,9 +6,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/6-ROID",
"value" : "https://example.tld/rdap/entity/6-ROID",
"rel" : "self",
"href" : "http://myserver.example.com/entity/6-ROID",
"href" : "https://example.tld/rdap/entity/6-ROID",
"type" : "application/rdap+json"
}
],

View file

@ -24,7 +24,7 @@
"links" :
[
{
"value" : "http://myserver.example.com/help/tos",
"value" : "https://example.tld/rdap/help/tos",
"rel" : "alternate",
"href" : "https://www.registry.tld/about/rdap/tos.html",
"type" : "text/html"

View file

@ -24,7 +24,7 @@
"links" :
[
{
"value" : "http://myserver.example.com/help/tos",
"value" : "https://example.tld/rdap/help/tos",
"rel" : "alternate",
"href" : "https://www.registry.tld/about/rdap/tos.html",
"type" : "text/html"

View file

@ -5,9 +5,9 @@
"links" :
[
{
"value" : "http://myserver.example.com/entity/8-ROID",
"value" : "https://example.tld/rdap/entity/8-ROID",
"rel" : "self",
"href" : "http://myserver.example.com/entity/8-ROID",
"href" : "https://example.tld/rdap/entity/8-ROID",
"type" : "application/rdap+json"
}
],