google-nomulus/javatests/google/registry/rdap/RdapDomainSearchActionTest.java
mountford 74873f90c8 Order RDAP domain searches by TLD in domain name order
I am not happy that another index is required, but the Pantheon console shows that domain indexes are much smaller than the other indexes (because there are fewer domains), so it's not adding an appreciable amount of storage space.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=173561771
2017-11-07 17:21:26 -05:00

1606 lines
59 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.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.makeDomainResource;
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.loadFileWithSubstitutions;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.google.appengine.api.users.User;
import com.google.common.collect.ImmutableList;
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.DomainResource;
import google.registry.model.domain.Period;
import google.registry.model.host.HostResource;
import google.registry.model.ofy.Ofy;
import google.registry.model.registrar.Registrar;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.HistoryEntry;
import google.registry.request.auth.AuthLevel;
import google.registry.request.auth.AuthResult;
import google.registry.request.auth.UserAuthInfo;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse;
import google.registry.testing.InjectRule;
import google.registry.ui.server.registrar.SessionUtils;
import google.registry.util.Idn;
import java.net.IDN;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.joda.time.DateTime;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
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 {
@Rule
public final AppEngineRule appEngine = AppEngineRule.builder()
.withDatastore()
.build();
@Rule
public final InjectRule inject = new InjectRule();
private final HttpServletRequest request = mock(HttpServletRequest.class);
private final FakeResponse response = new FakeResponse();
private final FakeClock clock = new FakeClock(DateTime.parse("2000-01-01T00:00:00Z"));
private final SessionUtils sessionUtils = mock(SessionUtils.class);
private final User user = new User("rdap.user@example.com", "gmail.com", "12345");
private final UserAuthInfo userAuthInfo = UserAuthInfo.create(user, false);
private final UserAuthInfo adminUserAuthInfo = UserAuthInfo.create(user, true);
private final RdapDomainSearchAction action = new RdapDomainSearchAction();
private Registrar registrar;
private DomainResource domainCatLol;
private DomainResource domainCatLol2;
private DomainResource domainCatExample;
private DomainResource domainIdn;
private DomainResource 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) {
action.requestPath = RdapDomainSearchAction.PATH;
switch (requestType) {
case NAME:
action.nameParam = Optional.of(paramValue);
action.nsLdhNameParam = Optional.empty();
action.nsIpParam = Optional.empty();
break;
case NS_LDH_NAME:
action.nameParam = Optional.empty();
action.nsLdhNameParam = Optional.of(paramValue);
action.nsIpParam = Optional.empty();
break;
case NS_IP:
action.nameParam = Optional.empty();
action.nsLdhNameParam = Optional.empty();
action.nsIpParam = Optional.of(paramValue);
break;
default:
action.nameParam = Optional.empty();
action.nsLdhNameParam = Optional.empty();
action.nsIpParam = Optional.empty();
break;
}
action.rdapResultSetMaxSize = 4;
action.run();
return JSONValue.parse(response.getPayload());
}
private HostResource addHostToMap(HostResource host) {
hostNameToHostMap.put(host.getFullyQualifiedHostName(), host);
return host;
}
@Before
public void setUp() throws Exception {
inject.setStaticField(Ofy.class, "clock", clock);
// cat.lol and cat2.lol
createTld("lol");
registrar = persistResource(
makeRegistrar("evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE));
persistSimpleResources(makeRegistrarContacts(registrar));
domainCatLol = persistResource(
makeDomainResource(
"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(
makeDomainResource(
"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(
makeDomainResource(
"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(
makeDomainResource(
"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(makeDomainResource(
"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.clock = clock;
action.request = request;
action.response = response;
action.registrarParam = Optional.empty();
action.includeDeletedParam = Optional.empty();
action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter();
action.rdapLinkBase = "https://example.com/rdap/";
action.rdapWhoisServer = null;
action.sessionUtils = sessionUtils;
action.authResult = AuthResult.create(AuthLevel.USER, userAuthInfo);
}
private void login(String clientId) {
when(sessionUtils.checkRegistrarConsoleLogin(request, userAuthInfo)).thenReturn(true);
when(sessionUtils.getRegistrarClientId(request)).thenReturn(clientId);
}
private void loginAsAdmin() {
when(sessionUtils.checkRegistrarConsoleLogin(request, adminUserAuthInfo)).thenReturn(true);
when(sessionUtils.getRegistrarClientId(request)).thenReturn("irrelevant");
action.authResult = AuthResult.create(AuthLevel.USER, adminUserAuthInfo);
}
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(loadFileWithSubstitutions(
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 JSONValue.parse(
loadFileWithSubstitutions(
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)
.build()));
}
private Object generateExpectedJson(String name, String expectedOutputFile) {
return generateExpectedJson(name, null, null, null, null, expectedOutputFile);
}
private Object generateExpectedJson(
String name,
String punycodeName,
String handle,
@Nullable List<String> contactRoids,
@Nullable List<String> nameservers,
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)));
}
}
return JSONValue.parse(
loadFileWithSubstitutions(
this.getClass(), expectedOutputFile, substitutionsBuilder.build()));
}
private Object generateExpectedJsonForDomain(
String name,
String punycodeName,
String handle,
@Nullable List<String> contactRoids,
@Nullable List<String> nameservers,
String expectedOutputFile) {
Object obj =
generateExpectedJson(
name, punycodeName, handle, contactRoids, nameservers, expectedOutputFile);
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
builder.put("domainSearchResults", ImmutableList.of(obj));
builder.put("rdapConformance", ImmutableList.of("rdap_level_0"));
RdapTestHelper.addNotices(builder, "https://example.com/rdap/");
RdapTestHelper.addDomainBoilerplateRemarks(builder);
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<DomainResource> domainsBuilder = new ImmutableList.Builder<>();
for (int i = numActiveDomains * numTotalDomainsPerActiveDomain; i >= 1; i--) {
String domainName = String.format("domain%d.lol", i);
DomainResource.Builder builder =
makeDomainResource(
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 JSONValue.parse(loadFileWithSubstitutions(
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)
.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"),
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"),
fileName);
}
private void runSuccessfulTest(
RequestType requestType,
String queryString,
String name,
String punycodeName,
String handle,
@Nullable List<String> contactRoids,
@Nullable List<String> nameservers,
String fileName) {
assertThat(generateActualJson(requestType, queryString))
.isEqualTo(
generateExpectedJsonForDomain(
name, punycodeName, handle, contactRoids, nameservers, fileName));
assertThat(response.getStatus()).isEqualTo(200);
}
private void runSuccessfulTestWithFourDomains(
RequestType requestType,
String queryString,
String domainRoid1,
String domainRoid2,
String domainRoid3,
String domainRoid4,
String fileName) {
assertThat(generateActualJson(requestType, queryString))
.isEqualTo(
readMultiDomainFile(
fileName,
"domain1.lol",
domainRoid1,
"domain2.lol",
domainRoid2,
"domain3.lol",
domainRoid3,
"domain4.lol",
domainRoid4));
assertThat(response.getStatus()).isEqualTo(200);
}
private void runNotFoundTest(RequestType requestType, String fullName, String errorMessage) {
assertThat(generateActualJson(requestType, fullName))
.isEqualTo(generateExpectedJson(errorMessage, "rdap_error_404.json"));
assertThat(response.getStatus()).isEqualTo(404);
}
@Test
public void testInvalidPath_rejected() throws Exception {
action.requestPath = RdapDomainSearchAction.PATH + "/path";
action.run();
assertThat(response.getStatus()).isEqualTo(400);
}
@Test
public void testInvalidRequest_rejected() throws Exception {
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);
}
@Test
public void testInvalidWildcard_rejected() throws Exception {
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);
}
@Test
public void testMultipleWildcards_rejected() throws Exception {
assertThat(generateActualJson(RequestType.NAME, "*.*"))
.isEqualTo(generateExpectedJson("Only one wildcard allowed", "rdap_error_422.json"));
assertThat(response.getStatus()).isEqualTo(422);
}
@Test
public void testNoCharactersToMatch_rejected() throws Exception {
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);
}
@Test
public void testFewerThanTwoCharactersToMatch_rejected() throws Exception {
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);
}
@Test
public void testDomainMatch_found() throws Exception {
login("evilregistrar");
runSuccessfulTestWithCatLol(RequestType.NAME, "cat.lol", "rdap_domain.json");
}
@Test
public void testDomainMatch_foundWithUpperCase() throws Exception {
login("evilregistrar");
runSuccessfulTestWithCatLol(RequestType.NAME, "CaT.lOl", "rdap_domain.json");
}
@Test
public void testDomainMatch_found_sameRegistrarRequested() throws Exception {
login("evilregistrar");
action.registrarParam = Optional.of("evilregistrar");
runSuccessfulTestWithCatLol(RequestType.NAME, "cat.lol", "rdap_domain.json");
}
@Test
public void testDomainMatch_notFound_differentRegistrarRequested() throws Exception {
action.registrarParam = Optional.of("otherregistrar");
runNotFoundTest(RequestType.NAME, "cat.lol", "No domains found");
}
@Test
public void testDomainMatch_found_asAdministrator() throws Exception {
loginAsAdmin();
runSuccessfulTestWithCatLol(RequestType.NAME, "cat.lol", "rdap_domain.json");
}
@Test
public void testDomainMatch_found_loggedInAsOtherRegistrar() throws Exception {
login("otherregistrar");
runSuccessfulTestWithCatLol(
RequestType.NAME, "cat.lol", "rdap_domain_no_contacts_with_remark.json");
}
/*
* 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() throws Exception {
runNotFoundTest(RequestType.NAME, "cat.lol.", "No domains found");
}
@Test
public void testDomainMatch_cat2_lol_found() throws Exception {
login("evilregistrar");
runSuccessfulTestWithCat2Lol(RequestType.NAME, "cat2.lol", "rdap_domain_cat2.json");
}
@Test
public void testDomainMatch_cat_example_found() throws Exception {
login("evilregistrar");
runSuccessfulTest(
RequestType.NAME,
"cat.example",
"cat.example",
null,
"21-EXAMPLE",
null,
ImmutableList.of("ns1.cat.lol", "ns2.external.tld"),
"rdap_domain_no_contacts_with_remark.json");
}
@Test
public void testDomainMatch_cat_idn_unicode_found() throws Exception {
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");
}
@Test
public void testDomainMatch_cat_idn_punycode_found() throws Exception {
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");
}
@Test
public void testDomainMatch_cat_1_test_found() throws Exception {
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"),
"rdap_domain_no_contacts_with_remark.json");
}
@Test
public void testDomainMatch_castar_1_test_found() throws Exception {
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"),
"rdap_domain_no_contacts_with_remark.json");
}
@Test
public void testDomainMatch_castar_test_notFound() throws Exception {
runNotFoundTest(RequestType.NAME, "ca*.test", "No domains found");
}
@Test
public void testDomainMatch_catstar_lol_found() throws Exception {
assertThat(generateActualJson(RequestType.NAME, "cat*.lol"))
.isEqualTo(generateExpectedJsonForTwoDomains("cat.lol", "C-LOL", "cat2.lol", "17-LOL"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testDomainMatch_cstar_lol_found() throws Exception {
assertThat(generateActualJson(RequestType.NAME, "c*.lol"))
.isEqualTo(generateExpectedJsonForTwoDomains("cat.lol", "C-LOL", "cat2.lol", "17-LOL"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testDomainMatch_qstar_lol_notFound() throws Exception {
runNotFoundTest(RequestType.NAME, "q*.lol", "No domains found");
}
@Test
public void testDomainMatch_star_lol_found() throws Exception {
assertThat(generateActualJson(RequestType.NAME, "*.lol"))
.isEqualTo(generateExpectedJsonForTwoDomains("cat.lol", "C-LOL", "cat2.lol", "17-LOL"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testDomainMatch_star_lol_found_sameRegistrarRequested() throws Exception {
action.registrarParam = Optional.of("evilregistrar");
assertThat(generateActualJson(RequestType.NAME, "*.lol"))
.isEqualTo(generateExpectedJsonForTwoDomains("cat.lol", "C-LOL", "cat2.lol", "17-LOL"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testDomainMatch_star_lol_notFound_differentRegistrarRequested() throws Exception {
action.registrarParam = Optional.of("otherregistrar");
runNotFoundTest(RequestType.NAME, "*.lol", "No domains found");
}
@Test
public void testDomainMatch_cat_star_found() throws Exception {
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);
}
@Test
public void testDomainMatch_cat_star_foundOne_sameRegistrarRequested() throws Exception {
login("evilregistrar");
action.registrarParam = Optional.of("evilregistrar");
runSuccessfulTestWithCatLol(RequestType.NAME, "cat.*", "rdap_domain.json");
}
@Test
public void testDomainMatch_cat_star_notFound_differentRegistrarRequested() throws Exception {
action.registrarParam = Optional.of("otherregistrar");
runNotFoundTest(RequestType.NAME, "cat.*", "No domains found");
}
@Test
public void testDomainMatch_cat_lstar_found() throws Exception {
login("evilregistrar");
runSuccessfulTestWithCatLol(RequestType.NAME, "cat.l*", "rdap_domain.json");
}
@Test
public void testDomainMatch_catstar_found() throws Exception {
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_truncated.json"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testDomainMatchWithWildcardAndEmptySuffix_fails() throws Exception {
// 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.
generateActualJson(RequestType.NAME, "exam*..");
assertThat(response.getStatus()).isIn(Range.closed(400, 499));
}
@Test
public void testDomainMatch_dog_notFound() throws Exception {
runNotFoundTest(RequestType.NAME, "dog*", "No domains found");
}
@Test
public void testDomainMatchDeletedDomain_notFound() throws Exception {
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
runNotFoundTest(RequestType.NAME, "cat.lol", "No domains found");
}
@Test
public void testDomainMatchDeletedDomain_notFound_deletedNotRequested() throws Exception {
login("evilregistrar");
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
runNotFoundTest(RequestType.NAME, "cat.lol", "No domains found");
}
@Test
public void testDomainMatchDeletedDomain_found_loggedInAsSameRegistrar() throws Exception {
login("evilregistrar");
action.includeDeletedParam = Optional.of(true);
deleteCatLol();
runSuccessfulTestWithCatLol(RequestType.NAME, "cat.lol", "rdap_domain_deleted.json");
}
@Test
public void testDomainMatchDeletedDomain_notFound_loggedInAsOtherRegistrar() throws Exception {
login("otherregistrar");
action.includeDeletedParam = Optional.of(true);
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
runNotFoundTest(RequestType.NAME, "cat.lol", "No domains found");
}
@Test
public void testDomainMatchDeletedDomain_found_loggedInAsAdmin() throws Exception {
loginAsAdmin();
action.includeDeletedParam = Optional.of(true);
deleteCatLol();
runSuccessfulTestWithCatLol(RequestType.NAME, "cat.lol", "rdap_domain_deleted.json");
}
@Test
public void testDomainMatchDeletedDomainWithWildcard_notFound() throws Exception {
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
runNotFoundTest(RequestType.NAME, "cat.lo*", "No domains found");
}
@Test
public void testDomainMatchDeletedDomainsWithWildcardAndTld_notFound() throws Exception {
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
persistDomainAsDeleted(domainCatLol2, clock.nowUtc().minusDays(1));
runNotFoundTest(RequestType.NAME, "cat*.lol", "No domains found");
}
// TODO(b/27378695): reenable or delete this test
@Ignore
@Test
public void testDomainMatchDomainInTestTld_notFound() throws Exception {
persistResource(Registry.get("lol").asBuilder().setTldType(Registry.TldType.TEST).build());
runNotFoundTest(RequestType.NAME, "cat.lol", "No domains found");
}
@Test
public void testDomainMatch_manyDeletedDomains_fullResultSet() throws Exception {
// There are enough domains to fill a full result set; deleted domains are ignored.
createManyDomainsAndHosts(4, 4, 2);
Object obj = generateActualJson(RequestType.NAME, "domain*.lol");
assertThat(response.getStatus()).isEqualTo(200);
checkNumberOfDomainsInResult(obj, 4);
}
@Test
public void testDomainMatch_manyDeletedDomains_partialResultSetDueToInsufficientDomains()
throws Exception {
// There are not enough domains to fill a full result set.
createManyDomainsAndHosts(3, 20, 2);
Object obj = generateActualJson(RequestType.NAME, "domain*.lol");
assertThat(response.getStatus()).isEqualTo(200);
checkNumberOfDomainsInResult(obj, 3);
}
@Test
public void testDomainMatch_manyDeletedDomains_partialResultSetDueToFetchingLimit()
throws Exception {
// 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);
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);
}
@Test
public void testDomainMatch_nontruncatedResultsSet() throws Exception {
createManyDomainsAndHosts(4, 1, 2);
runSuccessfulTestWithFourDomains(
RequestType.NAME,
"domain*.lol",
"46-LOL",
"45-LOL",
"44-LOL",
"43-LOL",
"rdap_nontruncated_domains.json");
}
@Test
public void testDomainMatch_truncatedResultsSet() throws Exception {
createManyDomainsAndHosts(5, 1, 2);
runSuccessfulTestWithFourDomains(
RequestType.NAME,
"domain*.lol",
"47-LOL",
"46-LOL",
"45-LOL",
"44-LOL",
"rdap_domains_four_truncated.json");
}
@Test
public void testDomainMatch_tldSearchOrderedProperly() throws Exception {
createManyDomainsAndHosts(4, 1, 2);
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"));
}
@Test
public void testDomainMatch_reallyTruncatedResultsSet() throws Exception {
// 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",
"rdap_domains_four_truncated.json");
}
@Test
public void testDomainMatch_truncatedResultsAfterMultipleChunks() throws Exception {
createManyDomainsAndHosts(5, 6, 2);
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"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testNameserverMatch_foundMultiple() throws Exception {
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns1.cat.lol"))
.isEqualTo(generateExpectedJsonForTwoDomains());
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testNameserverMatch_foundMultiple_sameRegistrarRequested() throws Exception {
action.registrarParam = Optional.of("TheRegistrar");
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns1.cat.lol"))
.isEqualTo(generateExpectedJsonForTwoDomains());
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testNameserverMatch_notFound_differentRegistrarRequested() throws Exception {
action.registrarParam = Optional.of("otherregistrar");
runNotFoundTest(RequestType.NS_LDH_NAME, "ns1.cat.lol", "No matching nameservers found");
}
@Test
public void testNameserverMatchWithWildcard_found() throws Exception {
login("evilregistrar");
runSuccessfulTestWithCatLol(RequestType.NS_LDH_NAME, "ns2.cat.l*", "rdap_domain.json");
}
@Test
public void testNameserverMatchWithWildcard_found_sameRegistrarRequested() throws Exception {
login("evilregistrar");
action.registrarParam = Optional.of("TheRegistrar");
runSuccessfulTestWithCatLol(RequestType.NS_LDH_NAME, "ns2.cat.l*", "rdap_domain.json");
}
@Test
public void testNameserverMatchWithWildcard_notFound_differentRegistrarRequested()
throws Exception {
action.registrarParam = Optional.of("otherregistrar");
runNotFoundTest(RequestType.NS_LDH_NAME, "ns2.cat.l*", "No matching nameservers found");
}
@Test
public void testNameserverMatchWithWildcardAndDomainSuffix_notFound() throws Exception {
runNotFoundTest(RequestType.NS_LDH_NAME, "ns5*.cat.lol", "No matching nameservers found");
}
@Test
public void testNameserverMatchWithNoPrefixAndDomainSuffix_found() throws Exception {
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "*.cat.lol"))
.isEqualTo(generateExpectedJsonForTwoDomains());
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testNameserverMatchWithOneCharacterPrefixAndDomainSuffix_found()
throws Exception {
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "n*.cat.lol"))
.isEqualTo(generateExpectedJsonForTwoDomains());
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void
testNameserverMatchWithOneCharacterPrefixAndDomainSuffix_found_sameRegistrarRequested()
throws Exception {
action.registrarParam = Optional.of("TheRegistrar");
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "n*.cat.lol"))
.isEqualTo(generateExpectedJsonForTwoDomains());
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testNameserverMatchWithPrefixAndDomainSuffix_notFound_differentRegistrarRequested()
throws Exception {
action.registrarParam = Optional.of("otherregistrar");
runNotFoundTest(RequestType.NS_LDH_NAME, "n*.cat.lol", "No matching nameservers found");
}
@Test
public void testNameserverMatchWithTwoCharacterPrefixAndDomainSuffix_found()
throws Exception {
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns*.cat.lol"))
.isEqualTo(generateExpectedJsonForTwoDomains());
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testNameserverMatchWithWildcardAndEmptySuffix_unprocessable() throws Exception {
generateActualJson(RequestType.NS_LDH_NAME, "ns*.");
assertThat(response.getStatus()).isEqualTo(422);
}
@Test
public void testNameserverMatchWithWildcardAndInvalidSuffix_unprocessable() throws Exception {
generateActualJson(RequestType.NS_LDH_NAME, "ns*.google.com");
assertThat(response.getStatus()).isEqualTo(422);
}
@Test
public void testNameserverMatch_ns2_cat_lol_found() throws Exception {
login("evilregistrar");
runSuccessfulTestWithCatLol(RequestType.NS_LDH_NAME, "ns2.cat.lol", "rdap_domain.json");
}
@Test
public void testNameserverMatch_ns2_dog_lol_found() throws Exception {
login("evilregistrar");
runSuccessfulTestWithCat2Lol(RequestType.NS_LDH_NAME, "ns2.dog.lol", "rdap_domain_cat2.json");
}
@Test
public void testNameserverMatch_ns1_cat_idn_unicode_badRequest() throws Exception {
// nsLdhName must use punycode.
generateActualJson(RequestType.NS_LDH_NAME, "ns1.cat.みんな");
assertThat(response.getStatus()).isEqualTo(400);
}
@Test
public void testNameserverMatch_ns1_cat_idn_punycode_found() throws Exception {
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");
}
@Test
public void testNameserverMatch_ns1_cat_1_test_found() throws Exception {
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"),
"rdap_domain_no_contacts_with_remark.json");
}
@Test
public void testNameserverMatch_nsstar_cat_1_test_found() throws Exception {
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"),
"rdap_domain_no_contacts_with_remark.json");
}
@Test
public void testNameserverMatch_nsstar_test_unprocessable() throws Exception {
generateActualJson(RequestType.NS_LDH_NAME, "ns*.1.test");
assertThat(response.getStatus()).isEqualTo(422);
}
@Test
public void testNameserverMatchMissing_notFound() throws Exception {
runNotFoundTest(RequestType.NS_LDH_NAME, "ns1.missing.com", "No matching nameservers found");
}
// TODO(b/27378695): reenable or delete this test
@Ignore
@Test
public void testNameserverMatchDomainsInTestTld_notFound() throws Exception {
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() throws Exception {
action.includeDeletedParam = Optional.of(true);
deleteCatLol();
runNotFoundTest(RequestType.NS_LDH_NAME, "ns2.cat.lol", "No domains found");
}
@Test
public void testNameserverMatchDeletedDomain_found_loggedInAsSameRegistrar() throws Exception {
login("evilregistrar");
action.includeDeletedParam = Optional.of(true);
deleteCatLol();
runSuccessfulTestWithCatLol(RequestType.NS_LDH_NAME, "ns2.cat.lol", "rdap_domain_deleted.json");
}
@Test
public void testNameserverMatchDeletedDomain_notFound_loggedInAsOtherRegistrar()
throws Exception {
login("otherregistrar");
action.includeDeletedParam = Optional.of(true);
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
runNotFoundTest(RequestType.NS_LDH_NAME, "ns2.cat.lol", "No domains found");
}
@Test
public void testNameserverMatchDeletedDomain_found_loggedInAsAdmin() throws Exception {
loginAsAdmin();
action.includeDeletedParam = Optional.of(true);
deleteCatLol();
runSuccessfulTestWithCatLol(RequestType.NS_LDH_NAME, "ns2.cat.lol", "rdap_domain_deleted.json");
}
@Test
public void testNameserverMatchOneDeletedDomain_foundTheOther() throws Exception {
login("evilregistrar");
persistDomainAsDeleted(domainCatExample, clock.nowUtc().minusDays(1));
runSuccessfulTestWithCatLol(RequestType.NS_LDH_NAME, "ns1.cat.lol", "rdap_domain.json");
}
@Test
public void testNameserverMatchTwoDeletedDomains_notFound() throws Exception {
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
persistDomainAsDeleted(domainCatExample, clock.nowUtc().minusDays(1));
runNotFoundTest(RequestType.NS_LDH_NAME, "ns1.cat.lol", "No domains found");
}
@Test
public void testNameserverMatchDeletedNameserver_notFound() throws Exception {
persistResource(
hostNs1CatLol.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
runNotFoundTest(RequestType.NS_LDH_NAME, "ns1.cat.lol", "No matching nameservers found");
}
@Test
public void testNameserverMatchDeletedNameserverWithWildcard_notFound() throws Exception {
persistResource(
hostNs1CatLol.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
runNotFoundTest(RequestType.NS_LDH_NAME, "ns1.cat.l*", "No matching nameservers found");
}
@Test
public void testNameserverMatchDeletedNameserverWithWildcardAndSuffix_notFound()
throws Exception {
persistResource(
hostNs1CatLol.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
runNotFoundTest(RequestType.NS_LDH_NAME, "ns1*.cat.lol", "No matching nameservers found");
}
@Test
public void testNameserverMatchManyNameserversForTheSameDomains() throws Exception {
// 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);
Object obj = generateActualJson(RequestType.NS_LDH_NAME, "ns1.domain1.lol");
assertThat(response.getStatus()).isEqualTo(200);
checkNumberOfDomainsInResult(obj, 3);
}
@Test
public void testNameserverMatchManyNameserversForTheSameDomainsWithWildcard() throws Exception {
// Same as above, except with a wildcard (that still only finds one nameserver).
createManyDomainsAndHosts(3, 1, 40);
Object obj = generateActualJson(RequestType.NS_LDH_NAME, "ns1.domain1.l*");
assertThat(response.getStatus()).isEqualTo(200);
checkNumberOfDomainsInResult(obj, 3);
}
@Test
public void testNameserverMatchManyNameserversForTheSameDomainsWithSuffix() throws Exception {
// Same as above, except that we find all 40 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, 40);
Object obj = generateActualJson(RequestType.NS_LDH_NAME, "ns*.domain1.lol");
assertThat(response.getStatus()).isEqualTo(200);
checkNumberOfDomainsInResult(obj, 3);
}
@Test
public void testNameserverMatch_nontruncatedResultsSet() throws Exception {
createManyDomainsAndHosts(4, 1, 2);
runSuccessfulTestWithFourDomains(
RequestType.NS_LDH_NAME,
"ns1.domain1.lol",
"46-LOL",
"45-LOL",
"44-LOL",
"43-LOL",
"rdap_nontruncated_domains.json");
}
@Test
public void testNameserverMatch_truncatedResultsSet() throws Exception {
createManyDomainsAndHosts(5, 1, 2);
runSuccessfulTestWithFourDomains(
RequestType.NS_LDH_NAME,
"ns1.domain1.lol",
"47-LOL",
"46-LOL",
"45-LOL",
"44-LOL",
"rdap_domains_four_truncated.json");
}
@Test
public void testNameserverMatch_reallyTruncatedResultsSet() throws Exception {
createManyDomainsAndHosts(9, 1, 2);
runSuccessfulTestWithFourDomains(
RequestType.NS_LDH_NAME,
"ns1.domain1.lol",
"4B-LOL",
"4A-LOL",
"49-LOL",
"48-LOL",
"rdap_domains_four_truncated.json");
}
@Test
public void testNameserverMatch_duplicatesNotTruncated() throws Exception {
// 60 nameservers for each of 4 domains; these should translate into 2 30-nameserver domain
// fetches, which should _not_ trigger the truncation warning because all the domains will be
// duplicates.
createManyDomainsAndHosts(4, 1, 60);
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns*.domain1.lol"))
.isEqualTo(readMultiDomainFile(
"rdap_nontruncated_domains.json",
"domain1.lol",
"BA-LOL",
"domain2.lol",
"B9-LOL",
"domain3.lol",
"B8-LOL",
"domain4.lol",
"B7-LOL"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testNameserverMatch_incompleteResultsSet() throws Exception {
createManyDomainsAndHosts(2, 1, 2500);
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns*.domain1.lol"))
.isEqualTo(readMultiDomainFile(
"rdap_incomplete_domains.json",
"domain1.lol",
"13C8-LOL",
"domain2.lol",
"13C7-LOL",
"x",
"x",
"x",
"x"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testAddressMatchV4Address_invalidAddress() throws Exception {
generateActualJson(RequestType.NS_IP, "1.2.3.4.5.6.7.8.9");
assertThat(response.getStatus()).isEqualTo(400);
}
@Test
public void testAddressMatchV4Address_foundMultiple() throws Exception {
assertThat(generateActualJson(RequestType.NS_IP, "1.2.3.4"))
.isEqualTo(generateExpectedJsonForTwoDomains());
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testAddressMatchV4Address_foundMultiple_sameRegistrarRequested() throws Exception {
action.registrarParam = Optional.of("TheRegistrar");
assertThat(generateActualJson(RequestType.NS_IP, "1.2.3.4"))
.isEqualTo(generateExpectedJsonForTwoDomains());
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testAddressMatchV4Address_notFound_differentRegistrarRequested() throws Exception {
action.registrarParam = Optional.of("otherregistrar");
runNotFoundTest(RequestType.NS_IP, "1.2.3.4", "No domains found");
}
@Test
public void testAddressMatchV6Address_foundOne() throws Exception {
runSuccessfulTestWithCatLol(
RequestType.NS_IP,
"bad:f00d:cafe:0:0:0:15:beef",
"rdap_domain_no_contacts_with_remark.json");
}
@Test
public void testAddressMatchLocalhost_notFound() throws Exception {
runNotFoundTest(RequestType.NS_IP, "127.0.0.1", "No domains found");
}
// TODO(b/27378695): reenable or delete this test
@Ignore
@Test
public void testAddressMatchDomainsInTestTld_notFound() throws Exception {
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");
}
@Test
public void testAddressMatchDeletedDomain_notFound() throws Exception {
action.includeDeletedParam = Optional.of(true);
deleteCatLol();
runNotFoundTest(RequestType.NS_IP, "bad:f00d:cafe:0:0:0:15:beef", "No domains found");
}
@Test
public void testAddressMatchDeletedDomain_found_loggedInAsSameRegistrar() throws Exception {
login("evilregistrar");
action.includeDeletedParam = Optional.of(true);
deleteCatLol();
runSuccessfulTestWithCatLol(
RequestType.NS_IP, "bad:f00d:cafe:0:0:0:15:beef", "rdap_domain_deleted.json");
}
@Test
public void testAddressMatchDeletedDomain_notFound_loggedInAsOtherRegistrar() throws Exception {
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");
}
@Test
public void testAddressMatchDeletedDomain_found_loggedInAsAdmin() throws Exception {
loginAsAdmin();
action.includeDeletedParam = Optional.of(true);
deleteCatLol();
runSuccessfulTestWithCatLol(
RequestType.NS_IP, "bad:f00d:cafe:0:0:0:15:beef", "rdap_domain_deleted.json");
}
@Test
public void testAddressMatchOneDeletedDomain_foundTheOther() throws Exception {
login("evilregistrar");
persistDomainAsDeleted(domainCatExample, clock.nowUtc().minusDays(1));
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"),
"rdap_domain.json"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testAddressMatchTwoDeletedDomains_notFound() throws Exception {
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
persistDomainAsDeleted(domainCatExample, clock.nowUtc().minusDays(1));
runNotFoundTest(RequestType.NS_IP, "1.2.3.4", "No domains found");
}
@Test
public void testAddressMatchDeletedNameserver_notFound() throws Exception {
persistResource(hostNs1CatLol.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
runNotFoundTest(RequestType.NS_IP, "1.2.3.4", "No domains found");
}
@Test
public void testAddressMatch_nontruncatedResultsSet() throws Exception {
createManyDomainsAndHosts(4, 1, 2);
runSuccessfulTestWithFourDomains(
RequestType.NS_IP,
"5.5.5.1",
"46-LOL",
"45-LOL",
"44-LOL",
"43-LOL",
"rdap_nontruncated_domains.json");
}
@Test
public void testAddressMatch_truncatedResultsSet() throws Exception {
createManyDomainsAndHosts(5, 1, 2);
runSuccessfulTestWithFourDomains(
RequestType.NS_IP,
"5.5.5.1",
"47-LOL",
"46-LOL",
"45-LOL",
"44-LOL",
"rdap_domains_four_truncated.json");
}
@Test
public void testAddressMatch_reallyTruncatedResultsSet() throws Exception {
createManyDomainsAndHosts(9, 1, 2);
runSuccessfulTestWithFourDomains(
RequestType.NS_IP,
"5.5.5.1",
"4B-LOL",
"4A-LOL",
"49-LOL",
"48-LOL",
"rdap_domains_four_truncated.json");
}
}