Convert RDAP tests from simple.json to Gson

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=247237275
This commit is contained in:
guyben 2019-05-08 10:20:53 -07:00 committed by jianglai
parent 3b8a8892bb
commit 38e2175699
16 changed files with 305 additions and 425 deletions

View file

@ -20,7 +20,6 @@ import static google.registry.testing.JUnitBackports.assertThrows;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive; import com.google.gson.JsonPrimitive;
import google.registry.rdap.AbstractJsonableObject.JsonableException; import google.registry.rdap.AbstractJsonableObject.JsonableException;
@ -34,7 +33,7 @@ import org.junit.runners.JUnit4;
@RunWith(JUnit4.class) @RunWith(JUnit4.class)
public final class AbstractJsonableObjectTest { public final class AbstractJsonableObjectTest {
private final Gson gson = new GsonBuilder().create(); private final Gson gson = new Gson();
private JsonElement createJson(String... lines) { private JsonElement createJson(String... lines) {
return gson.fromJson(Joiner.on("\n").join(lines), JsonElement.class); return gson.fromJson(Joiner.on("\n").join(lines), JsonElement.class);

View file

@ -30,7 +30,6 @@ import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
import google.registry.request.Action; import google.registry.request.Action;
import google.registry.request.auth.Auth; import google.registry.request.auth.Auth;
import java.util.Optional; import java.util.Optional;
import org.json.simple.JSONValue;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -168,7 +167,7 @@ public class RdapActionBaseTest extends RdapActionBaseTestCase<RdapActionBaseTes
action.run(); action.run();
String payload = response.getPayload(); String payload = response.getPayload();
assertThat(payload).doesNotContain("\n"); assertThat(payload).doesNotContain("\n");
assertThat(JSONValue.parse(payload)).isEqualTo(loadJsonFile("rdapjson_toplevel.json")); assertThat(parseJsonObject(payload)).isEqualTo(loadJsonFile("rdapjson_toplevel.json"));
} }
@Test @Test
@ -179,6 +178,6 @@ public class RdapActionBaseTest extends RdapActionBaseTestCase<RdapActionBaseTes
action.run(); action.run();
String payload = response.getPayload(); String payload = response.getPayload();
assertThat(payload).contains("\n"); assertThat(payload).contains("\n");
assertThat(JSONValue.parse(payload)).isEqualTo(loadJsonFile("rdapjson_toplevel.json")); assertThat(parseJsonObject(payload)).isEqualTo(loadJsonFile("rdapjson_toplevel.json"));
} }
} }

View file

@ -25,6 +25,8 @@ import static org.mockito.Mockito.mock;
import com.google.appengine.api.users.User; import com.google.appengine.api.users.User;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import google.registry.model.ofy.Ofy; import google.registry.model.ofy.Ofy;
import google.registry.request.Action; import google.registry.request.Action;
import google.registry.request.Actions; import google.registry.request.Actions;
@ -39,8 +41,6 @@ import google.registry.util.TypeUtils;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -78,6 +78,8 @@ public class RdapActionBaseTestCase<A extends RdapActionBase> {
protected final String actionPath; protected final String actionPath;
protected final Class<A> rdapActionClass; protected final Class<A> rdapActionClass;
private static final Gson GSON = new Gson();
protected RdapActionBaseTestCase(Class<A> rdapActionClass) { protected RdapActionBaseTestCase(Class<A> rdapActionClass) {
this.rdapActionClass = rdapActionClass; this.rdapActionClass = rdapActionClass;
this.actionPath = Actions.getPathForAction(rdapActionClass); this.actionPath = Actions.getPathForAction(rdapActionClass);
@ -117,11 +119,15 @@ public class RdapActionBaseTestCase<A extends RdapActionBase> {
metricRole = ADMINISTRATOR; metricRole = ADMINISTRATOR;
} }
protected JSONObject generateActualJson(String domainName) { protected static JsonObject parseJsonObject(String jsonString) {
return GSON.fromJson(jsonString, JsonObject.class);
}
protected JsonObject generateActualJson(String domainName) {
action.requestPath = actionPath + domainName; action.requestPath = actionPath + domainName;
action.requestMethod = GET; action.requestMethod = GET;
action.run(); action.run();
return (JSONObject) JSONValue.parse(response.getPayload()); return parseJsonObject(response.getPayload());
} }
protected String generateHeadPayload(String domainName) { protected String generateHeadPayload(String domainName) {
@ -141,7 +147,7 @@ public class RdapActionBaseTestCase<A extends RdapActionBase> {
* @param keysAndValues alternating substitution key and value. The substitutions are applied to * @param keysAndValues alternating substitution key and value. The substitutions are applied to
* the file before parsing it to JSON. * the file before parsing it to JSON.
*/ */
protected JSONObject loadJsonFile(String filename, String... keysAndValues) { protected static JsonObject loadJsonFile(String filename, String... keysAndValues) {
checkArgument(keysAndValues.length % 2 == 0); checkArgument(keysAndValues.length % 2 == 0);
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<>(); ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<>();
for (int i = 0; i < keysAndValues.length; i += 2) { for (int i = 0; i < keysAndValues.length; i += 2) {
@ -159,11 +165,11 @@ public class RdapActionBaseTestCase<A extends RdapActionBase> {
* @param substitutions map of substitutions to apply to the file. The substitutions are applied * @param substitutions map of substitutions to apply to the file. The substitutions are applied
* to the file before parsing it to JSON. * to the file before parsing it to JSON.
*/ */
protected JSONObject loadJsonFile(String filename, Map<String, String> substitutions) { protected static JsonObject loadJsonFile(String filename, Map<String, String> substitutions) {
return (JSONObject) JSONValue.parse(loadFile(this.getClass(), filename, substitutions)); return parseJsonObject(loadFile(RdapActionBaseTestCase.class, filename, substitutions));
} }
protected JSONObject generateExpectedJsonError( protected JsonObject generateExpectedJsonError(
String description, String description,
int code) { int code) {
String title; String title;

View file

@ -28,7 +28,7 @@ import static org.mockito.Mockito.verify;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.gson.JsonObject;
import google.registry.model.contact.ContactResource; import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DomainBase; import google.registry.model.domain.DomainBase;
import google.registry.model.domain.Period; import google.registry.model.domain.Period;
@ -42,10 +42,8 @@ import google.registry.rdap.RdapMetrics.WildcardType;
import google.registry.rdap.RdapSearchResults.IncompletenessWarningType; import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
import google.registry.request.Action; import google.registry.request.Action;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.json.simple.JSONObject;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
@ -228,7 +226,7 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
clock.nowUtc().minusMonths(6))); clock.nowUtc().minusMonths(6)));
} }
private JSONObject generateExpectedJson( private JsonObject generateExpectedJson(
String expectedOutputFile, String expectedOutputFile,
String name, String name,
String punycodeName, String punycodeName,
@ -274,7 +272,7 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
return loadJsonFile(expectedOutputFile, substitutionsBuilder.build()); return loadJsonFile(expectedOutputFile, substitutionsBuilder.build());
} }
private JSONObject generateExpectedJsonWithTopLevelEntries( private JsonObject generateExpectedJsonWithTopLevelEntries(
String name, String name,
String punycodeName, String punycodeName,
String handle, String handle,
@ -292,7 +290,7 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
registrarName, registrarName,
expectedOutputFile); expectedOutputFile);
} }
private JSONObject generateExpectedJsonWithTopLevelEntries( private JsonObject generateExpectedJsonWithTopLevelEntries(
String name, String name,
String punycodeName, String punycodeName,
String handle, String handle,
@ -301,7 +299,7 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
@Nullable List<String> nameserverNames, @Nullable List<String> nameserverNames,
@Nullable String registrarName, @Nullable String registrarName,
String expectedOutputFile) { String expectedOutputFile) {
JSONObject obj = JsonObject obj =
generateExpectedJson( generateExpectedJson(
expectedOutputFile, expectedOutputFile,
name, name,
@ -311,59 +309,43 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
nameserverRoids, nameserverRoids,
nameserverNames, nameserverNames,
registrarName); registrarName);
@SuppressWarnings("unchecked") RdapTestHelper.addDomainBoilerplateNotices(obj, "https://example.tld/rdap/");
Map<String, Object> map = (Map<String, Object>) obj;
ImmutableMap.Builder<String, Object> builder =
RdapTestHelper.getBuilderExcluding(map, ImmutableSet.of("notices"));
RdapTestHelper.addDomainBoilerplateNotices(
builder, RdapTestHelper.createNotices("https://example.tld/rdap/", map.get("notices")));
obj = new JSONObject(builder.build());
return obj; return obj;
} }
private void assertJsonEqual(Object json1, Object json2) {
if (json1 instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) json1;
assertThat(map).isEqualTo(json2);
} else {
assertThat(json1).isEqualTo(json2);
}
}
private void assertProperResponseForCatLol(String queryString, String expectedOutputFile) { private void assertProperResponseForCatLol(String queryString, String expectedOutputFile) {
assertJsonEqual( assertThat(generateActualJson(queryString))
generateActualJson(queryString), .isEqualTo(
generateExpectedJsonWithTopLevelEntries( generateExpectedJsonWithTopLevelEntries(
"cat.lol", "cat.lol",
null, null,
"C-LOL", "C-LOL",
ImmutableList.of("4-ROID", "6-ROID", "2-ROID"), ImmutableList.of("4-ROID", "6-ROID", "2-ROID"),
ImmutableList.of("8-ROID", "A-ROID"), ImmutableList.of("8-ROID", "A-ROID"),
"Yes Virginia <script>", "Yes Virginia <script>",
expectedOutputFile)); expectedOutputFile));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@Test @Test
public void testInvalidDomain_returns400() { public void testInvalidDomain_returns400() {
assertJsonEqual( assertThat(generateActualJson("invalid/domain/name"))
generateActualJson("invalid/domain/name"), .isEqualTo(
generateExpectedJsonError( generateExpectedJsonError(
"invalid/domain/name is not a valid domain name: Domain names can only contain a-z," "invalid/domain/name is not a valid domain name: Domain names can only contain a-z,"
+ " 0-9, '.' and '-'", + " 0-9, '.' and '-'",
400)); 400));
assertThat(response.getStatus()).isEqualTo(400); assertThat(response.getStatus()).isEqualTo(400);
} }
@Test @Test
public void testUnknownDomain_returns400() { public void testUnknownDomain_returns400() {
assertJsonEqual( assertThat(generateActualJson("missingdomain.com"))
generateActualJson("missingdomain.com"), .isEqualTo(
generateExpectedJsonError( generateExpectedJsonError(
"missingdomain.com is not a valid domain name: Domain name is under tld com which" "missingdomain.com is not a valid domain name: Domain name is under tld com which"
+ " doesn't exist", + " doesn't exist",
400)); 400));
assertThat(response.getStatus()).isEqualTo(400); assertThat(response.getStatus()).isEqualTo(400);
} }
@ -422,64 +404,64 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
@Test @Test
public void testIdnDomain_works() { public void testIdnDomain_works() {
login("idnregistrar"); login("idnregistrar");
assertJsonEqual( assertThat(generateActualJson("cat.みんな"))
generateActualJson("cat.みんな"), .isEqualTo(
generateExpectedJsonWithTopLevelEntries( generateExpectedJsonWithTopLevelEntries(
"cat.みんな", "cat.みんな",
"cat.xn--q9jyb4c", "cat.xn--q9jyb4c",
"1D-Q9JYB4C", "1D-Q9JYB4C",
ImmutableList.of("19-ROID", "1B-ROID", "17-ROID"), ImmutableList.of("19-ROID", "1B-ROID", "17-ROID"),
ImmutableList.of("8-ROID", "A-ROID"), ImmutableList.of("8-ROID", "A-ROID"),
"IDN Registrar", "IDN Registrar",
"rdap_domain_unicode.json")); "rdap_domain_unicode.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@Test @Test
public void testIdnDomainWithPercentEncoding_works() { public void testIdnDomainWithPercentEncoding_works() {
login("idnregistrar"); login("idnregistrar");
assertJsonEqual( assertThat(generateActualJson("cat.%E3%81%BF%E3%82%93%E3%81%AA"))
generateActualJson("cat.%E3%81%BF%E3%82%93%E3%81%AA"), .isEqualTo(
generateExpectedJsonWithTopLevelEntries( generateExpectedJsonWithTopLevelEntries(
"cat.みんな", "cat.みんな",
"cat.xn--q9jyb4c", "cat.xn--q9jyb4c",
"1D-Q9JYB4C", "1D-Q9JYB4C",
ImmutableList.of("19-ROID", "1B-ROID", "17-ROID"), ImmutableList.of("19-ROID", "1B-ROID", "17-ROID"),
ImmutableList.of("8-ROID", "A-ROID"), ImmutableList.of("8-ROID", "A-ROID"),
"IDN Registrar", "IDN Registrar",
"rdap_domain_unicode.json")); "rdap_domain_unicode.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@Test @Test
public void testPunycodeDomain_works() { public void testPunycodeDomain_works() {
login("idnregistrar"); login("idnregistrar");
assertJsonEqual( assertThat(generateActualJson("cat.xn--q9jyb4c"))
generateActualJson("cat.xn--q9jyb4c"), .isEqualTo(
generateExpectedJsonWithTopLevelEntries( generateExpectedJsonWithTopLevelEntries(
"cat.みんな", "cat.みんな",
"cat.xn--q9jyb4c", "cat.xn--q9jyb4c",
"1D-Q9JYB4C", "1D-Q9JYB4C",
ImmutableList.of("19-ROID", "1B-ROID", "17-ROID"), ImmutableList.of("19-ROID", "1B-ROID", "17-ROID"),
ImmutableList.of("8-ROID", "A-ROID"), ImmutableList.of("8-ROID", "A-ROID"),
"IDN Registrar", "IDN Registrar",
"rdap_domain_unicode.json")); "rdap_domain_unicode.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@Test @Test
public void testMultilevelDomain_works() { public void testMultilevelDomain_works() {
login("1tldregistrar"); login("1tldregistrar");
assertJsonEqual( assertThat(generateActualJson("cat.1.tld"))
generateActualJson("cat.1.tld"), .isEqualTo(
generateExpectedJsonWithTopLevelEntries( generateExpectedJsonWithTopLevelEntries(
"cat.1.tld", "cat.1.tld",
null, null,
"25-1_TLD", "25-1_TLD",
ImmutableList.of("21-ROID", "23-ROID", "1F-ROID"), ImmutableList.of("21-ROID", "23-ROID", "1F-ROID"),
ImmutableList.of("8-ROID", "A-ROID"), ImmutableList.of("8-ROID", "A-ROID"),
"Multilevel Registrar", "Multilevel Registrar",
"rdap_domain.json")); "rdap_domain.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@ -494,9 +476,8 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
@Test @Test
public void testDeletedDomain_notFound() { public void testDeletedDomain_notFound() {
assertJsonEqual( assertThat(generateActualJson("dodo.lol"))
generateActualJson("dodo.lol"), .isEqualTo(generateExpectedJsonError("dodo.lol not found", 404));
generateExpectedJsonError("dodo.lol not found", 404));
assertThat(response.getStatus()).isEqualTo(404); assertThat(response.getStatus()).isEqualTo(404);
} }
@ -526,17 +507,17 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
public void testDeletedDomain_works_loggedInAsCorrectRegistrar() { public void testDeletedDomain_works_loggedInAsCorrectRegistrar() {
login("evilregistrar"); login("evilregistrar");
action.includeDeletedParam = Optional.of(true); action.includeDeletedParam = Optional.of(true);
assertJsonEqual( assertThat(generateActualJson("dodo.lol"))
generateActualJson("dodo.lol"), .isEqualTo(
generateExpectedJsonWithTopLevelEntries( generateExpectedJsonWithTopLevelEntries(
"dodo.lol", "dodo.lol",
null, null,
"15-LOL", "15-LOL",
ImmutableList.of("11-ROID", "13-ROID", "F-ROID"), ImmutableList.of("11-ROID", "13-ROID", "F-ROID"),
ImmutableList.of("8-ROID", "D-ROID"), ImmutableList.of("8-ROID", "D-ROID"),
ImmutableList.of("ns1.cat.lol", "ns2.dodo.lol"), ImmutableList.of("ns1.cat.lol", "ns2.dodo.lol"),
"Yes Virginia <script>", "Yes Virginia <script>",
"rdap_domain_deleted.json")); "rdap_domain_deleted.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@ -544,17 +525,17 @@ public class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainActio
public void testDeletedDomain_works_loggedInAsAdmin() { public void testDeletedDomain_works_loggedInAsAdmin() {
loginAsAdmin(); loginAsAdmin();
action.includeDeletedParam = Optional.of(true); action.includeDeletedParam = Optional.of(true);
assertJsonEqual( assertThat(generateActualJson("dodo.lol"))
generateActualJson("dodo.lol"), .isEqualTo(
generateExpectedJsonWithTopLevelEntries( generateExpectedJsonWithTopLevelEntries(
"dodo.lol", "dodo.lol",
null, null,
"15-LOL", "15-LOL",
ImmutableList.of("11-ROID", "13-ROID", "F-ROID"), ImmutableList.of("11-ROID", "13-ROID", "F-ROID"),
ImmutableList.of("8-ROID", "D-ROID"), ImmutableList.of("8-ROID", "D-ROID"),
ImmutableList.of("ns1.cat.lol", "ns2.dodo.lol"), ImmutableList.of("ns1.cat.lol", "ns2.dodo.lol"),
"Yes Virginia <script>", "Yes Virginia <script>",
"rdap_domain_deleted.json")); "rdap_domain_deleted.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }

View file

@ -35,6 +35,9 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Range; import com.google.common.collect.Range;
import com.google.common.net.InetAddresses; import com.google.common.net.InetAddresses;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
import google.registry.model.contact.ContactResource; import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DomainBase; import google.registry.model.domain.DomainBase;
@ -56,9 +59,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
@ -89,11 +89,11 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
enum RequestType { NONE, NAME, NS_LDH_NAME, NS_IP } enum RequestType { NONE, NAME, NS_LDH_NAME, NS_IP }
private JSONObject generateActualJson(RequestType requestType, String paramValue) { private JsonObject generateActualJson(RequestType requestType, String paramValue) {
return generateActualJson(requestType, paramValue, null); return generateActualJson(requestType, paramValue, null);
} }
private JSONObject generateActualJson( private JsonObject generateActualJson(
RequestType requestType, String paramValue, String cursor) { RequestType requestType, String paramValue, String cursor) {
action.requestPath = actionPath; action.requestPath = actionPath;
action.requestMethod = POST; action.requestMethod = POST;
@ -135,7 +135,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
} }
} }
action.run(); action.run();
return (JSONObject) JSONValue.parse(response.getPayload()); return parseJsonObject(response.getPayload());
} }
private HostResource addHostToMap(HostResource host) { private HostResource addHostToMap(HostResource host) {
@ -362,11 +362,11 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
action.requestMethod = POST; action.requestMethod = POST;
} }
private JSONObject generateExpectedJsonForTwoDomains() { private JsonObject generateExpectedJsonForTwoDomains() {
return generateExpectedJsonForTwoDomains("cat.example", "21-EXAMPLE", "cat.lol", "C-LOL"); return generateExpectedJsonForTwoDomains("cat.example", "21-EXAMPLE", "cat.lol", "C-LOL");
} }
private JSONObject generateExpectedJsonForTwoDomains( private JsonObject generateExpectedJsonForTwoDomains(
String domain1Name, String domain1Name,
String domain1Handle, String domain1Handle,
String domain2Name, String domain2Name,
@ -380,7 +380,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
"DOMAINHANDLE2", domain2Handle); "DOMAINHANDLE2", domain2Handle);
} }
private JSONObject generateExpectedJsonForFourDomains( private JsonObject generateExpectedJsonForFourDomains(
String domain1Name, String domain1Name,
String domain1Handle, String domain1Handle,
String domain2Name, String domain2Name,
@ -403,7 +403,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
expectedOutputFile); expectedOutputFile);
} }
private JSONObject generateExpectedJsonForFourDomains( private JsonObject generateExpectedJsonForFourDomains(
String domain1Name, String domain1Name,
String domain1Handle, String domain1Handle,
String domain2Name, String domain2Name,
@ -432,7 +432,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
"NEXT_QUERY", nextQuery); "NEXT_QUERY", nextQuery);
} }
private JSONObject generateExpectedJson( private JsonObject generateExpectedJson(
String name, String name,
String punycodeName, String punycodeName,
String handle, String handle,
@ -468,7 +468,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
return loadJsonFile(expectedOutputFile, substitutionsBuilder.build()); return loadJsonFile(expectedOutputFile, substitutionsBuilder.build());
} }
private JSONObject generateExpectedJsonForDomain( private JsonObject generateExpectedJsonForDomain(
String name, String name,
String punycodeName, String punycodeName,
String handle, String handle,
@ -476,7 +476,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
@Nullable List<String> nameservers, @Nullable List<String> nameservers,
@Nullable String registrarName, @Nullable String registrarName,
String expectedOutputFile) { String expectedOutputFile) {
JSONObject obj = JsonObject obj =
generateExpectedJson( generateExpectedJson(
name, name,
punycodeName, punycodeName,
@ -485,13 +485,9 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
nameservers, nameservers,
registrarName, registrarName,
expectedOutputFile); expectedOutputFile);
obj.remove("rdapConformance"); obj = RdapTestHelper.wrapInSearchReply("domainSearchResults", obj);
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>(); RdapTestHelper.addDomainBoilerplateNotices(obj, "https://example.tld/rdap/");
builder.put("domainSearchResults", ImmutableList.of(obj)); return obj;
builder.put("rdapConformance", ImmutableList.of("icann_rdap_response_profile_0"));
RdapTestHelper.addDomainBoilerplateNotices(
builder, RdapTestHelper.createNotices("https://example.tld/rdap/"));
return new JSONObject(builder.build());
} }
private void deleteCatLol() { private void deleteCatLol() {
@ -549,7 +545,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
persistResources(domainsBuilder.build()); persistResources(domainsBuilder.build());
} }
private JSONObject readMultiDomainFile( private JsonObject readMultiDomainFile(
String fileName, String fileName,
String domainName1, String domainName1,
String domainHandle1, String domainHandle1,
@ -572,7 +568,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
"none"); "none");
} }
private JSONObject readMultiDomainFile( private JsonObject readMultiDomainFile(
String fileName, String fileName,
String domainName1, String domainName1,
String domainHandle1, String domainHandle1,
@ -596,13 +592,8 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
"NEXT_QUERY", nextQuery); "NEXT_QUERY", nextQuery);
} }
private void checkNumberOfDomainsInResult(JSONObject obj, int expected) { private void checkNumberOfDomainsInResult(JsonObject obj, int expected) {
assertThat(obj).isInstanceOf(Map.class); assertThat(obj.getAsJsonArray("domainSearchResults")).hasSize(expected);
@SuppressWarnings("unchecked")
List<Object> domains = (List<Object>) obj.get("domainSearchResults");
assertThat(domains).hasSize(expected);
} }
private void runSuccessfulTestWithCatLol( private void runSuccessfulTestWithCatLol(
@ -784,7 +775,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
int expectedPageCount = int expectedPageCount =
(expectedNames.size() + action.rdapResultSetMaxSize - 1) / action.rdapResultSetMaxSize; (expectedNames.size() + action.rdapResultSetMaxSize - 1) / action.rdapResultSetMaxSize;
for (int pageNum = 0; pageNum < expectedPageCount; pageNum++) { for (int pageNum = 0; pageNum < expectedPageCount; pageNum++) {
JSONObject results = generateActualJson(requestType, paramValue, cursor); JsonObject results = generateActualJson(requestType, paramValue, cursor);
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
String linkToNext = RdapTestHelper.getLinkToNext(results); String linkToNext = RdapTestHelper.getLinkToNext(results);
if (pageNum == expectedPageCount - 1) { if (pageNum == expectedPageCount - 1) {
@ -794,15 +785,11 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
int pos = linkToNext.indexOf("cursor="); int pos = linkToNext.indexOf("cursor=");
assertThat(pos).isAtLeast(0); assertThat(pos).isAtLeast(0);
cursor = URLDecoder.decode(linkToNext.substring(pos + 7), "UTF-8"); cursor = URLDecoder.decode(linkToNext.substring(pos + 7), "UTF-8");
Object searchResults = results.get("domainSearchResults"); JsonArray searchResults = results.getAsJsonArray("domainSearchResults");
assertThat(searchResults).isInstanceOf(JSONArray.class); assertThat(searchResults).hasSize(action.rdapResultSetMaxSize);
assertThat(((JSONArray) searchResults)).hasSize(action.rdapResultSetMaxSize); for (JsonElement item : searchResults) {
for (Object item : ((JSONArray) searchResults)) { assertThat(item.getAsJsonObject().get("ldhName").getAsString())
assertThat(item).isInstanceOf(JSONObject.class); .isEqualTo(expectedNames.get(expectedNameOffset++));
Object name = ((JSONObject) item).get("ldhName");
assertThat(name).isNotNull();
assertThat(name).isInstanceOf(String.class);
assertThat(name).isEqualTo(expectedNames.get(expectedNameOffset++));
} }
response = new FakeResponse(); response = new FakeResponse();
action.response = response; action.response = response;
@ -1209,7 +1196,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
// There are enough domains to fill a full result set; deleted domains are ignored. // There are enough domains to fill a full result set; deleted domains are ignored.
createManyDomainsAndHosts(4, 4, 2); createManyDomainsAndHosts(4, 4, 2);
rememberWildcardType("domain*.lol"); rememberWildcardType("domain*.lol");
JSONObject obj = generateActualJson(RequestType.NAME, "domain*.lol"); JsonObject obj = generateActualJson(RequestType.NAME, "domain*.lol");
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
checkNumberOfDomainsInResult(obj, 4); checkNumberOfDomainsInResult(obj, 4);
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(16L)); verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(16L));
@ -1220,7 +1207,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
// There are not enough domains to fill a full result set. // There are not enough domains to fill a full result set.
createManyDomainsAndHosts(3, 20, 2); createManyDomainsAndHosts(3, 20, 2);
rememberWildcardType("domain*.lol"); rememberWildcardType("domain*.lol");
JSONObject obj = generateActualJson(RequestType.NAME, "domain*.lol"); JsonObject obj = generateActualJson(RequestType.NAME, "domain*.lol");
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
checkNumberOfDomainsInResult(obj, 3); checkNumberOfDomainsInResult(obj, 3);
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(60L)); verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(60L));
@ -1665,7 +1652,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
// each one references the nameserver. // each one references the nameserver.
createManyDomainsAndHosts(3, 1, 40); createManyDomainsAndHosts(3, 1, 40);
rememberWildcardType("ns1.domain1.lol"); rememberWildcardType("ns1.domain1.lol");
JSONObject obj = generateActualJson(RequestType.NS_LDH_NAME, "ns1.domain1.lol"); JsonObject obj = generateActualJson(RequestType.NS_LDH_NAME, "ns1.domain1.lol");
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
checkNumberOfDomainsInResult(obj, 3); checkNumberOfDomainsInResult(obj, 3);
verifyMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(3L), Optional.of(1L)); verifyMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(3L), Optional.of(1L));
@ -1676,7 +1663,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
// Same as above, except with a wildcard (that still only finds one nameserver). // Same as above, except with a wildcard (that still only finds one nameserver).
createManyDomainsAndHosts(3, 1, 40); createManyDomainsAndHosts(3, 1, 40);
rememberWildcardType("ns1.domain1.l*"); rememberWildcardType("ns1.domain1.l*");
JSONObject obj = generateActualJson(RequestType.NS_LDH_NAME, "ns1.domain1.l*"); JsonObject obj = generateActualJson(RequestType.NS_LDH_NAME, "ns1.domain1.l*");
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
checkNumberOfDomainsInResult(obj, 3); checkNumberOfDomainsInResult(obj, 3);
verifyMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(3L), Optional.of(1L)); verifyMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(3L), Optional.of(1L));
@ -1690,7 +1677,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
// have more than that number of nameservers for an effective test. // have more than that number of nameservers for an effective test.
createManyDomainsAndHosts(3, 1, 39); createManyDomainsAndHosts(3, 1, 39);
rememberWildcardType("ns*.domain1.lol"); rememberWildcardType("ns*.domain1.lol");
JSONObject obj = generateActualJson(RequestType.NS_LDH_NAME, "ns*.domain1.lol"); JsonObject obj = generateActualJson(RequestType.NS_LDH_NAME, "ns*.domain1.lol");
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
checkNumberOfDomainsInResult(obj, 3); checkNumberOfDomainsInResult(obj, 3);
verifyMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(3L), Optional.of(39L)); verifyMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(3L), Optional.of(39L));

View file

@ -27,8 +27,7 @@ import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrarCo
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.gson.JsonObject;
import com.google.common.collect.ImmutableSet;
import google.registry.model.contact.ContactResource; import google.registry.model.contact.ContactResource;
import google.registry.model.host.HostResource; import google.registry.model.host.HostResource;
import google.registry.model.registrar.Registrar; import google.registry.model.registrar.Registrar;
@ -37,10 +36,8 @@ import google.registry.rdap.RdapMetrics.SearchType;
import google.registry.rdap.RdapMetrics.WildcardType; import google.registry.rdap.RdapMetrics.WildcardType;
import google.registry.rdap.RdapSearchResults.IncompletenessWarningType; import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
import google.registry.request.Action; import google.registry.request.Action;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.json.simple.JSONObject;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -131,7 +128,7 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
clock.nowUtc().minusMonths(6)); clock.nowUtc().minusMonths(6));
} }
private Object generateExpectedJson( private JsonObject generateExpectedJson(
String handle, String handle,
String fullName, String fullName,
String status, String status,
@ -147,29 +144,21 @@ public class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityActio
"STATUS", status); "STATUS", status);
} }
private Object generateExpectedJsonWithTopLevelEntries( private JsonObject generateExpectedJsonWithTopLevelEntries(
String handle, String handle,
String expectedOutputFile) { String expectedOutputFile) {
return generateExpectedJsonWithTopLevelEntries( return generateExpectedJsonWithTopLevelEntries(
handle, "(◕‿◕)", "active", null, expectedOutputFile); handle, "(◕‿◕)", "active", null, expectedOutputFile);
} }
private Object generateExpectedJsonWithTopLevelEntries( private JsonObject generateExpectedJsonWithTopLevelEntries(
String handle, String handle,
String fullName, String fullName,
String status, String status,
String address, String address,
String expectedOutputFile) { String expectedOutputFile) {
Object obj = generateExpectedJson(handle, fullName, status, address, expectedOutputFile); JsonObject obj = generateExpectedJson(handle, fullName, status, address, expectedOutputFile);
if (obj instanceof Map) { RdapTestHelper.addNonDomainBoilerplateNotices(obj, "https://example.tld/rdap/");
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) obj;
ImmutableMap.Builder<String, Object> builder =
RdapTestHelper.getBuilderExcluding(map, ImmutableSet.of("notices"));
RdapTestHelper.addNonDomainBoilerplateNotices(
builder, RdapTestHelper.createNotices("https://example.tld/rdap/", map.get("notices")));
obj = new JSONObject(builder.build());
}
return obj; return obj;
} }

View file

@ -30,6 +30,9 @@ import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrarCo
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import google.registry.model.contact.ContactResource; import google.registry.model.contact.ContactResource;
import google.registry.model.registrar.Registrar; import google.registry.model.registrar.Registrar;
@ -39,13 +42,8 @@ import google.registry.rdap.RdapMetrics.SearchType;
import google.registry.rdap.RdapSearchResults.IncompletenessWarningType; import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
import google.registry.testing.FakeResponse; import google.registry.testing.FakeResponse;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.List;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -68,11 +66,11 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
private Registrar registrarInactive; private Registrar registrarInactive;
private Registrar registrarTest; private Registrar registrarTest;
private JSONObject generateActualJsonWithFullName(String fn) { private JsonObject generateActualJsonWithFullName(String fn) {
return generateActualJsonWithFullName(fn, null); return generateActualJsonWithFullName(fn, null);
} }
private JSONObject generateActualJsonWithFullName(String fn, String cursor) { private JsonObject generateActualJsonWithFullName(String fn, String cursor) {
metricSearchType = SearchType.BY_FULL_NAME; metricSearchType = SearchType.BY_FULL_NAME;
action.fnParam = Optional.of(fn); action.fnParam = Optional.of(fn);
if (cursor == null) { if (cursor == null) {
@ -83,14 +81,14 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
action.cursorTokenParam = Optional.of(cursor); action.cursorTokenParam = Optional.of(cursor);
} }
action.run(); action.run();
return (JSONObject) JSONValue.parse(response.getPayload()); return parseJsonObject(response.getPayload());
} }
private JSONObject generateActualJsonWithHandle(String handle) { private JsonObject generateActualJsonWithHandle(String handle) {
return generateActualJsonWithHandle(handle, null); return generateActualJsonWithHandle(handle, null);
} }
private JSONObject generateActualJsonWithHandle(String handle, String cursor) { private JsonObject generateActualJsonWithHandle(String handle, String cursor) {
metricSearchType = SearchType.BY_HANDLE; metricSearchType = SearchType.BY_HANDLE;
action.handleParam = Optional.of(handle); action.handleParam = Optional.of(handle);
if (cursor == null) { if (cursor == null) {
@ -101,7 +99,7 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
action.cursorTokenParam = Optional.of(cursor); action.cursorTokenParam = Optional.of(cursor);
} }
action.run(); action.run();
return (JSONObject) JSONValue.parse(response.getPayload()); return parseJsonObject(response.getPayload());
} }
@Before @Before
@ -156,17 +154,17 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
action.subtypeParam = Optional.empty(); action.subtypeParam = Optional.empty();
} }
private JSONObject generateExpectedJson(String expectedOutputFile) { private JsonObject generateExpectedJson(String expectedOutputFile) {
return loadJsonFile(expectedOutputFile, "TYPE", "entity"); return loadJsonFile(expectedOutputFile, "TYPE", "entity");
} }
private JSONObject generateExpectedJson( private JsonObject generateExpectedJson(
String handle, String handle,
String expectedOutputFile) { String expectedOutputFile) {
return generateExpectedJson(handle, null, "active", null, null, expectedOutputFile); return generateExpectedJson(handle, null, "active", null, null, expectedOutputFile);
} }
private JSONObject generateExpectedJson( private JsonObject generateExpectedJson(
String handle, String handle,
@Nullable String fullName, @Nullable String fullName,
String status, String status,
@ -189,22 +187,18 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
return loadJsonFile(expectedOutputFile, builder.build()); return loadJsonFile(expectedOutputFile, builder.build());
} }
private JSONObject generateExpectedJsonForEntity( private JsonObject generateExpectedJsonForEntity(
String handle, String handle,
String fullName, String fullName,
String status, String status,
@Nullable String email, @Nullable String email,
@Nullable String address, @Nullable String address,
String expectedOutputFile) { String expectedOutputFile) {
JSONObject obj = JsonObject obj =
generateExpectedJson(handle, fullName, status, email, address, expectedOutputFile); generateExpectedJson(handle, fullName, status, email, address, expectedOutputFile);
obj.remove("rdapConformance"); obj = RdapTestHelper.wrapInSearchReply("entitySearchResults", obj);
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>(); RdapTestHelper.addNonDomainBoilerplateNotices(obj, "https://example.tld/rdap/");
builder.put("entitySearchResults", ImmutableList.of(obj)); return obj;
builder.put("rdapConformance", ImmutableList.of("icann_rdap_response_profile_0"));
RdapTestHelper.addNonDomainBoilerplateNotices(
builder, RdapTestHelper.createNotices("https://example.tld/rdap/"));
return new JSONObject(builder.build());
} }
private void createManyContactsAndRegistrars( private void createManyContactsAndRegistrars(
@ -275,15 +269,6 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
verifyMetrics(numContactsRetrieved); verifyMetrics(numContactsRetrieved);
} }
private void checkNumberOfEntitiesInResult(JSONObject obj, int expected) {
assertThat(obj).isInstanceOf(Map.class);
@SuppressWarnings("unchecked")
List<Object> entities = (List<Object>) obj.get("entitySearchResults");
assertThat(entities).hasSize(expected);
}
private void runSuccessfulNameTestWithBlinky(String queryString, String fileName) { private void runSuccessfulNameTestWithBlinky(String queryString, String fileName) {
runSuccessfulNameTest( runSuccessfulNameTest(
queryString, queryString,
@ -384,7 +369,7 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
int expectedPageCount = int expectedPageCount =
(expectedNames.size() + action.rdapResultSetMaxSize - 1) / action.rdapResultSetMaxSize; (expectedNames.size() + action.rdapResultSetMaxSize - 1) / action.rdapResultSetMaxSize;
for (int pageNum = 0; pageNum < expectedPageCount; pageNum++) { for (int pageNum = 0; pageNum < expectedPageCount; pageNum++) {
JSONObject results = JsonObject results =
(queryType == QueryType.FULL_NAME) (queryType == QueryType.FULL_NAME)
? generateActualJsonWithFullName(paramValue, cursor) ? generateActualJsonWithFullName(paramValue, cursor)
: generateActualJsonWithHandle(paramValue, cursor); : generateActualJsonWithHandle(paramValue, cursor);
@ -397,20 +382,14 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
int pos = linkToNext.indexOf("cursor="); int pos = linkToNext.indexOf("cursor=");
assertThat(pos).isAtLeast(0); assertThat(pos).isAtLeast(0);
cursor = URLDecoder.decode(linkToNext.substring(pos + 7), "UTF-8"); cursor = URLDecoder.decode(linkToNext.substring(pos + 7), "UTF-8");
Object searchResults = results.get("entitySearchResults"); JsonArray searchResults = results.getAsJsonArray("entitySearchResults");
assertThat(searchResults).isInstanceOf(JSONArray.class); assertThat(searchResults).hasSize(action.rdapResultSetMaxSize);
assertThat(((JSONArray) searchResults)).hasSize(action.rdapResultSetMaxSize); for (JsonElement item : searchResults) {
for (Object item : ((JSONArray) searchResults)) { JsonArray vcardArray = item.getAsJsonObject().getAsJsonArray("vcardArray");
assertThat(item).isInstanceOf(JSONObject.class); // vcardArray is an array with 2 elements, the first is just a string, the second is an
Object vcardArray = ((JSONObject) item).get("vcardArray"); // array with all the vcards, starting with a "version" (so we want the second one).
assertThat(vcardArray).isInstanceOf(JSONArray.class); JsonArray vcardFn = vcardArray.get(1).getAsJsonArray().get(1).getAsJsonArray();
Object vcardData = ((JSONArray) vcardArray).get(1); String name = vcardFn.get(3).getAsString();
assertThat(vcardData).isInstanceOf(JSONArray.class);
Object vcardFn = ((JSONArray) vcardData).get(1);
assertThat(vcardFn).isInstanceOf(JSONArray.class);
Object name = ((JSONArray) vcardFn).get(3);
assertThat(name).isNotNull();
assertThat(name).isInstanceOf(String.class);
assertThat(name).isEqualTo(expectedNames.get(expectedNameOffset++)); assertThat(name).isEqualTo(expectedNames.get(expectedNameOffset++));
} }
response = new FakeResponse(); response = new FakeResponse();
@ -430,7 +409,7 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
@Test @Test
public void testInvalidRequest_rejected() { public void testInvalidRequest_rejected() {
action.run(); action.run();
assertThat(JSONValue.parse(response.getPayload())) assertThat(parseJsonObject(response.getPayload()))
.isEqualTo( .isEqualTo(
generateExpectedJsonError( generateExpectedJsonError(
"You must specify either fn=XXXX or handle=YYYY", 400)); "You must specify either fn=XXXX or handle=YYYY", 400));
@ -1237,9 +1216,9 @@ public class RdapEntitySearchActionTest extends RdapSearchActionTestCase<RdapEnt
public void testHandleMatchMix_found_truncated() { public void testHandleMatchMix_found_truncated() {
createManyContactsAndRegistrars(30, 0, registrarTest); createManyContactsAndRegistrars(30, 0, registrarTest);
rememberWildcardType("00*"); rememberWildcardType("00*");
JSONObject obj = generateActualJsonWithHandle("00*"); JsonObject obj = generateActualJsonWithHandle("00*");
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
checkNumberOfEntitiesInResult(obj, 4); assertThat(obj.getAsJsonArray("entitySearchResults")).hasSize(4);
verifyMetrics(5, IncompletenessWarningType.TRUNCATED); verifyMetrics(5, IncompletenessWarningType.TRUNCATED);
} }

View file

@ -21,19 +21,16 @@ import static google.registry.testing.FullFieldsTestEntityHelper.makeAndPersistH
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar; import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.gson.JsonObject;
import google.registry.model.registrar.Registrar; import google.registry.model.registrar.Registrar;
import google.registry.rdap.RdapMetrics.EndpointType; import google.registry.rdap.RdapMetrics.EndpointType;
import google.registry.rdap.RdapMetrics.SearchType; import google.registry.rdap.RdapMetrics.SearchType;
import google.registry.rdap.RdapMetrics.WildcardType; import google.registry.rdap.RdapMetrics.WildcardType;
import google.registry.rdap.RdapSearchResults.IncompletenessWarningType; import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
import google.registry.request.Action; import google.registry.request.Action;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.json.simple.JSONObject;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -74,7 +71,7 @@ public class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameser
makeAndPersistHostResource("ns1.domain.external", "9.10.11.12", clock.nowUtc().minusYears(1)); makeAndPersistHostResource("ns1.domain.external", "9.10.11.12", clock.nowUtc().minusYears(1));
} }
private Object generateExpectedJson( private JsonObject generateExpectedJson(
String name, String name,
@Nullable ImmutableMap<String, String> otherSubstitutions, @Nullable ImmutableMap<String, String> otherSubstitutions,
String expectedOutputFile) { String expectedOutputFile) {
@ -96,25 +93,12 @@ public class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameser
builder.build()); builder.build());
} }
private Object generateExpectedJsonWithTopLevelEntries( private JsonObject generateExpectedJsonWithTopLevelEntries(
String name, String name,
@Nullable ImmutableMap<String, String> otherSubstitutions, @Nullable ImmutableMap<String, String> otherSubstitutions,
String expectedOutputFile) { String expectedOutputFile) {
Object obj = generateExpectedJson(name, otherSubstitutions, expectedOutputFile); JsonObject obj = generateExpectedJson(name, otherSubstitutions, expectedOutputFile);
if (obj instanceof Map) { RdapTestHelper.addNonDomainBoilerplateNotices(obj, "https://example.tld/rdap/");
@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.addNonDomainBoilerplateNotices(
builder,
RdapTestHelper.createNotices(
"https://example.tld/rdap/",
map.get("notices")));
obj = new JSONObject(builder.build());
}
return obj; return obj;
} }

View file

@ -29,8 +29,10 @@ import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrarCo
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
import google.registry.model.domain.DomainBase; import google.registry.model.domain.DomainBase;
import google.registry.model.host.HostResource; import google.registry.model.host.HostResource;
@ -42,9 +44,6 @@ import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
import google.registry.testing.FakeResponse; import google.registry.testing.FakeResponse;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.Optional; import java.util.Optional;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -63,11 +62,11 @@ public class RdapNameserverSearchActionTest
private HostResource hostNs1CatLol; private HostResource hostNs1CatLol;
private HostResource hostNs2CatLol; private HostResource hostNs2CatLol;
private JSONObject generateActualJsonWithName(String name) { private JsonObject generateActualJsonWithName(String name) {
return generateActualJsonWithName(name, null); return generateActualJsonWithName(name, null);
} }
private JSONObject generateActualJsonWithName(String name, String cursor) { private JsonObject generateActualJsonWithName(String name, String cursor) {
metricSearchType = SearchType.BY_NAMESERVER_NAME; metricSearchType = SearchType.BY_NAMESERVER_NAME;
rememberWildcardType(name); rememberWildcardType(name);
action.nameParam = Optional.of(name); action.nameParam = Optional.of(name);
@ -79,14 +78,14 @@ public class RdapNameserverSearchActionTest
action.cursorTokenParam = Optional.of(cursor); action.cursorTokenParam = Optional.of(cursor);
} }
action.run(); action.run();
return (JSONObject) JSONValue.parse(response.getPayload()); return parseJsonObject(response.getPayload());
} }
private JSONObject generateActualJsonWithIp(String ipString) { private JsonObject generateActualJsonWithIp(String ipString) {
return generateActualJsonWithIp(ipString, null); return generateActualJsonWithIp(ipString, null);
} }
private JSONObject generateActualJsonWithIp(String ipString, String cursor) { private JsonObject generateActualJsonWithIp(String ipString, String cursor) {
metricSearchType = SearchType.BY_NAMESERVER_ADDRESS; metricSearchType = SearchType.BY_NAMESERVER_ADDRESS;
action.parameterMap = ImmutableListMultimap.of("ip", ipString); action.parameterMap = ImmutableListMultimap.of("ip", ipString);
action.ipParam = Optional.of(ipString); action.ipParam = Optional.of(ipString);
@ -98,7 +97,7 @@ public class RdapNameserverSearchActionTest
action.cursorTokenParam = Optional.of(cursor); action.cursorTokenParam = Optional.of(cursor);
} }
action.run(); action.run();
return (JSONObject) JSONValue.parse(response.getPayload()); return parseJsonObject(response.getPayload());
} }
@Before @Before
@ -154,14 +153,14 @@ public class RdapNameserverSearchActionTest
action.nameParam = Optional.empty(); action.nameParam = Optional.empty();
} }
private JSONObject generateExpectedJsonForNameserver( private JsonObject generateExpectedJsonForNameserver(
String name, String name,
String punycodeName, String punycodeName,
String handle, String handle,
String ipAddressType, String ipAddressType,
String ipAddress, String ipAddress,
String expectedOutputFile) { String expectedOutputFile) {
JSONObject obj = JsonObject obj =
loadJsonFile( loadJsonFile(
expectedOutputFile, expectedOutputFile,
"NAME", name, "NAME", name,
@ -171,13 +170,9 @@ public class RdapNameserverSearchActionTest
"ADDRESS", ipAddress, "ADDRESS", ipAddress,
"STATUS", "active", "STATUS", "active",
"TYPE", "nameserver"); "TYPE", "nameserver");
obj.remove("rdapConformance"); obj = RdapTestHelper.wrapInSearchReply("nameserverSearchResults", obj);
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>(); RdapTestHelper.addNonDomainBoilerplateNotices(obj, "https://example.tld/rdap/");
builder.put("nameserverSearchResults", ImmutableList.of(obj)); return obj;
builder.put("rdapConformance", ImmutableList.of("icann_rdap_response_profile_0"));
RdapTestHelper.addNonDomainBoilerplateNotices(
builder, RdapTestHelper.createNotices("https://example.tld/rdap/"));
return new JSONObject(builder.build());
} }
private void createManyHosts(int numHosts) { private void createManyHosts(int numHosts) {
@ -246,7 +241,7 @@ public class RdapNameserverSearchActionTest
@Test @Test
public void testInvalidRequest_rejected() { public void testInvalidRequest_rejected() {
action.run(); action.run();
assertThat(JSONValue.parse(response.getPayload())) assertThat(parseJsonObject(response.getPayload()))
.isEqualTo( .isEqualTo(
generateExpectedJsonError( generateExpectedJsonError(
"You must specify either name=XXXX or ip=YYYY", "You must specify either name=XXXX or ip=YYYY",
@ -644,7 +639,7 @@ public class RdapNameserverSearchActionTest
int expectedPageCount = int expectedPageCount =
(expectedNames.size() + action.rdapResultSetMaxSize - 1) / action.rdapResultSetMaxSize; (expectedNames.size() + action.rdapResultSetMaxSize - 1) / action.rdapResultSetMaxSize;
for (int pageNum = 0; pageNum < expectedPageCount; pageNum++) { for (int pageNum = 0; pageNum < expectedPageCount; pageNum++) {
JSONObject results = JsonObject results =
byName byName
? generateActualJsonWithName(paramValue, cursor) ? generateActualJsonWithName(paramValue, cursor)
: generateActualJsonWithIp(paramValue, cursor); : generateActualJsonWithIp(paramValue, cursor);
@ -657,15 +652,11 @@ public class RdapNameserverSearchActionTest
int pos = linkToNext.indexOf("cursor="); int pos = linkToNext.indexOf("cursor=");
assertThat(pos).isAtLeast(0); assertThat(pos).isAtLeast(0);
cursor = URLDecoder.decode(linkToNext.substring(pos + 7), "UTF-8"); cursor = URLDecoder.decode(linkToNext.substring(pos + 7), "UTF-8");
Object searchResults = results.get("nameserverSearchResults"); JsonArray searchResults = results.getAsJsonArray("nameserverSearchResults");
assertThat(searchResults).isInstanceOf(JSONArray.class); assertThat(searchResults).hasSize(action.rdapResultSetMaxSize);
assertThat(((JSONArray) searchResults)).hasSize(action.rdapResultSetMaxSize); for (JsonElement item : searchResults) {
for (Object item : ((JSONArray) searchResults)) { assertThat(item.getAsJsonObject().get("ldhName").getAsString())
assertThat(item).isInstanceOf(JSONObject.class); .isEqualTo(expectedNames.get(expectedNameOffset++));
Object name = ((JSONObject) item).get("ldhName");
assertThat(name).isNotNull();
assertThat(name).isInstanceOf(String.class);
assertThat(name).isEqualTo(expectedNames.get(expectedNameOffset++));
} }
response = new FakeResponse(); response = new FakeResponse();
action.response = response; action.response = response;

View file

@ -19,15 +19,12 @@ import static com.google.common.truth.Truth.assertThat;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Streams;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import java.util.Map; import com.google.gson.JsonObject;
import java.util.Map.Entry;
import java.util.Set;
import javax.annotation.Nullable;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
public class RdapTestHelper { public class RdapTestHelper {
@ -43,26 +40,8 @@ public class RdapTestHelper {
CONTACT CONTACT
} }
static ImmutableMap.Builder<String, Object> getBuilderExcluding( private static JsonObject createTosNotice(String linkBase) {
Map<String, Object> map, Set<String> keysToExclude) { return new Gson().toJsonTree(
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
for (Entry<String, Object> entry : map.entrySet()) {
if (!keysToExclude.contains(entry.getKey())) {
builder.put(entry);
}
}
return builder;
}
static ImmutableList<ImmutableMap<String, Object>> createNotices(String linkBase) {
return createNotices(linkBase, null);
}
static ImmutableList<ImmutableMap<String, Object>> createNotices(
String linkBase, @Nullable Object otherNotices) {
ImmutableList.Builder<ImmutableMap<String, Object>> noticesBuilder =
getBuilderWithOthersAdded(otherNotices);
noticesBuilder.add(
ImmutableMap.of( ImmutableMap.of(
"title", "RDAP Terms of Service", "title", "RDAP Terms of Service",
"description", "description",
@ -94,81 +73,73 @@ public class RdapTestHelper {
"value", linkBase + "help/tos", "value", linkBase + "help/tos",
"rel", "alternate", "rel", "alternate",
"href", "https://www.registry.tld/about/rdap/tos.html", "href", "https://www.registry.tld/about/rdap/tos.html",
"type", "text/html")))); "type", "text/html")))).getAsJsonObject();
return noticesBuilder.build();
} }
static void addNonDomainBoilerplateNotices(ImmutableMap.Builder<String, Object> builder) { static void addNonDomainBoilerplateNotices(JsonObject jsonObject, String linkBase) {
addNonDomainBoilerplateNotices(builder, null); if (!jsonObject.has("notices")) {
} jsonObject.add("notices", new JsonArray());
static void addNonDomainBoilerplateNotices(
ImmutableMap.Builder<String, Object> builder, @Nullable Object otherNotices) {
ImmutableList.Builder<ImmutableMap<String, Object>> noticesBuilder =
getBuilderWithOthersAdded(otherNotices);
noticesBuilder.add(
ImmutableMap.of(
"description",
ImmutableList.of(
"This response conforms to the RDAP Operational Profile for gTLD Registries and"
+ " Registrars version 1.0")));
builder.put("notices", noticesBuilder.build());
}
static void addDomainBoilerplateNotices(ImmutableMap.Builder<String, Object> builder) {
addDomainBoilerplateNotices(builder, null);
}
static void addDomainBoilerplateNotices(
ImmutableMap.Builder<String, Object> builder, @Nullable Object otherNotices) {
ImmutableList.Builder<ImmutableMap<String, Object>> noticesBuilder =
getBuilderWithOthersAdded(otherNotices);
noticesBuilder.add(
ImmutableMap.of(
"description",
ImmutableList.of(
"This response conforms to the RDAP Operational Profile for gTLD Registries and"
+ " Registrars version 1.0")));
noticesBuilder.add(
ImmutableMap.of(
"title",
"Status Codes",
"description",
ImmutableList.of(
"For more information on domain status codes, please visit"
+ " https://icann.org/epp"),
"links",
ImmutableList.of(
ImmutableMap.of(
"value", "https://icann.org/epp",
"rel", "alternate",
"href", "https://icann.org/epp",
"type", "text/html"))));
noticesBuilder.add(
ImmutableMap.of(
"description",
ImmutableList.of(
"URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf"),
"links",
ImmutableList.of(
ImmutableMap.of(
"value", "https://www.icann.org/wicf",
"rel", "alternate",
"href", "https://www.icann.org/wicf",
"type", "text/html"))));
builder.put("notices", noticesBuilder.build());
}
private static ImmutableList.Builder<ImmutableMap<String, Object>> getBuilderWithOthersAdded(
@Nullable Object others) {
ImmutableList.Builder<ImmutableMap<String, Object>> builder = new ImmutableList.Builder<>();
if ((others != null) && (others instanceof ImmutableList<?>)) {
@SuppressWarnings("unchecked")
ImmutableList<ImmutableMap<String, Object>> othersList =
(ImmutableList<ImmutableMap<String, Object>>) others;
builder.addAll(othersList);
} }
return builder; JsonArray notices = jsonObject.getAsJsonArray("notices");
notices.add(createTosNotice(linkBase));
notices.add(
new Gson()
.toJsonTree(
ImmutableMap.of(
"description",
ImmutableList.of(
"This response conforms to the RDAP Operational Profile for gTLD"
+ " Registries and Registrars version 1.0"))));
}
static void addDomainBoilerplateNotices(JsonObject jsonObject, String linkBase) {
if (!jsonObject.has("notices")) {
jsonObject.add("notices", new JsonArray());
}
JsonArray notices = jsonObject.getAsJsonArray("notices");
notices.add(createTosNotice(linkBase));
notices.add(
new Gson()
.toJsonTree(
ImmutableMap.of(
"description",
ImmutableList.of(
"This response conforms to the RDAP Operational Profile for gTLD"
+ " Registries and Registrars version 1.0"))));
notices.add(
new Gson()
.toJsonTree(
ImmutableMap.of(
"title",
"Status Codes",
"description",
ImmutableList.of(
"For more information on domain status codes, please visit"
+ " https://icann.org/epp"),
"links",
ImmutableList.of(
ImmutableMap.of(
"value", "https://icann.org/epp",
"rel", "alternate",
"href", "https://icann.org/epp",
"type", "text/html")))));
notices.add(
new Gson()
.toJsonTree(
ImmutableMap.of(
"description",
ImmutableList.of(
"URL of the ICANN Whois Inaccuracy Complaint Form:"
+ " https://www.icann.org/wicf"),
"links",
ImmutableList.of(
ImmutableMap.of(
"value", "https://www.icann.org/wicf",
"rel", "alternate",
"href", "https://www.icann.org/wicf",
"type", "text/html")))));
} }
static RdapJsonFormatter getTestRdapJsonFormatter() { static RdapJsonFormatter getTestRdapJsonFormatter() {
@ -202,34 +173,28 @@ public class RdapTestHelper {
return rdapJsonFormatter; return rdapJsonFormatter;
} }
static String getLinkToNext(Object results) { static String getLinkToNext(JsonObject results) {
assertThat(results).isInstanceOf(JSONObject.class); JsonArray notices = results.getAsJsonArray("notices");
Object notices = ((JSONObject) results).get("notices"); assertThat(notices).isNotNull();
assertThat(notices).isInstanceOf(JSONArray.class); return Streams.stream(notices)
for (Object notice : (JSONArray) notices) { .map(notice -> notice.getAsJsonObject())
assertThat(notice).isInstanceOf(JSONObject.class); .filter(notice -> notice.has("title"))
Object title = ((JSONObject) notice).get("title"); .filter(notice -> notice.get("title").getAsString().equals("Navigation Links"))
if (title == null) { .flatMap(notice -> Streams.stream(notice.getAsJsonArray("links")))
continue; .map(link -> link.getAsJsonObject())
} .filter(link -> link.get("rel").getAsString().equals("next"))
assertThat(title).isInstanceOf(String.class); .map(link -> link.get("href").getAsString())
if (!title.equals("Navigation Links")) { .findAny().orElse(null);
continue; }
}
Object links = ((JSONObject) notice).get("links"); static JsonObject wrapInSearchReply(String searchResultsName, JsonObject obj) {
assertThat(links).isInstanceOf(JSONArray.class); JsonArray searchResults = new JsonArray();
for (Object link : (JSONArray) links) { searchResults.add(obj);
assertThat(link).isInstanceOf(JSONObject.class); JsonObject reply = new JsonObject();
Object rel = ((JSONObject) link).get("rel");
assertThat(rel).isInstanceOf(String.class); reply.add(searchResultsName, searchResults);
if (!rel.equals("next")) { reply.add("rdapConformance", obj.getAsJsonArray("rdapConformance"));
continue; obj.remove("rdapConformance");
} return reply;
Object href = ((JSONObject) link).get("href");
assertThat(href).isInstanceOf(String.class);
return (String) href;
}
}
return null;
} }
} }

View file

@ -96,7 +96,7 @@
], ],
"ipAddresses" : "ipAddresses" :
{ {
"v4" : ["1.2.3.3"] "v4" : ["1.2.3.3"],
"v6" : ["bad:f00d:cafe::15:beef"] "v6" : ["bad:f00d:cafe::15:beef"]
}, },
"remarks": [ "remarks": [

View file

@ -43,7 +43,7 @@
[ [
"", "",
"", "",
"123 Example Boulevard <script>" "123 Example Boulevard <script>",
"Williamsburg <script>", "Williamsburg <script>",
"NY", "NY",
"11211", "11211",
@ -71,7 +71,7 @@
["tel", {"type" : ["fax"]}, "uri", "tel:+1.2125551216"], ["tel", {"type" : ["fax"]}, "uri", "tel:+1.2125551216"],
["email", {}, "text", "jakedoe@example.com"] ["email", {}, "text", "jakedoe@example.com"]
] ]
], ]
}, },
{ {
"objectClassName" : "entity", "objectClassName" : "entity",
@ -87,7 +87,7 @@
["tel", {"type" : ["fax"]}, "uri", "tel:+1.2125551216"], ["tel", {"type" : ["fax"]}, "uri", "tel:+1.2125551216"],
["email", {}, "text", "janedoe@example.com"] ["email", {}, "text", "janedoe@example.com"]
] ]
], ]
}, },
{ {
"objectClassName" : "entity", "objectClassName" : "entity",
@ -103,7 +103,7 @@
["tel", {"type" : ["fax"]}, "uri", "tel:+1.2125551213"], ["tel", {"type" : ["fax"]}, "uri", "tel:+1.2125551213"],
["email", {}, "text", "johndoe@example.com"] ["email", {}, "text", "johndoe@example.com"]
] ]
], ]
} }
] ]
} }

View file

@ -27,7 +27,7 @@
[ [
"", "",
"", "",
"123 Example Boulevard <script>" "123 Example Boulevard <script>",
"Williamsburg <script>", "Williamsburg <script>",
"NY", "NY",
"11211", "11211",
@ -55,7 +55,7 @@
["tel", {"type" : ["fax"]}, "uri", "tel:+1.2125551216"], ["tel", {"type" : ["fax"]}, "uri", "tel:+1.2125551216"],
["email", {}, "text", "jakedoe@example.com"] ["email", {}, "text", "jakedoe@example.com"]
] ]
], ]
}, },
{ {
"objectClassName" : "entity", "objectClassName" : "entity",
@ -71,7 +71,7 @@
["tel", {"type" : ["fax"]}, "uri", "tel:+1.2125551216"], ["tel", {"type" : ["fax"]}, "uri", "tel:+1.2125551216"],
["email", {}, "text", "janedoe@example.com"] ["email", {}, "text", "janedoe@example.com"]
] ]
], ]
}, },
{ {
"objectClassName" : "entity", "objectClassName" : "entity",
@ -87,7 +87,7 @@
["tel", {"type" : ["fax"]}, "uri", "tel:+1.2125551213"], ["tel", {"type" : ["fax"]}, "uri", "tel:+1.2125551213"],
["email", {}, "text", "johndoe@example.com"] ["email", {}, "text", "johndoe@example.com"]
] ]
], ]
} }
] ]
} }

View file

@ -207,7 +207,7 @@
"rel" : "next" "rel" : "next"
} }
], ],
"description" : [ "Links to related pages." ], "description" : [ "Links to related pages." ]
}, },
{ {
"title" : "RDAP Terms of Service", "title" : "RDAP Terms of Service",

View file

@ -214,7 +214,7 @@
"rel" : "next" "rel" : "next"
} }
], ],
"description" : [ "Links to related pages." ], "description" : [ "Links to related pages." ]
}, },
{ {
"title" : "RDAP Terms of Service", "title" : "RDAP Terms of Service",

View file

@ -235,7 +235,7 @@
"rel" : "next" "rel" : "next"
} }
], ],
"description" : [ "Links to related pages." ], "description" : [ "Links to related pages." ]
}, },
{ {
"title" : "RDAP Terms of Service", "title" : "RDAP Terms of Service",