mirror of
https://github.com/google/nomulus.git
synced 2025-05-01 12:37:52 +02:00
Overriding getter methods to change values is a bit overkill when these values are static (don't change based on internal state). Just setting them in the base class' constructor is simpler. Also, we can read the PATH of an Action based on the Annotation instead returning it manually for each Action. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=246135754
2027 lines
74 KiB
Java
2027 lines
74 KiB
Java
// Copyright 2017 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.base.Preconditions.checkNotNull;
|
|
import static com.google.common.truth.Truth.assertThat;
|
|
import static google.registry.request.Action.Method.POST;
|
|
import static google.registry.testing.DatastoreHelper.createTld;
|
|
import static google.registry.testing.DatastoreHelper.persistDomainAsDeleted;
|
|
import static google.registry.testing.DatastoreHelper.persistResource;
|
|
import static google.registry.testing.DatastoreHelper.persistResources;
|
|
import static google.registry.testing.DatastoreHelper.persistSimpleResources;
|
|
import static google.registry.testing.FullFieldsTestEntityHelper.makeAndPersistContactResource;
|
|
import static google.registry.testing.FullFieldsTestEntityHelper.makeAndPersistHostResource;
|
|
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;
|
|
import com.google.common.collect.ImmutableMap;
|
|
import com.google.common.collect.ImmutableSet;
|
|
import com.google.common.collect.Range;
|
|
import com.google.common.net.InetAddresses;
|
|
import com.googlecode.objectify.Key;
|
|
import google.registry.model.contact.ContactResource;
|
|
import google.registry.model.domain.DomainBase;
|
|
import google.registry.model.domain.Period;
|
|
import google.registry.model.host.HostResource;
|
|
import google.registry.model.registrar.Registrar;
|
|
import google.registry.model.registry.Registry;
|
|
import google.registry.model.reporting.HistoryEntry;
|
|
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.testing.FakeResponse;
|
|
import google.registry.util.Idn;
|
|
import java.net.IDN;
|
|
import java.net.URLDecoder;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Optional;
|
|
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.Ignore;
|
|
import org.junit.Test;
|
|
import org.junit.runner.RunWith;
|
|
import org.junit.runners.JUnit4;
|
|
|
|
/** Unit tests for {@link RdapDomainSearchAction}. */
|
|
@RunWith(JUnit4.class)
|
|
public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSearchAction> {
|
|
|
|
public RdapDomainSearchActionTest() {
|
|
super(RdapDomainSearchAction.class);
|
|
}
|
|
|
|
private Registrar registrar;
|
|
private DomainBase domainCatLol;
|
|
private DomainBase domainCatLol2;
|
|
private DomainBase domainCatExample;
|
|
private DomainBase domainIdn;
|
|
private DomainBase domainMultipart;
|
|
private ContactResource contact1;
|
|
private ContactResource contact2;
|
|
private ContactResource contact3;
|
|
private HostResource hostNs1CatLol;
|
|
private HostResource hostNs2CatLol;
|
|
private HistoryEntry historyEntryCatLolCreate;
|
|
private Map<String, HostResource> hostNameToHostMap = new HashMap<>();
|
|
|
|
enum RequestType { NONE, NAME, NS_LDH_NAME, NS_IP }
|
|
|
|
private Object generateActualJson(RequestType requestType, String paramValue) {
|
|
return generateActualJson(requestType, paramValue, null);
|
|
}
|
|
|
|
private Object generateActualJson(
|
|
RequestType requestType, String paramValue, String cursor) {
|
|
action.requestPath = actionPath;
|
|
action.requestMethod = POST;
|
|
String requestTypeParam = null;
|
|
switch (requestType) {
|
|
case NAME:
|
|
action.nameParam = Optional.of(paramValue);
|
|
action.nsLdhNameParam = Optional.empty();
|
|
action.nsIpParam = Optional.empty();
|
|
requestTypeParam = "name";
|
|
break;
|
|
case NS_LDH_NAME:
|
|
action.nameParam = Optional.empty();
|
|
action.nsLdhNameParam = Optional.of(paramValue);
|
|
action.nsIpParam = Optional.empty();
|
|
requestTypeParam = "nsLdhName";
|
|
break;
|
|
case NS_IP:
|
|
action.nameParam = Optional.empty();
|
|
action.nsLdhNameParam = Optional.empty();
|
|
action.nsIpParam = Optional.of(paramValue);
|
|
requestTypeParam = "nsIp";
|
|
break;
|
|
default:
|
|
action.nameParam = Optional.empty();
|
|
action.nsLdhNameParam = Optional.empty();
|
|
action.nsIpParam = Optional.empty();
|
|
requestTypeParam = "";
|
|
break;
|
|
}
|
|
if (paramValue != null) {
|
|
if (cursor == null) {
|
|
action.parameterMap = ImmutableListMultimap.of(requestTypeParam, paramValue);
|
|
action.cursorTokenParam = Optional.empty();
|
|
} else {
|
|
action.parameterMap =
|
|
ImmutableListMultimap.of(requestTypeParam, paramValue, "cursor", cursor);
|
|
action.cursorTokenParam = Optional.of(cursor);
|
|
}
|
|
}
|
|
action.run();
|
|
return JSONValue.parse(response.getPayload());
|
|
}
|
|
|
|
private HostResource addHostToMap(HostResource host) {
|
|
hostNameToHostMap.put(host.getFullyQualifiedHostName(), host);
|
|
return host;
|
|
}
|
|
|
|
@Before
|
|
public void setUp() {
|
|
RdapDomainSearchAction.maxNameserversInFirstStage = 40;
|
|
|
|
// cat.lol and cat2.lol
|
|
createTld("lol");
|
|
registrar = persistResource(
|
|
makeRegistrar("evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE));
|
|
persistSimpleResources(makeRegistrarContacts(registrar));
|
|
domainCatLol = persistResource(
|
|
makeDomainBase(
|
|
"cat.lol",
|
|
contact1 = makeAndPersistContactResource(
|
|
"5372808-ERL",
|
|
"Goblin Market",
|
|
"lol@cat.lol",
|
|
clock.nowUtc().minusYears(1),
|
|
registrar),
|
|
contact2 = makeAndPersistContactResource(
|
|
"5372808-IRL",
|
|
"Santa Claus",
|
|
"BOFH@cat.lol",
|
|
clock.nowUtc().minusYears(2),
|
|
registrar),
|
|
contact3 = makeAndPersistContactResource(
|
|
"5372808-TRL",
|
|
"The Raven",
|
|
"bog@cat.lol",
|
|
clock.nowUtc().minusYears(3),
|
|
registrar),
|
|
hostNs1CatLol = addHostToMap(makeAndPersistHostResource(
|
|
"ns1.cat.lol",
|
|
"1.2.3.4",
|
|
clock.nowUtc().minusYears(1))),
|
|
hostNs2CatLol = addHostToMap(makeAndPersistHostResource(
|
|
"ns2.cat.lol",
|
|
"bad:f00d:cafe:0:0:0:15:beef",
|
|
clock.nowUtc().minusYears(2))),
|
|
registrar)
|
|
.asBuilder()
|
|
.setSubordinateHosts(ImmutableSet.of("ns1.cat.lol", "ns2.cat.lol"))
|
|
.setCreationTimeForTest(clock.nowUtc().minusYears(3))
|
|
.build());
|
|
persistResource(
|
|
hostNs1CatLol.asBuilder().setSuperordinateDomain(Key.create(domainCatLol)).build());
|
|
persistResource(
|
|
hostNs2CatLol.asBuilder().setSuperordinateDomain(Key.create(domainCatLol)).build());
|
|
domainCatLol2 = persistResource(
|
|
makeDomainBase(
|
|
"cat2.lol",
|
|
makeAndPersistContactResource(
|
|
"6372808-ERL",
|
|
"Siegmund",
|
|
"siegmund@cat2.lol",
|
|
clock.nowUtc().minusYears(1),
|
|
registrar),
|
|
makeAndPersistContactResource(
|
|
"6372808-IRL",
|
|
"Sieglinde",
|
|
"sieglinde@cat2.lol",
|
|
clock.nowUtc().minusYears(2),
|
|
registrar),
|
|
makeAndPersistContactResource(
|
|
"6372808-TRL",
|
|
"Siegfried",
|
|
"siegfried@cat2.lol",
|
|
clock.nowUtc().minusYears(3),
|
|
registrar),
|
|
addHostToMap(makeAndPersistHostResource(
|
|
"ns1.cat.example", "10.20.30.40", clock.nowUtc().minusYears(1))),
|
|
addHostToMap(makeAndPersistHostResource(
|
|
"ns2.dog.lol", "12:feed:5000:0:0:0:15:beef", clock.nowUtc().minusYears(2))),
|
|
registrar)
|
|
.asBuilder()
|
|
.setCreationTimeForTest(clock.nowUtc().minusYears(3))
|
|
.build());
|
|
// cat.example
|
|
createTld("example");
|
|
registrar = persistResource(
|
|
makeRegistrar("goodregistrar", "St. John Chrysostom", Registrar.State.ACTIVE));
|
|
persistSimpleResources(makeRegistrarContacts(registrar));
|
|
domainCatExample = persistResource(
|
|
makeDomainBase(
|
|
"cat.example",
|
|
makeAndPersistContactResource(
|
|
"7372808-ERL",
|
|
"Matthew",
|
|
"lol@cat.lol",
|
|
clock.nowUtc().minusYears(1),
|
|
registrar),
|
|
makeAndPersistContactResource(
|
|
"7372808-IRL",
|
|
"Mark",
|
|
"BOFH@cat.lol",
|
|
clock.nowUtc().minusYears(2),
|
|
registrar),
|
|
makeAndPersistContactResource(
|
|
"7372808-TRL",
|
|
"Luke",
|
|
"bog@cat.lol",
|
|
clock.nowUtc().minusYears(3),
|
|
registrar),
|
|
hostNs1CatLol,
|
|
addHostToMap(makeAndPersistHostResource(
|
|
"ns2.external.tld", "bad:f00d:cafe:0:0:0:16:beef", clock.nowUtc().minusYears(2))),
|
|
registrar)
|
|
.asBuilder()
|
|
.setCreationTimeForTest(clock.nowUtc().minusYears(3))
|
|
.build());
|
|
// cat.みんな
|
|
createTld("xn--q9jyb4c");
|
|
registrar = persistResource(makeRegistrar("unicoderegistrar", "みんな", Registrar.State.ACTIVE));
|
|
persistSimpleResources(makeRegistrarContacts(registrar));
|
|
domainIdn = persistResource(
|
|
makeDomainBase(
|
|
"cat.みんな",
|
|
makeAndPersistContactResource(
|
|
"8372808-ERL",
|
|
"(◕‿◕)",
|
|
"lol@cat.みんな",
|
|
clock.nowUtc().minusYears(1),
|
|
registrar),
|
|
makeAndPersistContactResource(
|
|
"8372808-IRL",
|
|
"Santa Claus",
|
|
"BOFH@cat.みんな",
|
|
clock.nowUtc().minusYears(2),
|
|
registrar),
|
|
makeAndPersistContactResource(
|
|
"8372808-TRL",
|
|
"The Raven",
|
|
"bog@cat.みんな",
|
|
clock.nowUtc().minusYears(3),
|
|
registrar),
|
|
addHostToMap(makeAndPersistHostResource(
|
|
"ns1.cat.みんな", "1.2.3.5", clock.nowUtc().minusYears(1))),
|
|
addHostToMap(makeAndPersistHostResource(
|
|
"ns2.cat.みんな", "bad:f00d:cafe:0:0:0:14:beef", clock.nowUtc().minusYears(2))),
|
|
registrar)
|
|
.asBuilder()
|
|
.setCreationTimeForTest(clock.nowUtc().minusYears(3))
|
|
.build());
|
|
// cat.1.test
|
|
createTld("1.test");
|
|
registrar =
|
|
persistResource(makeRegistrar("multiregistrar", "1.test", Registrar.State.ACTIVE));
|
|
persistSimpleResources(makeRegistrarContacts(registrar));
|
|
domainMultipart = persistResource(makeDomainBase(
|
|
"cat.1.test",
|
|
makeAndPersistContactResource(
|
|
"9372808-ERL",
|
|
"(◕‿◕)",
|
|
"lol@cat.みんな",
|
|
clock.nowUtc().minusYears(1),
|
|
registrar),
|
|
makeAndPersistContactResource(
|
|
"9372808-IRL",
|
|
"Santa Claus",
|
|
"BOFH@cat.みんな",
|
|
clock.nowUtc().minusYears(2),
|
|
registrar),
|
|
makeAndPersistContactResource(
|
|
"9372808-TRL",
|
|
"The Raven",
|
|
"bog@cat.みんな",
|
|
clock.nowUtc().minusYears(3),
|
|
registrar),
|
|
addHostToMap(makeAndPersistHostResource(
|
|
"ns1.cat.1.test", "1.2.3.5", clock.nowUtc().minusYears(1))),
|
|
addHostToMap(makeAndPersistHostResource(
|
|
"ns2.cat.2.test", "bad:f00d:cafe:0:0:0:14:beef", clock.nowUtc().minusYears(2))),
|
|
registrar)
|
|
.asBuilder()
|
|
.setSubordinateHosts(ImmutableSet.of("ns1.cat.1.test"))
|
|
.setCreationTimeForTest(clock.nowUtc().minusYears(3))
|
|
.build());
|
|
|
|
persistResource(makeRegistrar("otherregistrar", "other", Registrar.State.ACTIVE));
|
|
|
|
// history entries
|
|
historyEntryCatLolCreate = persistResource(
|
|
makeHistoryEntry(
|
|
domainCatLol,
|
|
HistoryEntry.Type.DOMAIN_CREATE,
|
|
Period.create(1, Period.Unit.YEARS),
|
|
"created",
|
|
clock.nowUtc()));
|
|
persistResource(
|
|
makeHistoryEntry(
|
|
domainCatLol2,
|
|
HistoryEntry.Type.DOMAIN_CREATE,
|
|
Period.create(1, Period.Unit.YEARS),
|
|
"created",
|
|
clock.nowUtc()));
|
|
persistResource(
|
|
makeHistoryEntry(
|
|
domainCatExample,
|
|
HistoryEntry.Type.DOMAIN_CREATE,
|
|
Period.create(1, Period.Unit.YEARS),
|
|
"created",
|
|
clock.nowUtc()));
|
|
persistResource(
|
|
makeHistoryEntry(
|
|
domainIdn,
|
|
HistoryEntry.Type.DOMAIN_CREATE,
|
|
Period.create(1, Period.Unit.YEARS),
|
|
"created",
|
|
clock.nowUtc()));
|
|
persistResource(
|
|
makeHistoryEntry(
|
|
domainMultipart,
|
|
HistoryEntry.Type.DOMAIN_CREATE,
|
|
Period.create(1, Period.Unit.YEARS),
|
|
"created",
|
|
clock.nowUtc()));
|
|
|
|
action.requestMethod = POST;
|
|
}
|
|
|
|
private Object generateExpectedJsonForTwoDomains() {
|
|
return generateExpectedJsonForTwoDomains("cat.example", "21-EXAMPLE", "cat.lol", "C-LOL");
|
|
}
|
|
|
|
private Object generateExpectedJsonForTwoDomains(
|
|
String domain1Name,
|
|
String domain1Handle,
|
|
String domain2Name,
|
|
String domain2Handle) {
|
|
return JSONValue.parse(loadFile(
|
|
this.getClass(),
|
|
"rdap_domains_two.json",
|
|
ImmutableMap.of(
|
|
"TYPE", "domain name",
|
|
"DOMAINNAME1", domain1Name,
|
|
"DOMAINHANDLE1", domain1Handle,
|
|
"DOMAINNAME2", domain2Name,
|
|
"DOMAINHANDLE2", domain2Handle)));
|
|
}
|
|
|
|
private Object generateExpectedJsonForFourDomains(
|
|
String domain1Name,
|
|
String domain1Handle,
|
|
String domain2Name,
|
|
String domain2Handle,
|
|
String domain3Name,
|
|
String domain3Handle,
|
|
String domain4Name,
|
|
String domain4Handle,
|
|
String expectedOutputFile) {
|
|
return generateExpectedJsonForFourDomains(
|
|
domain1Name,
|
|
domain1Handle,
|
|
domain2Name,
|
|
domain2Handle,
|
|
domain3Name,
|
|
domain3Handle,
|
|
domain4Name,
|
|
domain4Handle,
|
|
"none",
|
|
expectedOutputFile);
|
|
}
|
|
|
|
private Object generateExpectedJsonForFourDomains(
|
|
String domain1Name,
|
|
String domain1Handle,
|
|
String domain2Name,
|
|
String domain2Handle,
|
|
String domain3Name,
|
|
String domain3Handle,
|
|
String domain4Name,
|
|
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()));
|
|
}
|
|
|
|
private Object generateExpectedJson(String name, String expectedOutputFile) {
|
|
return generateExpectedJson(name, null, null, null, null, null, expectedOutputFile);
|
|
}
|
|
|
|
private Object generateExpectedJson(
|
|
String name,
|
|
String punycodeName,
|
|
String handle,
|
|
@Nullable List<String> contactRoids,
|
|
@Nullable List<String> nameservers,
|
|
@Nullable String registrarName,
|
|
String expectedOutputFile) {
|
|
ImmutableMap.Builder<String, String> substitutionsBuilder = new ImmutableMap.Builder<>();
|
|
substitutionsBuilder.put("NAME", name);
|
|
substitutionsBuilder.put("PUNYCODENAME", (punycodeName == null) ? name : punycodeName);
|
|
substitutionsBuilder.put("HANDLE", (handle == null) ? "(null)" : handle);
|
|
substitutionsBuilder.put("TYPE", "domain name");
|
|
if (contactRoids != null) {
|
|
for (int i = 0; i < contactRoids.size(); i++) {
|
|
substitutionsBuilder.put("CONTACT" + (i + 1) + "ROID", contactRoids.get(i));
|
|
}
|
|
}
|
|
if (nameservers != null) {
|
|
for (int i = 0; i < nameservers.size(); i++) {
|
|
HostResource host = checkNotNull(hostNameToHostMap.get(nameservers.get(i)));
|
|
substitutionsBuilder.put("NAMESERVER" + (i + 1) + "PUNYCODENAME", nameservers.get(i));
|
|
substitutionsBuilder.put(
|
|
"NAMESERVER" + (i + 1) + "NAME", Idn.toUnicode(nameservers.get(i)));
|
|
substitutionsBuilder.put("NAMESERVER" + (i + 1) + "ROID", host.getRepoId());
|
|
substitutionsBuilder.put(
|
|
"NAMESERVER" + (i + 1) + "ADDRESS",
|
|
InetAddresses.toAddrString(host.getInetAddresses().asList().get(0)));
|
|
}
|
|
}
|
|
if (registrarName != null) {
|
|
substitutionsBuilder.put("REGISTRARNAME", registrarName);
|
|
}
|
|
return JSONValue.parse(
|
|
loadFile(this.getClass(), expectedOutputFile, substitutionsBuilder.build()));
|
|
}
|
|
|
|
private Object generateExpectedJsonForDomain(
|
|
String name,
|
|
String punycodeName,
|
|
String handle,
|
|
@Nullable List<String> contactRoids,
|
|
@Nullable List<String> nameservers,
|
|
@Nullable String registrarName,
|
|
String expectedOutputFile) {
|
|
Object obj =
|
|
generateExpectedJson(
|
|
name,
|
|
punycodeName,
|
|
handle,
|
|
contactRoids,
|
|
nameservers,
|
|
registrarName,
|
|
expectedOutputFile);
|
|
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
|
builder.put("domainSearchResults", ImmutableList.of(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() {
|
|
persistResource(
|
|
domainCatLol
|
|
.asBuilder()
|
|
.setCreationTimeForTest(clock.nowUtc().minusYears(1))
|
|
.setDeletionTime(clock.nowUtc().minusMonths(6))
|
|
.build());
|
|
persistResource(
|
|
historyEntryCatLolCreate
|
|
.asBuilder()
|
|
.setModificationTime(clock.nowUtc().minusYears(1))
|
|
.build());
|
|
persistResource(
|
|
makeHistoryEntry(
|
|
domainCatLol,
|
|
HistoryEntry.Type.DOMAIN_DELETE,
|
|
Period.create(1, Period.Unit.YEARS),
|
|
"deleted",
|
|
clock.nowUtc().minusMonths(6)));
|
|
}
|
|
|
|
private void createManyDomainsAndHosts(
|
|
int numActiveDomains, int numTotalDomainsPerActiveDomain, int numHosts) {
|
|
ImmutableSet.Builder<Key<HostResource>> hostKeysBuilder = new ImmutableSet.Builder<>();
|
|
ImmutableSet.Builder<String> subordinateHostnamesBuilder = new ImmutableSet.Builder<>();
|
|
String mainDomainName = String.format("domain%d.lol", numTotalDomainsPerActiveDomain);
|
|
for (int i = numHosts; i >= 1; i--) {
|
|
String hostName = String.format("ns%d.%s", i, mainDomainName);
|
|
subordinateHostnamesBuilder.add(hostName);
|
|
HostResource host = makeAndPersistHostResource(
|
|
hostName, String.format("5.5.%d.%d", 5 + i / 250, i % 250), clock.nowUtc().minusYears(1));
|
|
hostKeysBuilder.add(Key.create(host));
|
|
}
|
|
ImmutableSet<Key<HostResource>> hostKeys = hostKeysBuilder.build();
|
|
// Create all the domains at once, then persist them in parallel, for increased efficiency.
|
|
ImmutableList.Builder<DomainBase> domainsBuilder = new ImmutableList.Builder<>();
|
|
for (int i = numActiveDomains * numTotalDomainsPerActiveDomain; i >= 1; i--) {
|
|
String domainName = String.format("domain%d.lol", i);
|
|
DomainBase.Builder builder =
|
|
makeDomainBase(
|
|
domainName, contact1, contact2, contact3, null, null, registrar)
|
|
.asBuilder()
|
|
.setNameservers(hostKeys)
|
|
.setCreationTimeForTest(clock.nowUtc().minusYears(3));
|
|
if (domainName.equals(mainDomainName)) {
|
|
builder.setSubordinateHosts(subordinateHostnamesBuilder.build());
|
|
}
|
|
if (i % numTotalDomainsPerActiveDomain != 0) {
|
|
builder = builder.setDeletionTime(clock.nowUtc().minusDays(1));
|
|
}
|
|
domainsBuilder.add(builder.build());
|
|
}
|
|
persistResources(domainsBuilder.build());
|
|
}
|
|
|
|
private Object readMultiDomainFile(
|
|
String fileName,
|
|
String domainName1,
|
|
String domainHandle1,
|
|
String domainName2,
|
|
String domainHandle2,
|
|
String domainName3,
|
|
String domainHandle3,
|
|
String domainName4,
|
|
String domainHandle4) {
|
|
return readMultiDomainFile(
|
|
fileName,
|
|
domainName1,
|
|
domainHandle1,
|
|
domainName2,
|
|
domainHandle2,
|
|
domainName3,
|
|
domainHandle3,
|
|
domainName4,
|
|
domainHandle4,
|
|
"none");
|
|
}
|
|
|
|
private Object readMultiDomainFile(
|
|
String fileName,
|
|
String domainName1,
|
|
String domainHandle1,
|
|
String domainName2,
|
|
String domainHandle2,
|
|
String domainName3,
|
|
String domainHandle3,
|
|
String domainName4,
|
|
String domainHandle4,
|
|
String nextQuery) {
|
|
return JSONValue.parse(loadFile(
|
|
this.getClass(),
|
|
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()));
|
|
}
|
|
|
|
private void checkNumberOfDomainsInResult(Object 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");
|
|
|
|
assertThat(domains).hasSize(expected);
|
|
}
|
|
|
|
private void runSuccessfulTestWithCatLol(
|
|
RequestType requestType, String queryString, String fileName) {
|
|
runSuccessfulTest(
|
|
requestType,
|
|
queryString,
|
|
"cat.lol",
|
|
null,
|
|
"C-LOL",
|
|
ImmutableList.of("4-ROID", "6-ROID", "2-ROID"),
|
|
ImmutableList.of("ns1.cat.lol", "ns2.cat.lol"),
|
|
"Yes Virginia <script>",
|
|
fileName);
|
|
}
|
|
|
|
private void runSuccessfulTestWithCat2Lol(
|
|
RequestType requestType, String queryString, String fileName) {
|
|
runSuccessfulTest(
|
|
requestType,
|
|
queryString,
|
|
"cat2.lol",
|
|
null,
|
|
"17-LOL",
|
|
ImmutableList.of("F-ROID", "11-ROID", "D-ROID"),
|
|
ImmutableList.of("ns1.cat.example", "ns2.dog.lol"),
|
|
"Yes Virginia <script>",
|
|
fileName);
|
|
}
|
|
|
|
private void runSuccessfulTest(
|
|
RequestType requestType,
|
|
String queryString,
|
|
String name,
|
|
String punycodeName,
|
|
String handle,
|
|
@Nullable List<String> contactRoids,
|
|
@Nullable List<String> nameservers,
|
|
@Nullable String registrarName,
|
|
String fileName) {
|
|
rememberWildcardType(queryString);
|
|
assertThat(generateActualJson(requestType, queryString))
|
|
.isEqualTo(
|
|
generateExpectedJsonForDomain(
|
|
name, punycodeName, handle, contactRoids, nameservers, registrarName, fileName));
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
}
|
|
|
|
private void runSuccessfulTestWithFourDomains(
|
|
RequestType requestType,
|
|
String queryString,
|
|
String domainRoid1,
|
|
String domainRoid2,
|
|
String domainRoid3,
|
|
String domainRoid4,
|
|
String fileName) {
|
|
runSuccessfulTestWithFourDomains(
|
|
requestType,
|
|
queryString,
|
|
domainRoid1,
|
|
domainRoid2,
|
|
domainRoid3,
|
|
domainRoid4,
|
|
"none",
|
|
fileName);
|
|
}
|
|
|
|
private void runSuccessfulTestWithFourDomains(
|
|
RequestType requestType,
|
|
String queryString,
|
|
String domainRoid1,
|
|
String domainRoid2,
|
|
String domainRoid3,
|
|
String domainRoid4,
|
|
String nextQuery,
|
|
String fileName) {
|
|
rememberWildcardType(queryString);
|
|
assertThat(generateActualJson(requestType, queryString))
|
|
.isEqualTo(
|
|
readMultiDomainFile(
|
|
fileName,
|
|
"domain1.lol",
|
|
domainRoid1,
|
|
"domain2.lol",
|
|
domainRoid2,
|
|
"domain3.lol",
|
|
domainRoid3,
|
|
"domain4.lol",
|
|
domainRoid4,
|
|
nextQuery));
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
}
|
|
|
|
private void runNotFoundTest(
|
|
RequestType requestType, String queryString, String errorMessage) {
|
|
rememberWildcardType(queryString);
|
|
assertThat(generateActualJson(requestType, queryString))
|
|
.isEqualTo(generateExpectedJson(errorMessage, "rdap_error_404.json"));
|
|
assertThat(response.getStatus()).isEqualTo(404);
|
|
}
|
|
|
|
private void verifyMetrics(SearchType searchType, Optional<Long> numDomainsRetrieved) {
|
|
verifyMetrics(
|
|
searchType, numDomainsRetrieved, Optional.empty(), IncompletenessWarningType.COMPLETE);
|
|
}
|
|
|
|
private void verifyMetrics(
|
|
SearchType searchType,
|
|
Optional<Long> numDomainsRetrieved,
|
|
IncompletenessWarningType incompletenessWarningType) {
|
|
verifyMetrics(searchType, numDomainsRetrieved, Optional.empty(), incompletenessWarningType);
|
|
}
|
|
|
|
private void verifyMetrics(
|
|
SearchType searchType, Optional<Long> numDomainsRetrieved, Optional<Long> numHostsRetrieved) {
|
|
verifyMetrics(
|
|
searchType, numDomainsRetrieved, numHostsRetrieved, IncompletenessWarningType.COMPLETE);
|
|
}
|
|
|
|
private void verifyMetrics(
|
|
SearchType searchType, long numDomainsRetrieved, long numHostsRetrieved) {
|
|
verifyMetrics(
|
|
searchType,
|
|
Optional.of(numDomainsRetrieved),
|
|
Optional.of(numHostsRetrieved),
|
|
IncompletenessWarningType.COMPLETE);
|
|
}
|
|
|
|
private void verifyMetrics(
|
|
SearchType searchType,
|
|
Optional<Long> numDomainsRetrieved,
|
|
Optional<Long> numHostsRetrieved,
|
|
IncompletenessWarningType incompletenessWarningType) {
|
|
metricSearchType = searchType;
|
|
verifyMetrics(
|
|
EndpointType.DOMAINS,
|
|
POST,
|
|
action.includeDeletedParam.orElse(false),
|
|
action.registrarParam.isPresent(),
|
|
numDomainsRetrieved,
|
|
numHostsRetrieved,
|
|
Optional.empty(),
|
|
incompletenessWarningType);
|
|
}
|
|
|
|
private void verifyErrorMetrics(SearchType searchType) {
|
|
verifyErrorMetrics(searchType, Optional.of(0L), Optional.empty(), 404);
|
|
}
|
|
|
|
private void verifyErrorMetrics(
|
|
SearchType searchType, Optional<Long> numDomainsRetrieved, int statusCode) {
|
|
verifyErrorMetrics(searchType, numDomainsRetrieved, Optional.empty(), statusCode);
|
|
}
|
|
|
|
private void verifyErrorMetrics(
|
|
SearchType searchType,
|
|
Optional<Long> numDomainsRetrieved,
|
|
Optional<Long> numHostsRetrieved,
|
|
int statusCode) {
|
|
metricStatusCode = statusCode;
|
|
verifyMetrics(searchType, numDomainsRetrieved, numHostsRetrieved);
|
|
}
|
|
|
|
/**
|
|
* Checks multi-page result set navigation using the cursor.
|
|
*
|
|
* <p>If there are more results than the max result set size, the RDAP code returns a cursor token
|
|
* which can be used in a subsequent call to get the next chunk of results.
|
|
*
|
|
* @param requestType the type of query (name, nameserver name or nameserver address)
|
|
* @param paramValue the query string
|
|
* @param expectedNames an immutable list of the domain names we expect to retrieve
|
|
*/
|
|
private void checkCursorNavigation(
|
|
RequestType requestType, String paramValue, ImmutableList<String> expectedNames)
|
|
throws Exception {
|
|
String cursor = null;
|
|
int expectedNameOffset = 0;
|
|
int expectedPageCount =
|
|
(expectedNames.size() + action.rdapResultSetMaxSize - 1) / action.rdapResultSetMaxSize;
|
|
for (int pageNum = 0; pageNum < expectedPageCount; pageNum++) {
|
|
Object results = generateActualJson(requestType, paramValue, cursor);
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
String linkToNext = RdapTestHelper.getLinkToNext(results);
|
|
if (pageNum == expectedPageCount - 1) {
|
|
assertThat(linkToNext).isNull();
|
|
} else {
|
|
assertThat(linkToNext).isNotNull();
|
|
int pos = linkToNext.indexOf("cursor=");
|
|
assertThat(pos).isAtLeast(0);
|
|
cursor = URLDecoder.decode(linkToNext.substring(pos + 7), "UTF-8");
|
|
Object searchResults = ((JSONObject) results).get("domainSearchResults");
|
|
assertThat(searchResults).isInstanceOf(JSONArray.class);
|
|
assertThat(((JSONArray) searchResults)).hasSize(action.rdapResultSetMaxSize);
|
|
for (Object item : ((JSONArray) searchResults)) {
|
|
assertThat(item).isInstanceOf(JSONObject.class);
|
|
Object name = ((JSONObject) item).get("ldhName");
|
|
assertThat(name).isNotNull();
|
|
assertThat(name).isInstanceOf(String.class);
|
|
assertThat(name).isEqualTo(expectedNames.get(expectedNameOffset++));
|
|
}
|
|
response = new FakeResponse();
|
|
action.response = response;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void testInvalidPath_rejected() {
|
|
action.requestPath = actionPath + "/path";
|
|
action.run();
|
|
assertThat(response.getStatus()).isEqualTo(400);
|
|
verifyErrorMetrics(SearchType.NONE, Optional.empty(), 400);
|
|
}
|
|
|
|
@Test
|
|
public void testInvalidRequest_rejected() {
|
|
assertThat(generateActualJson(RequestType.NONE, null))
|
|
.isEqualTo(generateExpectedJson(
|
|
"You must specify either name=XXXX, nsLdhName=YYYY or nsIp=ZZZZ",
|
|
"rdap_error_400.json"));
|
|
assertThat(response.getStatus()).isEqualTo(400);
|
|
verifyErrorMetrics(SearchType.NONE, Optional.empty(), 400);
|
|
}
|
|
|
|
@Test
|
|
public void testInvalidWildcard_rejected() {
|
|
assertThat(generateActualJson(RequestType.NAME, "exam*ple"))
|
|
.isEqualTo(generateExpectedJson(
|
|
"Suffix after wildcard must be one or more domain"
|
|
+ " name labels, e.g. exam*.tld, ns*.example.tld",
|
|
"rdap_error_422.json"));
|
|
assertThat(response.getStatus()).isEqualTo(422);
|
|
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME, Optional.empty(), 422);
|
|
}
|
|
|
|
@Test
|
|
public void testMultipleWildcards_rejected() {
|
|
assertThat(generateActualJson(RequestType.NAME, "*.*"))
|
|
.isEqualTo(generateExpectedJson("Only one wildcard allowed", "rdap_error_422.json"));
|
|
assertThat(response.getStatus()).isEqualTo(422);
|
|
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME, Optional.empty(), 422);
|
|
}
|
|
|
|
@Test
|
|
public void testNoCharactersToMatch_rejected() {
|
|
rememberWildcardType("*");
|
|
assertThat(generateActualJson(RequestType.NAME, "*"))
|
|
.isEqualTo(
|
|
generateExpectedJson(
|
|
"Initial search string is required for wildcard domain searches without a TLD"
|
|
+ " suffix",
|
|
"rdap_error_422.json"));
|
|
assertThat(response.getStatus()).isEqualTo(422);
|
|
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME, Optional.empty(), 422);
|
|
}
|
|
|
|
@Test
|
|
public void testFewerThanTwoCharactersToMatch_rejected() {
|
|
rememberWildcardType("a*");
|
|
assertThat(generateActualJson(RequestType.NAME, "a*"))
|
|
.isEqualTo(
|
|
generateExpectedJson(
|
|
"Initial search string must be at least 2 characters for wildcard domain searches"
|
|
+ " without a TLD suffix",
|
|
"rdap_error_422.json"));
|
|
assertThat(response.getStatus()).isEqualTo(422);
|
|
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME, Optional.empty(), 422);
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_found() {
|
|
login("evilregistrar");
|
|
runSuccessfulTestWithCatLol(RequestType.NAME, "cat.lol", "rdap_domain.json");
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_foundWithUpperCase() {
|
|
login("evilregistrar");
|
|
runSuccessfulTestWithCatLol(RequestType.NAME, "CaT.lOl", "rdap_domain.json");
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_found_sameRegistrarRequested() {
|
|
login("evilregistrar");
|
|
action.registrarParam = Optional.of("evilregistrar");
|
|
runSuccessfulTestWithCatLol(RequestType.NAME, "cat.lol", "rdap_domain.json");
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_notFound_differentRegistrarRequested() {
|
|
action.registrarParam = Optional.of("otherregistrar");
|
|
runNotFoundTest(RequestType.NAME, "cat.lol", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME);
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_found_asAdministrator() {
|
|
loginAsAdmin();
|
|
runSuccessfulTestWithCatLol(RequestType.NAME, "cat.lol", "rdap_domain.json");
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_found_loggedInAsOtherRegistrar() {
|
|
login("otherregistrar");
|
|
runSuccessfulTestWithCatLol(
|
|
RequestType.NAME, "cat.lol", "rdap_domain_no_contacts_with_remark.json");
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
|
}
|
|
|
|
/*
|
|
* This test is flaky because IDN.toASCII may or may not remove the trailing dot of its own
|
|
* accord. If it does, the test will pass.
|
|
*/
|
|
@Ignore
|
|
@Test
|
|
public void testDomainMatchWithTrailingDot_notFound() {
|
|
runNotFoundTest(RequestType.NAME, "cat.lol.", "No domains found");
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_cat2_lol_found() {
|
|
login("evilregistrar");
|
|
runSuccessfulTestWithCat2Lol(RequestType.NAME, "cat2.lol", "rdap_domain_cat2.json");
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_cat_example_found() {
|
|
login("evilregistrar");
|
|
runSuccessfulTest(
|
|
RequestType.NAME,
|
|
"cat.example",
|
|
"cat.example",
|
|
null,
|
|
"21-EXAMPLE",
|
|
null,
|
|
ImmutableList.of("ns1.cat.lol", "ns2.external.tld"),
|
|
"St. John Chrysostom",
|
|
"rdap_domain_no_contacts_with_remark.json");
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_cat_idn_unicode_found() {
|
|
runSuccessfulTest(
|
|
RequestType.NAME,
|
|
"cat.みんな",
|
|
"cat.みんな",
|
|
"cat.xn--q9jyb4c",
|
|
"2D-Q9JYB4C",
|
|
null,
|
|
ImmutableList.of("ns1.cat.xn--q9jyb4c", "ns2.cat.xn--q9jyb4c"),
|
|
"みんな",
|
|
"rdap_domain_unicode_no_contacts_with_remark.json");
|
|
// The unicode gets translated to ASCII before getting parsed into a search pattern.
|
|
metricPrefixLength = 15;
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_cat_idn_punycode_found() {
|
|
runSuccessfulTest(
|
|
RequestType.NAME,
|
|
"cat.xn--q9jyb4c",
|
|
"cat.みんな",
|
|
"cat.xn--q9jyb4c",
|
|
"2D-Q9JYB4C",
|
|
null,
|
|
ImmutableList.of("ns1.cat.xn--q9jyb4c", "ns2.cat.xn--q9jyb4c"),
|
|
"みんな",
|
|
"rdap_domain_unicode_no_contacts_with_remark.json");
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_cat_1_test_found() {
|
|
runSuccessfulTest(
|
|
RequestType.NAME,
|
|
"cat.1.test",
|
|
"cat.1.test",
|
|
null,
|
|
"39-1_TEST",
|
|
ImmutableList.of("4-ROID", "6-ROID", "2-ROID"),
|
|
ImmutableList.of("ns1.cat.1.test", "ns2.cat.2.test"),
|
|
"1.test",
|
|
"rdap_domain_no_contacts_with_remark.json");
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_castar_1_test_found() {
|
|
runSuccessfulTest(
|
|
RequestType.NAME,
|
|
"ca*.1.test",
|
|
"cat.1.test",
|
|
null,
|
|
"39-1_TEST",
|
|
ImmutableList.of("4-ROID", "6-ROID", "2-ROID"),
|
|
ImmutableList.of("ns1.cat.1.test", "ns2.cat.2.test"),
|
|
"1.test",
|
|
"rdap_domain_no_contacts_with_remark.json");
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_castar_test_notFound() {
|
|
runNotFoundTest(RequestType.NAME, "ca*.test", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME);
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_catstar_lol_found() {
|
|
rememberWildcardType("cat*.lol");
|
|
assertThat(generateActualJson(RequestType.NAME, "cat*.lol"))
|
|
.isEqualTo(generateExpectedJsonForTwoDomains("cat.lol", "C-LOL", "cat2.lol", "17-LOL"));
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(2L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_cstar_lol_found() {
|
|
rememberWildcardType("c*.lol");
|
|
assertThat(generateActualJson(RequestType.NAME, "c*.lol"))
|
|
.isEqualTo(generateExpectedJsonForTwoDomains("cat.lol", "C-LOL", "cat2.lol", "17-LOL"));
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(2L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_qstar_lol_notFound() {
|
|
runNotFoundTest(RequestType.NAME, "q*.lol", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME);
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_star_lol_found() {
|
|
rememberWildcardType("*.lol");
|
|
assertThat(generateActualJson(RequestType.NAME, "*.lol"))
|
|
.isEqualTo(generateExpectedJsonForTwoDomains("cat.lol", "C-LOL", "cat2.lol", "17-LOL"));
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(2L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_star_lol_found_sameRegistrarRequested() {
|
|
action.registrarParam = Optional.of("evilregistrar");
|
|
rememberWildcardType("*.lol");
|
|
assertThat(generateActualJson(RequestType.NAME, "*.lol"))
|
|
.isEqualTo(generateExpectedJsonForTwoDomains("cat.lol", "C-LOL", "cat2.lol", "17-LOL"));
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(2L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_star_lol_notFound_differentRegistrarRequested() {
|
|
action.registrarParam = Optional.of("otherregistrar");
|
|
rememberWildcardType("*.lol");
|
|
runNotFoundTest(RequestType.NAME, "*.lol", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME);
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_cat_star_found() {
|
|
rememberWildcardType("cat.*");
|
|
assertThat(generateActualJson(RequestType.NAME, "cat.*"))
|
|
.isEqualTo(
|
|
generateExpectedJsonForFourDomains(
|
|
"cat.1.test", "39-1_TEST",
|
|
"cat.example", "21-EXAMPLE",
|
|
"cat.lol", "C-LOL",
|
|
"cat.xn--q9jyb4c", "2D-Q9JYB4C",
|
|
"rdap_domains_four_with_one_unicode.json"));
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(4L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_cat_star_foundOne_sameRegistrarRequested() {
|
|
login("evilregistrar");
|
|
action.registrarParam = Optional.of("evilregistrar");
|
|
runSuccessfulTestWithCatLol(RequestType.NAME, "cat.*", "rdap_domain.json");
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_cat_star_notFound_differentRegistrarRequested() {
|
|
action.registrarParam = Optional.of("otherregistrar");
|
|
runNotFoundTest(RequestType.NAME, "cat.*", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME);
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_cat_lstar_found() {
|
|
login("evilregistrar");
|
|
runSuccessfulTestWithCatLol(RequestType.NAME, "cat.l*", "rdap_domain.json");
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_catstar_found() {
|
|
rememberWildcardType("cat*");
|
|
assertThat(generateActualJson(RequestType.NAME, "cat*"))
|
|
.isEqualTo(
|
|
generateExpectedJsonForFourDomains(
|
|
"cat.1.test", "39-1_TEST",
|
|
"cat.example", "21-EXAMPLE",
|
|
"cat.lol", "C-LOL",
|
|
"cat.xn--q9jyb4c", "2D-Q9JYB4C",
|
|
"name=cat*&cursor=Y2F0LnhuLS1xOWp5YjRj",
|
|
"rdap_domains_four_with_one_unicode_truncated.json"));
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(5L), IncompletenessWarningType.TRUNCATED);
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatchWithWildcardAndEmptySuffix_fails() {
|
|
// Unfortunately, we can't be sure which error is going to be returned. The version of
|
|
// IDN.toASCII used in Eclipse drops a trailing dot, if any. But the version linked in by
|
|
// Blaze throws an error in that situation. So just check that it returns an error.
|
|
rememberWildcardType("exam*..");
|
|
generateActualJson(RequestType.NAME, "exam*..");
|
|
assertThat(response.getStatus()).isIn(Range.closed(400, 499));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_dog_notFound() {
|
|
runNotFoundTest(RequestType.NAME, "dog*", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME);
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatchDeletedDomain_notFound() {
|
|
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
|
|
runNotFoundTest(RequestType.NAME, "cat.lol", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME);
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatchDeletedDomain_notFound_deletedNotRequested() {
|
|
login("evilregistrar");
|
|
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
|
|
runNotFoundTest(RequestType.NAME, "cat.lol", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME);
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatchDeletedDomain_found_loggedInAsSameRegistrar() {
|
|
login("evilregistrar");
|
|
action.includeDeletedParam = Optional.of(true);
|
|
deleteCatLol();
|
|
runSuccessfulTestWithCatLol(RequestType.NAME, "cat.lol", "rdap_domain_deleted.json");
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatchDeletedDomain_notFound_loggedInAsOtherRegistrar() {
|
|
login("otherregistrar");
|
|
action.includeDeletedParam = Optional.of(true);
|
|
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
|
|
runNotFoundTest(RequestType.NAME, "cat.lol", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L), 404);
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatchDeletedDomain_found_loggedInAsAdmin() {
|
|
loginAsAdmin();
|
|
action.includeDeletedParam = Optional.of(true);
|
|
deleteCatLol();
|
|
runSuccessfulTestWithCatLol(RequestType.NAME, "cat.lol", "rdap_domain_deleted.json");
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatchDeletedDomainWithWildcard_notFound() {
|
|
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
|
|
runNotFoundTest(RequestType.NAME, "cat.lo*", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L), 404);
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatchDeletedDomainsWithWildcardAndTld_notFound() {
|
|
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
|
|
persistDomainAsDeleted(domainCatLol2, clock.nowUtc().minusDays(1));
|
|
runNotFoundTest(RequestType.NAME, "cat*.lol", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(2L), 404);
|
|
}
|
|
|
|
// TODO(b/27378695): reenable or delete this test
|
|
@Ignore
|
|
@Test
|
|
public void testDomainMatchDomainInTestTld_notFound() {
|
|
persistResource(Registry.get("lol").asBuilder().setTldType(Registry.TldType.TEST).build());
|
|
runNotFoundTest(RequestType.NAME, "cat.lol", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME);
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_manyDeletedDomains_fullResultSet() {
|
|
// 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");
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
checkNumberOfDomainsInResult(obj, 4);
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(16L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_manyDeletedDomains_partialResultSetDueToInsufficientDomains() {
|
|
// 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");
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
checkNumberOfDomainsInResult(obj, 3);
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(60L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_manyDeletedDomains_partialResultSetDueToFetchingLimit() {
|
|
// This is not exactly desired behavior, but expected: There are enough domains to fill a full
|
|
// result set, but there are so many deleted domains that we run out of patience before we work
|
|
// our way through all of them.
|
|
createManyDomainsAndHosts(4, 50, 2);
|
|
rememberWildcardType("domain*.lol");
|
|
assertThat(generateActualJson(RequestType.NAME, "domain*.lol"))
|
|
.isEqualTo(readMultiDomainFile(
|
|
"rdap_incomplete_domain_result_set.json",
|
|
"domain100.lol",
|
|
"A7-LOL",
|
|
"domain150.lol",
|
|
"75-LOL",
|
|
"domain200.lol",
|
|
"43-LOL",
|
|
"domainunused.lol",
|
|
"unused-LOL"));
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(
|
|
SearchType.BY_DOMAIN_NAME,
|
|
Optional.of(120L),
|
|
IncompletenessWarningType.MIGHT_BE_INCOMPLETE);
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_nontruncatedResultsSet() {
|
|
createManyDomainsAndHosts(4, 1, 2);
|
|
runSuccessfulTestWithFourDomains(
|
|
RequestType.NAME,
|
|
"domain*.lol",
|
|
"46-LOL",
|
|
"45-LOL",
|
|
"44-LOL",
|
|
"43-LOL",
|
|
"rdap_nontruncated_domains.json");
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(4L));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_truncatedResultsSet() {
|
|
createManyDomainsAndHosts(5, 1, 2);
|
|
runSuccessfulTestWithFourDomains(
|
|
RequestType.NAME,
|
|
"domain*.lol",
|
|
"47-LOL",
|
|
"46-LOL",
|
|
"45-LOL",
|
|
"44-LOL",
|
|
"name=domain*.lol&cursor=ZG9tYWluNC5sb2w%3D",
|
|
"rdap_domains_four_truncated.json");
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(5L), IncompletenessWarningType.TRUNCATED);
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_tldSearchOrderedProperly() {
|
|
createManyDomainsAndHosts(4, 1, 2);
|
|
rememberWildcardType("*.lol");
|
|
assertThat(generateActualJson(RequestType.NAME, "*.lol"))
|
|
.isEqualTo(readMultiDomainFile(
|
|
"rdap_domains_four_truncated.json",
|
|
"cat.lol",
|
|
"C-LOL",
|
|
"cat2.lol",
|
|
"17-LOL",
|
|
"domain1.lol",
|
|
"46-LOL",
|
|
"domain2.lol",
|
|
"45-LOL",
|
|
"name=*.lol&cursor=ZG9tYWluMi5sb2w%3D"));
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(5L), IncompletenessWarningType.TRUNCATED);
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_reallyTruncatedResultsSet() {
|
|
// Don't use 10 or more domains for this test, because domain10.lol will come before
|
|
// domain2.lol, and you'll get the wrong domains in the result set.
|
|
createManyDomainsAndHosts(9, 1, 2);
|
|
runSuccessfulTestWithFourDomains(
|
|
RequestType.NAME,
|
|
"domain*.lol",
|
|
"4B-LOL",
|
|
"4A-LOL",
|
|
"49-LOL",
|
|
"48-LOL",
|
|
"name=domain*.lol&cursor=ZG9tYWluNC5sb2w%3D",
|
|
"rdap_domains_four_truncated.json");
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(5L), IncompletenessWarningType.TRUNCATED);
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_truncatedResultsAfterMultipleChunks() {
|
|
createManyDomainsAndHosts(5, 6, 2);
|
|
rememberWildcardType("domain*.lol");
|
|
assertThat(generateActualJson(RequestType.NAME, "domain*.lol"))
|
|
.isEqualTo(readMultiDomainFile(
|
|
"rdap_domains_four_truncated.json",
|
|
"domain12.lol",
|
|
"55-LOL",
|
|
"domain18.lol",
|
|
"4F-LOL",
|
|
"domain24.lol",
|
|
"49-LOL",
|
|
"domain30.lol",
|
|
"43-LOL",
|
|
"name=domain*.lol&cursor=ZG9tYWluMzAubG9s"));
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(27L), IncompletenessWarningType.TRUNCATED);
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_cursorNavigationWithInitialString() throws Exception {
|
|
createManyDomainsAndHosts(11, 1, 2);
|
|
checkCursorNavigation(
|
|
RequestType.NAME,
|
|
"domain*.lol",
|
|
ImmutableList.of(
|
|
"domain1.lol",
|
|
"domain10.lol",
|
|
"domain11.lol",
|
|
"domain2.lol",
|
|
"domain3.lol",
|
|
"domain4.lol",
|
|
"domain5.lol",
|
|
"domain6.lol",
|
|
"domain7.lol",
|
|
"domain8.lol",
|
|
"domain9.lol"));
|
|
}
|
|
|
|
@Test
|
|
public void testDomainMatch_cursorNavigationWithTldSuffix() throws Exception {
|
|
createManyDomainsAndHosts(11, 1, 2);
|
|
checkCursorNavigation(
|
|
RequestType.NAME,
|
|
"*.lol",
|
|
ImmutableList.of(
|
|
"cat.lol",
|
|
"cat2.lol",
|
|
"domain1.lol",
|
|
"domain10.lol",
|
|
"domain11.lol",
|
|
"domain2.lol",
|
|
"domain3.lol",
|
|
"domain4.lol",
|
|
"domain5.lol",
|
|
"domain6.lol",
|
|
"domain7.lol",
|
|
"domain8.lol",
|
|
"domain9.lol"));
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatch_foundMultiple() {
|
|
rememberWildcardType("ns1.cat.lol");
|
|
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns1.cat.lol"))
|
|
.isEqualTo(generateExpectedJsonForTwoDomains());
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 2, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatch_foundMultiple_sameRegistrarRequested() {
|
|
action.registrarParam = Optional.of("TheRegistrar");
|
|
rememberWildcardType("ns1.cat.lol");
|
|
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns1.cat.lol"))
|
|
.isEqualTo(generateExpectedJsonForTwoDomains());
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 2, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatch_notFound_differentRegistrarRequested() {
|
|
action.registrarParam = Optional.of("otherregistrar");
|
|
runNotFoundTest(RequestType.NS_LDH_NAME, "ns1.cat.lol", "No matching nameservers found");
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.empty(), Optional.of(0L), 404);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchWithWildcard_found() {
|
|
login("evilregistrar");
|
|
runSuccessfulTestWithCatLol(RequestType.NS_LDH_NAME, "ns2.cat.l*", "rdap_domain.json");
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 1, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchWithWildcard_found_sameRegistrarRequested() {
|
|
login("evilregistrar");
|
|
action.registrarParam = Optional.of("TheRegistrar");
|
|
runSuccessfulTestWithCatLol(RequestType.NS_LDH_NAME, "ns2.cat.l*", "rdap_domain.json");
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 1, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchWithWildcard_notFound_differentRegistrarRequested() {
|
|
action.registrarParam = Optional.of("otherregistrar");
|
|
runNotFoundTest(RequestType.NS_LDH_NAME, "ns2.cat.l*", "No matching nameservers found");
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.empty(), Optional.of(0L), 404);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchWithWildcardAndDomainSuffix_notFound() {
|
|
runNotFoundTest(RequestType.NS_LDH_NAME, "ns5*.cat.lol", "No matching nameservers found");
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.empty(), Optional.of(0L), 404);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchWithNoPrefixAndDomainSuffix_found() {
|
|
rememberWildcardType("*.cat.lol");
|
|
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "*.cat.lol"))
|
|
.isEqualTo(generateExpectedJsonForTwoDomains());
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 2, 2);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchWithOneCharacterPrefixAndDomainSuffix_found() {
|
|
rememberWildcardType("n*.cat.lol");
|
|
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "n*.cat.lol"))
|
|
.isEqualTo(generateExpectedJsonForTwoDomains());
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 2, 2);
|
|
}
|
|
|
|
@Test
|
|
public void
|
|
testNameserverMatchWithOneCharacterPrefixAndDomainSuffix_found_sameRegistrarRequested() {
|
|
action.registrarParam = Optional.of("TheRegistrar");
|
|
rememberWildcardType("n*.cat.lol");
|
|
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "n*.cat.lol"))
|
|
.isEqualTo(generateExpectedJsonForTwoDomains());
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 2, 2);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchWithPrefixAndDomainSuffix_notFound_differentRegistrarRequested() {
|
|
action.registrarParam = Optional.of("otherregistrar");
|
|
runNotFoundTest(RequestType.NS_LDH_NAME, "n*.cat.lol", "No matching nameservers found");
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.empty(), Optional.of(0L), 404);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchWithTwoCharacterPrefixAndDomainSuffix_found() {
|
|
rememberWildcardType("ns*.cat.lol");
|
|
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns*.cat.lol"))
|
|
.isEqualTo(generateExpectedJsonForTwoDomains());
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 2, 2);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchWithWildcardAndEmptySuffix_unprocessable() {
|
|
rememberWildcardType("ns*.");
|
|
generateActualJson(RequestType.NS_LDH_NAME, "ns*.");
|
|
assertThat(response.getStatus()).isEqualTo(422);
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.empty(), 422);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchWithWildcardAndInvalidSuffix_unprocessable() {
|
|
rememberWildcardType("ns*.google.com");
|
|
generateActualJson(RequestType.NS_LDH_NAME, "ns*.google.com");
|
|
assertThat(response.getStatus()).isEqualTo(422);
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.empty(), 422);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatch_ns2_cat_lol_found() {
|
|
login("evilregistrar");
|
|
runSuccessfulTestWithCatLol(RequestType.NS_LDH_NAME, "ns2.cat.lol", "rdap_domain.json");
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 1, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatch_ns2_dog_lol_found() {
|
|
login("evilregistrar");
|
|
runSuccessfulTestWithCat2Lol(RequestType.NS_LDH_NAME, "ns2.dog.lol", "rdap_domain_cat2.json");
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 1, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatch_ns1_cat_idn_unicode_badRequest() {
|
|
// nsLdhName must use punycode.
|
|
metricWildcardType = WildcardType.INVALID;
|
|
metricPrefixLength = 0;
|
|
generateActualJson(RequestType.NS_LDH_NAME, "ns1.cat.みんな");
|
|
assertThat(response.getStatus()).isEqualTo(400);
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.empty(), 400);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatch_ns1_cat_idn_punycode_found() {
|
|
runSuccessfulTest(
|
|
RequestType.NS_LDH_NAME,
|
|
"ns1.cat.xn--q9jyb4c",
|
|
"cat.みんな",
|
|
"cat.xn--q9jyb4c",
|
|
"2D-Q9JYB4C",
|
|
null,
|
|
ImmutableList.of("ns1.cat.xn--q9jyb4c", "ns2.cat.xn--q9jyb4c"),
|
|
"みんな",
|
|
"rdap_domain_unicode_no_contacts_with_remark.json");
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 1, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatch_ns1_cat_1_test_found() {
|
|
runSuccessfulTest(
|
|
RequestType.NS_LDH_NAME,
|
|
"ns1.cat.1.test",
|
|
"cat.1.test",
|
|
null,
|
|
"39-1_TEST",
|
|
ImmutableList.of("4-ROID", "6-ROID", "2-ROID"),
|
|
ImmutableList.of("ns1.cat.1.test", "ns2.cat.2.test"),
|
|
"1.test",
|
|
"rdap_domain_no_contacts_with_remark.json");
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 1, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatch_nsstar_cat_1_test_found() {
|
|
runSuccessfulTest(
|
|
RequestType.NS_LDH_NAME,
|
|
"ns*.cat.1.test",
|
|
"cat.1.test",
|
|
null,
|
|
"39-1_TEST",
|
|
ImmutableList.of("4-ROID", "6-ROID", "2-ROID"),
|
|
ImmutableList.of("ns1.cat.1.test", "ns2.cat.2.test"),
|
|
"1.test",
|
|
"rdap_domain_no_contacts_with_remark.json");
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 1, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatch_nsstar_test_unprocessable() {
|
|
rememberWildcardType("ns*.1.test");
|
|
generateActualJson(RequestType.NS_LDH_NAME, "ns*.1.test");
|
|
assertThat(response.getStatus()).isEqualTo(422);
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.empty(), 422);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchMissing_notFound() {
|
|
runNotFoundTest(RequestType.NS_LDH_NAME, "ns1.missing.com", "No matching nameservers found");
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.empty(), Optional.of(0L), 404);
|
|
}
|
|
|
|
// TODO(b/27378695): reenable or delete this test
|
|
@Ignore
|
|
@Test
|
|
public void testNameserverMatchDomainsInTestTld_notFound() {
|
|
persistResource(Registry.get("lol").asBuilder().setTldType(Registry.TldType.TEST).build());
|
|
runNotFoundTest(RequestType.NS_LDH_NAME, "ns2.cat.lol", "No matching nameservers found");
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchDeletedDomain_notFound() {
|
|
action.includeDeletedParam = Optional.of(true);
|
|
deleteCatLol();
|
|
runNotFoundTest(RequestType.NS_LDH_NAME, "ns2.cat.lol", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(0L), Optional.of(1L), 404);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchDeletedDomain_found_loggedInAsSameRegistrar() {
|
|
login("evilregistrar");
|
|
action.includeDeletedParam = Optional.of(true);
|
|
deleteCatLol();
|
|
runSuccessfulTestWithCatLol(RequestType.NS_LDH_NAME, "ns2.cat.lol", "rdap_domain_deleted.json");
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 1, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchDeletedDomain_notFound_loggedInAsOtherRegistrar() {
|
|
login("otherregistrar");
|
|
action.includeDeletedParam = Optional.of(true);
|
|
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
|
|
runNotFoundTest(RequestType.NS_LDH_NAME, "ns2.cat.lol", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(0L), Optional.of(1L), 404);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchDeletedDomain_found_loggedInAsAdmin() {
|
|
loginAsAdmin();
|
|
action.includeDeletedParam = Optional.of(true);
|
|
deleteCatLol();
|
|
runSuccessfulTestWithCatLol(RequestType.NS_LDH_NAME, "ns2.cat.lol", "rdap_domain_deleted.json");
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 1, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchOneDeletedDomain_foundTheOther() {
|
|
login("evilregistrar");
|
|
persistDomainAsDeleted(domainCatExample, clock.nowUtc().minusDays(1));
|
|
runSuccessfulTestWithCatLol(RequestType.NS_LDH_NAME, "ns1.cat.lol", "rdap_domain.json");
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 1, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchTwoDeletedDomains_notFound() {
|
|
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
|
|
persistDomainAsDeleted(domainCatExample, clock.nowUtc().minusDays(1));
|
|
runNotFoundTest(RequestType.NS_LDH_NAME, "ns1.cat.lol", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(0L), Optional.of(1L), 404);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchDeletedNameserver_notFound() {
|
|
persistResource(
|
|
hostNs1CatLol.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
|
|
runNotFoundTest(RequestType.NS_LDH_NAME, "ns1.cat.lol", "No matching nameservers found");
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.empty(), Optional.of(0L), 404);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchDeletedNameserverWithWildcard_notFound() {
|
|
persistResource(
|
|
hostNs1CatLol.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
|
|
runNotFoundTest(RequestType.NS_LDH_NAME, "ns1.cat.l*", "No matching nameservers found");
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.empty(), Optional.of(0L), 404);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchDeletedNameserverWithWildcardAndSuffix_notFound() {
|
|
persistResource(
|
|
hostNs1CatLol.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
|
|
runNotFoundTest(RequestType.NS_LDH_NAME, "ns1*.cat.lol", "No matching nameservers found");
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.empty(), Optional.of(0L), 404);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchManyNameserversForTheSameDomains() {
|
|
// 40 nameservers for each of 3 domains; we should get back all three undeleted domains, because
|
|
// each one references the nameserver.
|
|
createManyDomainsAndHosts(3, 1, 40);
|
|
rememberWildcardType("ns1.domain1.lol");
|
|
Object 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));
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchManyNameserversForTheSameDomainsWithWildcard() {
|
|
// 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*");
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
checkNumberOfDomainsInResult(obj, 3);
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(3L), Optional.of(1L));
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatchManyNameserversForTheSameDomainsWithSuffix() {
|
|
// Same as above, except that we find all 39 nameservers because of the wildcard. But we
|
|
// should still only return 3 domains, because we merge duplicate domains together in a set.
|
|
// Since we fetch domains by nameserver in batches of 30 nameservers, we need to make sure to
|
|
// 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");
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
checkNumberOfDomainsInResult(obj, 3);
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(3L), Optional.of(39L));
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatch_nontruncatedResultsSet() {
|
|
createManyDomainsAndHosts(4, 1, 2);
|
|
runSuccessfulTestWithFourDomains(
|
|
RequestType.NS_LDH_NAME,
|
|
"ns1.domain1.lol",
|
|
"46-LOL",
|
|
"45-LOL",
|
|
"44-LOL",
|
|
"43-LOL",
|
|
"rdap_nontruncated_domains.json");
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(4L), Optional.of(1L));
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatch_truncatedResultsSet() {
|
|
createManyDomainsAndHosts(5, 1, 2);
|
|
runSuccessfulTestWithFourDomains(
|
|
RequestType.NS_LDH_NAME,
|
|
"ns1.domain1.lol",
|
|
"47-LOL",
|
|
"46-LOL",
|
|
"45-LOL",
|
|
"44-LOL",
|
|
"nsLdhName=ns1.domain1.lol&cursor=ZG9tYWluNC5sb2w%3D",
|
|
"rdap_domains_four_truncated.json");
|
|
verifyMetrics(
|
|
SearchType.BY_NAMESERVER_NAME,
|
|
Optional.of(5L),
|
|
Optional.of(1L),
|
|
IncompletenessWarningType.TRUNCATED);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatch_reallyTruncatedResultsSet() {
|
|
createManyDomainsAndHosts(9, 1, 2);
|
|
runSuccessfulTestWithFourDomains(
|
|
RequestType.NS_LDH_NAME,
|
|
"ns1.domain1.lol",
|
|
"4B-LOL",
|
|
"4A-LOL",
|
|
"49-LOL",
|
|
"48-LOL",
|
|
"nsLdhName=ns1.domain1.lol&cursor=ZG9tYWluNC5sb2w%3D",
|
|
"rdap_domains_four_truncated.json");
|
|
verifyMetrics(
|
|
SearchType.BY_NAMESERVER_NAME,
|
|
Optional.of(9L),
|
|
Optional.of(1L),
|
|
IncompletenessWarningType.TRUNCATED);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatch_duplicatesNotTruncated() {
|
|
// 36 nameservers for each of 4 domains; these should translate into two fetches, which should
|
|
// not trigger the truncation warning because all the domains will be duplicates.
|
|
createManyDomainsAndHosts(4, 1, 36);
|
|
rememberWildcardType("ns*.domain1.lol");
|
|
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns*.domain1.lol"))
|
|
.isEqualTo(readMultiDomainFile(
|
|
"rdap_nontruncated_domains.json",
|
|
"domain1.lol",
|
|
"8A-LOL",
|
|
"domain2.lol",
|
|
"89-LOL",
|
|
"domain3.lol",
|
|
"88-LOL",
|
|
"domain4.lol",
|
|
"87-LOL"));
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(4L), Optional.of(36L));
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatch_incompleteResultsSet() {
|
|
createManyDomainsAndHosts(2, 1, 41);
|
|
rememberWildcardType("ns*.domain1.lol");
|
|
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns*.domain1.lol"))
|
|
.isEqualTo(readMultiDomainFile(
|
|
"rdap_incomplete_domains.json",
|
|
"domain1.lol",
|
|
"92-LOL",
|
|
"domain2.lol",
|
|
"91-LOL",
|
|
"x",
|
|
"x",
|
|
"x",
|
|
"x"));
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(
|
|
SearchType.BY_NAMESERVER_NAME,
|
|
Optional.of(2L),
|
|
Optional.of(41L),
|
|
IncompletenessWarningType.MIGHT_BE_INCOMPLETE);
|
|
}
|
|
|
|
@Test
|
|
public void testNameserverMatch_cursorNavigation() throws Exception {
|
|
createManyDomainsAndHosts(8, 1, 2);
|
|
checkCursorNavigation(
|
|
RequestType.NS_LDH_NAME,
|
|
"ns*.domain1.lol",
|
|
ImmutableList.of(
|
|
"domain1.lol",
|
|
"domain2.lol",
|
|
"domain3.lol",
|
|
"domain4.lol",
|
|
"domain5.lol",
|
|
"domain6.lol",
|
|
"domain7.lol",
|
|
"domain8.lol"));
|
|
}
|
|
|
|
@Test
|
|
public void testAddressMatchV4Address_invalidAddress() {
|
|
rememberWildcardType("1.2.3.4.5.6.7.8.9");
|
|
generateActualJson(RequestType.NS_IP, "1.2.3.4.5.6.7.8.9");
|
|
assertThat(response.getStatus()).isEqualTo(400);
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_ADDRESS, Optional.empty(), 400);
|
|
}
|
|
|
|
@Test
|
|
public void testAddressMatchV4Address_foundMultiple() {
|
|
rememberWildcardType("1.2.3.4");
|
|
assertThat(generateActualJson(RequestType.NS_IP, "1.2.3.4"))
|
|
.isEqualTo(generateExpectedJsonForTwoDomains());
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(SearchType.BY_NAMESERVER_ADDRESS, 2, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testAddressMatchV4Address_foundMultiple_sameRegistrarRequested() {
|
|
action.registrarParam = Optional.of("TheRegistrar");
|
|
rememberWildcardType("1.2.3.4");
|
|
assertThat(generateActualJson(RequestType.NS_IP, "1.2.3.4"))
|
|
.isEqualTo(generateExpectedJsonForTwoDomains());
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(SearchType.BY_NAMESERVER_ADDRESS, 2, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testAddressMatchV4Address_notFound_differentRegistrarRequested() {
|
|
action.registrarParam = Optional.of("otherregistrar");
|
|
runNotFoundTest(RequestType.NS_IP, "1.2.3.4", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_ADDRESS, Optional.empty(), Optional.of(0L), 404);
|
|
}
|
|
|
|
@Test
|
|
public void testAddressMatchV6Address_foundOne() {
|
|
runSuccessfulTestWithCatLol(
|
|
RequestType.NS_IP,
|
|
"bad:f00d:cafe:0:0:0:15:beef",
|
|
"rdap_domain_no_contacts_with_remark.json");
|
|
verifyMetrics(SearchType.BY_NAMESERVER_ADDRESS, 1, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testAddressMatchLocalhost_notFound() {
|
|
runNotFoundTest(RequestType.NS_IP, "127.0.0.1", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_ADDRESS, Optional.empty(), Optional.of(0L), 404);
|
|
}
|
|
|
|
// TODO(b/27378695): reenable or delete this test
|
|
@Ignore
|
|
@Test
|
|
public void testAddressMatchDomainsInTestTld_notFound() {
|
|
persistResource(Registry.get("lol").asBuilder().setTldType(Registry.TldType.TEST).build());
|
|
persistResource(Registry.get("example").asBuilder().setTldType(Registry.TldType.TEST).build());
|
|
runNotFoundTest(RequestType.NS_IP, "127.0.0.1", "No matching nameservers found");
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_ADDRESS);
|
|
}
|
|
|
|
@Test
|
|
public void testAddressMatchDeletedDomain_notFound() {
|
|
action.includeDeletedParam = Optional.of(true);
|
|
deleteCatLol();
|
|
runNotFoundTest(RequestType.NS_IP, "bad:f00d:cafe:0:0:0:15:beef", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_ADDRESS, Optional.of(0L), Optional.of(1L), 404);
|
|
}
|
|
|
|
@Test
|
|
public void testAddressMatchDeletedDomain_found_loggedInAsSameRegistrar() {
|
|
login("evilregistrar");
|
|
action.includeDeletedParam = Optional.of(true);
|
|
deleteCatLol();
|
|
runSuccessfulTestWithCatLol(
|
|
RequestType.NS_IP, "bad:f00d:cafe:0:0:0:15:beef", "rdap_domain_deleted.json");
|
|
verifyMetrics(SearchType.BY_NAMESERVER_ADDRESS, 1, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testAddressMatchDeletedDomain_notFound_loggedInAsOtherRegistrar() {
|
|
login("otherregistrar");
|
|
action.includeDeletedParam = Optional.of(true);
|
|
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
|
|
runNotFoundTest(RequestType.NS_IP, "bad:f00d:cafe:0:0:0:15:beef", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_ADDRESS, Optional.of(0L), Optional.of(1L), 404);
|
|
}
|
|
|
|
@Test
|
|
public void testAddressMatchDeletedDomain_found_loggedInAsAdmin() {
|
|
loginAsAdmin();
|
|
action.includeDeletedParam = Optional.of(true);
|
|
deleteCatLol();
|
|
runSuccessfulTestWithCatLol(
|
|
RequestType.NS_IP, "bad:f00d:cafe:0:0:0:15:beef", "rdap_domain_deleted.json");
|
|
verifyMetrics(SearchType.BY_NAMESERVER_ADDRESS, 1, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testAddressMatchOneDeletedDomain_foundTheOther() {
|
|
login("evilregistrar");
|
|
persistDomainAsDeleted(domainCatExample, clock.nowUtc().minusDays(1));
|
|
rememberWildcardType("1.2.3.4");
|
|
assertThat(generateActualJson(RequestType.NS_IP, "1.2.3.4"))
|
|
.isEqualTo(
|
|
generateExpectedJsonForDomain(
|
|
"cat.lol",
|
|
null,
|
|
"C-LOL",
|
|
ImmutableList.of("4-ROID", "6-ROID", "2-ROID"),
|
|
ImmutableList.of("ns1.cat.lol", "ns2.cat.lol"),
|
|
"Yes Virginia <script>",
|
|
"rdap_domain.json"));
|
|
assertThat(response.getStatus()).isEqualTo(200);
|
|
verifyMetrics(SearchType.BY_NAMESERVER_ADDRESS, 1, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testAddressMatchTwoDeletedDomains_notFound() {
|
|
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
|
|
persistDomainAsDeleted(domainCatExample, clock.nowUtc().minusDays(1));
|
|
runNotFoundTest(RequestType.NS_IP, "1.2.3.4", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_ADDRESS, Optional.of(0L), Optional.of(1L), 404);
|
|
}
|
|
|
|
@Test
|
|
public void testAddressMatchDeletedNameserver_notFound() {
|
|
persistResource(hostNs1CatLol.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
|
|
runNotFoundTest(RequestType.NS_IP, "1.2.3.4", "No domains found");
|
|
verifyErrorMetrics(SearchType.BY_NAMESERVER_ADDRESS, Optional.empty(), Optional.of(0L), 404);
|
|
}
|
|
|
|
@Test
|
|
public void testAddressMatch_nontruncatedResultsSet() {
|
|
createManyDomainsAndHosts(4, 1, 2);
|
|
runSuccessfulTestWithFourDomains(
|
|
RequestType.NS_IP,
|
|
"5.5.5.1",
|
|
"46-LOL",
|
|
"45-LOL",
|
|
"44-LOL",
|
|
"43-LOL",
|
|
"rdap_nontruncated_domains.json");
|
|
verifyMetrics(SearchType.BY_NAMESERVER_ADDRESS, 4, 1);
|
|
}
|
|
|
|
@Test
|
|
public void testAddressMatch_truncatedResultsSet() {
|
|
createManyDomainsAndHosts(5, 1, 2);
|
|
runSuccessfulTestWithFourDomains(
|
|
RequestType.NS_IP,
|
|
"5.5.5.1",
|
|
"47-LOL",
|
|
"46-LOL",
|
|
"45-LOL",
|
|
"44-LOL",
|
|
"nsIp=5.5.5.1&cursor=ZG9tYWluNC5sb2w%3D",
|
|
"rdap_domains_four_truncated.json");
|
|
verifyMetrics(
|
|
SearchType.BY_NAMESERVER_ADDRESS,
|
|
Optional.of(5L),
|
|
Optional.of(1L),
|
|
IncompletenessWarningType.TRUNCATED);
|
|
}
|
|
|
|
@Test
|
|
public void testAddressMatch_reallyTruncatedResultsSet() {
|
|
createManyDomainsAndHosts(9, 1, 2);
|
|
runSuccessfulTestWithFourDomains(
|
|
RequestType.NS_IP,
|
|
"5.5.5.1",
|
|
"4B-LOL",
|
|
"4A-LOL",
|
|
"49-LOL",
|
|
"48-LOL",
|
|
"nsIp=5.5.5.1&cursor=ZG9tYWluNC5sb2w%3D",
|
|
"rdap_domains_four_truncated.json");
|
|
verifyMetrics(
|
|
SearchType.BY_NAMESERVER_ADDRESS,
|
|
Optional.of(9L),
|
|
Optional.of(1L),
|
|
IncompletenessWarningType.TRUNCATED);
|
|
}
|
|
|
|
@Test
|
|
public void testAddressMatch_cursorNavigation() throws Exception {
|
|
createManyDomainsAndHosts(7, 1, 2);
|
|
checkCursorNavigation(
|
|
RequestType.NS_IP,
|
|
"5.5.5.1",
|
|
ImmutableList.of(
|
|
"domain1.lol",
|
|
"domain2.lol",
|
|
"domain3.lol",
|
|
"domain4.lol",
|
|
"domain5.lol",
|
|
"domain6.lol",
|
|
"domain7.lol",
|
|
"domain8.lol"));
|
|
}
|
|
}
|