Conform to RDAP Response Profile 15feb19

This is only about the Response Profile, not the Technical Implementation guide.

The Response Profile can be found at https://www.icann.org/en/system/files/files/rdap-response-profile-15feb19-en.pdf

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=250277559
This commit is contained in:
guyben 2019-05-28 07:36:33 -07:00 committed by jianglai
parent b34a828b71
commit c79e0ea670
89 changed files with 4102 additions and 5815 deletions

View file

@ -14,22 +14,27 @@
package google.registry.rdap;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.testing.TestDataHelper.loadFile;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import com.google.common.collect.Streams;
import com.google.common.truth.Truth;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import google.registry.util.Clock;
import java.util.Map;
import java.util.Objects;
public class RdapTestHelper {
private static final Gson GSON = new GsonBuilder().create();
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
static JsonElement createJson(String... lines) {
return GSON.fromJson(Joiner.on("\n").join(lines), JsonElement.class);
@ -130,9 +135,11 @@ public class RdapTestHelper {
new Gson()
.toJsonTree(
ImmutableMap.of(
"title",
"RDDS Inaccuracy Complaint Form",
"description",
ImmutableList.of(
"URL of the ICANN Whois Inaccuracy Complaint Form:"
"URL of the ICANN RDDS Inaccuracy Complaint Form:"
+ " https://www.icann.org/wicf"),
"links",
ImmutableList.of(
@ -177,7 +184,7 @@ public class RdapTestHelper {
static String getLinkToNext(JsonObject results) {
JsonArray notices = results.getAsJsonArray("notices");
assertThat(notices).isNotNull();
Truth.assertThat(notices).isNotNull();
return Streams.stream(notices)
.map(notice -> notice.getAsJsonObject())
.filter(notice -> notice.has("title"))
@ -189,6 +196,43 @@ public class RdapTestHelper {
.findAny().orElse(null);
}
/**
* 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.
*/
static 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.
*/
static JsonObject loadJsonFile(String filename, Map<String, String> substitutions) {
System.out.format("Loading JSON file: %s\n", filename);
return parseJsonObject(loadFile(RdapTestHelper.class, filename, substitutions));
}
static JsonObject parseJsonObject(String jsonString) {
return GSON.fromJson(jsonString, JsonObject.class);
}
static JsonObject wrapInSearchReply(String searchResultsName, JsonObject obj) {
JsonArray searchResults = new JsonArray();
searchResults.add(obj);
@ -199,4 +243,83 @@ public class RdapTestHelper {
obj.remove("rdapConformance");
return reply;
}
/** A small utility class to show nicer "huge JSON" diffs. */
static final class GsonSubject {
private JsonObject actual;
GsonSubject(JsonObject actual) {
this.actual = actual;
}
void isEqualTo(JsonObject expected) {
if (actual.equals(expected)) {
return;
}
StringBuilder difference = new StringBuilder();
difference.append("Actual JSON different than expected:");
diff("", actual, expected, difference);
throw new AssertionError(difference.toString());
}
private String jsonifyAndIndent(JsonElement element) {
String json = GSON.toJson(element);
return json.replaceAll("\n", "\n ");
}
private JsonElement getOrNull(JsonArray jsonArray, int index) {
if (index >= jsonArray.size()) {
return null;
}
return jsonArray.get(index);
}
/** Writes down a human-readable diff between actual and expected into the StringBuilder. */
private void diff(
String name, JsonElement actual, JsonElement expected, StringBuilder builder) {
if (Objects.equals(actual, expected)) {
return;
}
if (actual == null) {
builder.append(String.format("Missing: %s ->%s\n\n", name, jsonifyAndIndent(expected)));
return;
}
if (expected == null) {
builder.append(String.format("Unexpected: %s -> %s\n\n", name, jsonifyAndIndent(actual)));
return;
}
if (actual.isJsonObject() && expected.isJsonObject()) {
// We put the "expected" first in the union so that the "expected" keys will all be first
// and in order
for (String key :
Sets.union(expected.getAsJsonObject().keySet(), actual.getAsJsonObject().keySet())) {
diff(
name + "." + key,
actual.getAsJsonObject().get(key),
expected.getAsJsonObject().get(key),
builder);
}
return;
}
if (actual.isJsonArray() && expected.isJsonArray()) {
int commonSize = Math.max(actual.getAsJsonArray().size(), expected.getAsJsonArray().size());
for (int i = 0; i < commonSize; i++) {
diff(
String.format("%s[%s]", name, i),
getOrNull(actual.getAsJsonArray(), i),
getOrNull(expected.getAsJsonArray(), i),
builder);
}
return;
}
builder.append(
String.format(
"Different: %s -> %s\ninstead of %s\n\n",
name, jsonifyAndIndent(actual), jsonifyAndIndent(expected)));
}
}
static GsonSubject assertThat(JsonObject actual) {
return new GsonSubject(actual);
}
}