Convert RegistrarServlet to RegistrarAction

Convert to an action and remove ResourceServlet, JsonTransportServlet and
JsonTransportServlet, all of which exist only to support it.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=137519385
This commit is contained in:
mmuller 2016-10-28 09:32:24 -07:00 committed by Ben McIlwain
parent 2e4273c4f4
commit bbd20ec71d
24 changed files with 330 additions and 858 deletions

View file

@ -51,6 +51,12 @@ public final class RequestModuleTest {
provideJsonPayload(MediaType.JSON_UTF_8, "{\"k\":");
}
@Test
public void testProvideJsonPayload_emptyInput_throws500() throws Exception {
thrown.expect(BadRequestException.class, "Malformed JSON");
provideJsonPayload(MediaType.JSON_UTF_8, "");
}
@Test
public void testProvideJsonPayload_nonJsonContentType_throws415() throws Exception {
thrown.expect(UnsupportedMediaTypeException.class);

View file

@ -32,28 +32,10 @@ java_library(
],
)
java_library(
name = "servlets",
srcs = glob(["*ServletTest.java"]),
deps = [
"//java/com/google/common/collect",
"//java/com/google/common/net",
"//third_party/java/junit",
"//third_party/java/mockito",
"//third_party/java/servlet/servlet_api",
"//third_party/java/truth",
"//java/google/registry/request",
"//java/google/registry/security",
"//java/google/registry/security:servlets",
"//javatests/google/registry/testing",
],
)
GenTestRules(
name = "GeneratedTestRules",
test_files = glob(["*Test.java"]),
deps = [
":security",
":servlets",
],
)

View file

@ -43,8 +43,8 @@ public final class JsonHttpTestUtils {
}
/**
* Returns JSON data parsed out of a JsonTransportServlet response stored in the given writer.
* If the data will be fetched multiple times, consider {@link #createJsonResponseSupplier}.
* Returns JSON data parsed out of the contents of the given writer. If the data will be fetched
* multiple times, consider {@link #createJsonResponseSupplier}.
*
* <p>Example Mockito usage:<pre> {@code
*

View file

@ -1,156 +0,0 @@
// Copyright 2016 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.security;
import static com.google.common.net.HttpHeaders.CONTENT_DISPOSITION;
import static com.google.common.net.HttpHeaders.X_CONTENT_TYPE_OPTIONS;
import static com.google.common.net.MediaType.JSON_UTF_8;
import static com.google.common.truth.Truth.assertThat;
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableMap;
import google.registry.request.HttpException;
import google.registry.testing.AppEngineRule;
import google.registry.testing.ExceptionRule;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
/** Unit tests for {@link JsonTransportServlet}. */
@RunWith(MockitoJUnitRunner.class)
public class JsonTransportServletTest {
@Rule
public final AppEngineRule appEngine = AppEngineRule.builder()
.withDatastore()
.build();
@Rule
public final ExceptionRule thrown = new ExceptionRule();
private StringWriter writer = new StringWriter();
@Mock
HttpServletRequest req;
@Mock
HttpServletResponse rsp;
static class TestServlet extends JsonTransportServlet {
private Map<String, Object> responseMap;
TestServlet(Map<String, Object> responseMap) {
super("foo", false);
this.responseMap = responseMap;
}
@Override
public Map<String, Object> doJsonPost(HttpServletRequest req, Map<String, ?> input) {
return responseMap;
}
}
private void verifySuccess(String json) {
verify(rsp).setStatus(SC_OK);
verify(rsp).setHeader(CONTENT_DISPOSITION, "attachment");
verify(rsp).setHeader(X_CONTENT_TYPE_OPTIONS, "nosniff");
verify(rsp).setContentType(JSON_UTF_8.toString());
assertThat(writer.toString()).isEqualTo(")]}'\n" + json);
}
private void doSuccessfulTest(
String requestJson, Map<String, Object> responseMap) throws Exception {
when(req.getMethod()).thenReturn("POST");
when(req.getContentType()).thenReturn(JSON_UTF_8.toString());
when(req.getReader()).thenReturn(new BufferedReader(new StringReader(requestJson)));
when(rsp.getWriter()).thenReturn(new PrintWriter(writer));
new TestServlet(responseMap).doPost(req, rsp);
verifySuccess("{\"a\":1}");
}
private void verifyFailure(int error) throws Exception {
verify(rsp).sendError(eq(error), anyString());
}
@Test
public void testSuccess() throws Exception {
doSuccessfulTest("{\"key\":\"value\"}", ImmutableMap.<String, Object>of("a", 1));
}
@Test
public void testDoJsonPost_returnsNull_notAllowed() throws Exception {
when(req.getMethod()).thenReturn("POST");
when(req.getContentType()).thenReturn(JSON_UTF_8.toString());
when(req.getReader()).thenReturn(new BufferedReader(new StringReader("{\"key\":\"value\"}")));
when(rsp.getWriter()).thenReturn(new PrintWriter(writer));
thrown.expect(NullPointerException.class);
new TestServlet(null).doPost(req, rsp);
}
private void doInvalidRequestTest(String requestJson) throws Exception {
when(req.getMethod()).thenReturn("POST");
when(req.getContentType()).thenReturn(JSON_UTF_8.toString());
when(req.getReader()).thenReturn(new BufferedReader(new StringReader(requestJson)));
new TestServlet(null).doPost(req, rsp);
verifyFailure(SC_BAD_REQUEST);
}
@Test
public void testSuccess_emptyJsonNotAllowed() throws Exception {
doInvalidRequestTest("");
}
@Test
public void testFailure_badJson() throws Exception {
doInvalidRequestTest("{}{}");
}
@Test
public void testFailure_nonObjectJson_null() throws Exception {
doInvalidRequestTest("null");
}
@Test
public void testFailure_nonObjectJson_array() throws Exception {
doInvalidRequestTest("[]");
}
@Test
public void testErrorMessagesAreEscaped() throws Exception {
when(req.getMethod()).thenReturn("POST");
when(req.getReader()).thenReturn(new BufferedReader(new StringReader("{}")));
when(req.getContentType()).thenReturn(JSON_UTF_8.toString());
new TestServlet(null) {
@Override
public Map<String, Object> doJsonPost(HttpServletRequest req, Map<String, ?> input) {
throw new HttpException(123, "<script>", null){};
}}.doPost(req, rsp);
verify(rsp).sendError(123, "&lt;script&gt;");
}
}

View file

@ -1,105 +0,0 @@
// Copyright 2016 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.security;
import static google.registry.security.XsrfTokenManager.X_CSRF_TOKEN;
import static google.registry.security.XsrfTokenManager.generateToken;
import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import google.registry.testing.AppEngineRule;
import google.registry.testing.UserInfo;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
/** Unit tests for {@link XsrfProtectedServlet}. */
@RunWith(MockitoJUnitRunner.class)
public class XsrfProtectedServletTest {
@Rule
public final AppEngineRule appEngine = AppEngineRule.builder()
.withDatastore()
.withUserService(UserInfo.create("test@example.com", "test@example.com"))
.build();
@Mock
HttpServletRequest req;
@Mock
HttpServletResponse rsp;
XsrfProtectedServlet servlet = new XsrfProtectedServlet("foo", false) {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse rsp) {
rsp.setStatus(SC_OK);
}};
String validXsrfToken;
@Before
public void init() {
this.validXsrfToken = generateToken("foo");
}
private void setup(String xsrf, String method) throws Exception {
when(req.getHeader(X_CSRF_TOKEN)).thenReturn(xsrf);
when(req.getMethod()).thenReturn(method);
when(req.getServletPath()).thenReturn("");
}
@Test
public void testSuccess() throws Exception {
setup(validXsrfToken, "post");
servlet.service(req, rsp);
verify(rsp).setStatus(SC_OK);
}
private void doInvalidRequestTest(String xsrf) throws Exception {
setup(xsrf, "post");
servlet.service(req, rsp);
verify(rsp).sendError(eq(SC_FORBIDDEN), anyString());
}
@Test
public void testFailure_badXsrfToken() throws Exception {
doInvalidRequestTest("foo");
}
@Test
public void testFailure_missingXsrfToken() throws Exception {
doInvalidRequestTest(null);
}
@Test
public void testFailure_notAdmin() throws Exception {
setup(validXsrfToken, "post");
new XsrfProtectedServlet("foo", true) {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse rsp) {
rsp.setStatus(SC_OK);
}}.service(req, rsp);
verify(rsp).sendError(eq(SC_FORBIDDEN), anyString());
}
}

View file

@ -79,7 +79,7 @@ public final class RegistryTestServer {
// Registrar Console
route("/registrar", google.registry.module.frontend.FrontendServlet.class),
route("/registrar-settings",
google.registry.ui.server.registrar.RegistrarServlet.class),
google.registry.module.frontend.FrontendServlet.class),
route("/registrar-payment",
google.registry.module.frontend.FrontendServlet.class),
route("/registrar-payment-setup",

View file

@ -32,6 +32,7 @@ java_library(
"//java/google/registry/config",
"//java/google/registry/export/sheet",
"//java/google/registry/model",
"//java/google/registry/request",
"//java/google/registry/security",
"//java/google/registry/ui/server/registrar",
"//java/google/registry/ui/soy/registrar:soy_java_wrappers",

View file

@ -15,10 +15,8 @@
package google.registry.ui.server.registrar;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.security.JsonHttpTestUtils.createJsonPayload;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.DatastoreHelper.persistSimpleResource;
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@ -34,33 +32,31 @@ import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
/**
* Unit tests for contact_settings.js use of {@link RegistrarServlet}.
* Unit tests for contact_settings.js use of {@link RegistrarAction}.
*
* <p>The default read and session validation tests are handled by the
* superclass.
*/
@RunWith(MockitoJUnitRunner.class)
public class ContactSettingsTest extends RegistrarServletTestCase {
public class ContactSettingsTest extends RegistrarActionTestCase {
@Test
public void testPost_readContacts_success() throws Exception {
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "read",
"args", ImmutableMap.of())));
servlet.service(req, rsp);
"args", ImmutableMap.of()));
@SuppressWarnings("unchecked")
List<Map<String, ?>> results = (List<Map<String, ?>>) json.get().get("results");
List<Map<String, ?>> results = (List<Map<String, ?>>) response.get("results");
assertThat(results.get(0).get("contacts"))
.isEqualTo(Registrar.loadByClientId(CLIENT_ID).toJsonMap().get("contacts"));
}
@Test
public void testPost_loadSaveRegistrar_success() throws Exception {
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", Registrar.loadByClientId(CLIENT_ID).toJsonMap())));
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "SUCCESS");
"args", Registrar.loadByClientId(CLIENT_ID).toJsonMap()));
assertThat(response).containsEntry("status", "SUCCESS");
}
@Test
@ -77,11 +73,10 @@ public class ContactSettingsTest extends RegistrarServletTestCase {
Registrar registrar = Registrar.loadByClientId(CLIENT_ID);
Map<String, Object> regMap = registrar.toJsonMap();
regMap.put("contacts", ImmutableList.of(adminContact1));
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", regMap)));
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "SUCCESS");
"args", regMap));
assertThat(response).containsEntry("status", "SUCCESS");
RegistrarContact newContact = new RegistrarContact.Builder()
.setParent(registrar)
@ -102,12 +97,11 @@ public class ContactSettingsTest extends RegistrarServletTestCase {
.asBuilder()
.setTypes(ImmutableList.<RegistrarContact.Type>of())
.build().toJsonMap()));
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", reqJson)));
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "ERROR");
assertThat(json.get()).containsEntry("message", "Must have at least one "
"args", reqJson));
assertThat(response).containsEntry("status", "ERROR");
assertThat(response).containsEntry("message", "Must have at least one "
+ RegistrarContact.Type.ADMIN.getDisplayName() + " contact");
}
@ -127,12 +121,11 @@ public class ContactSettingsTest extends RegistrarServletTestCase {
rc = rc.asBuilder().setPhoneNumber(null).build();
Map<String, Object> reqJson = registrar.toJsonMap();
reqJson.put("contacts", ImmutableList.of(rc.toJsonMap()));
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", reqJson)));
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "ERROR");
assertThat(json.get()).containsEntry("message", "At least one "
"args", reqJson));
assertThat(response).containsEntry("status", "ERROR");
assertThat(response).containsEntry("message", "At least one "
+ RegistrarContact.Type.TECH.getDisplayName() + " contact must have a phone number");
}
}

View file

@ -0,0 +1,125 @@
// Copyright 2016 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.ui.server.registrar;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.TaskQueueHelper.assertNoTasksEnqueued;
import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
import static google.registry.util.ResourceUtils.readResourceUtf8;
import static java.util.Arrays.asList;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableMap;
import google.registry.export.sheet.SyncRegistrarsSheetAction;
import google.registry.model.registrar.Registrar;
import google.registry.testing.ExceptionRule;
import google.registry.testing.TaskQueueHelper.TaskMatcher;
import java.util.Map;
import javax.mail.internet.InternetAddress;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
/** Tests for {@link RegistrarAction}. */
@RunWith(MockitoJUnitRunner.class)
public class RegistrarActionTest extends RegistrarActionTestCase {
@Rule
public final ExceptionRule thrown = new ExceptionRule();
@Test
public void testSuccess_updateRegistrarInfo_andSendsNotificationEmail() throws Exception {
String expectedEmailBody = readResourceUtf8(getClass(), "testdata/update_registrar_email.txt");
action.handleJsonRequest(readJsonFromFile("testdata/update_registrar.json"));
verify(rsp, never()).setStatus(anyInt());
verify(emailService).createMessage();
verify(emailService).sendMessage(message);
assertThat(message.getAllRecipients()).asList().containsExactly(
new InternetAddress("notification@test.example"),
new InternetAddress("notification2@test.example"));
assertThat(message.getContent()).isEqualTo(expectedEmailBody);
assertTasksEnqueued("sheet", new TaskMatcher()
.url(SyncRegistrarsSheetAction.PATH)
.method("GET")
.header("Host", "backend.hostname"));
}
@Test
public void testFailure_updateRegistrarInfo_duplicateContacts() throws Exception {
Map<String, Object> response = action.handleJsonRequest(
readJsonFromFile("testdata/update_registrar_duplicate_contacts.json"));
assertThat(response).containsEntry("status", "ERROR");
assertThat((String) response.get("message")).startsWith("One email address");
}
@Test
public void testRead_notAuthorized_failure() throws Exception {
when(sessionUtils.checkRegistrarConsoleLogin(req)).thenReturn(false);
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of());
assertThat(response).containsEntry("status", "ERROR");
assertThat((String) response.get("message")).startsWith("Not authorized");
assertNoTasksEnqueued("sheet");
}
/**
* This is the default read test for the registrar settings actions.
*/
@Test
public void testRead_authorized_returnsRegistrarJson() throws Exception {
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of());
assertThat(response).containsEntry("status", "SUCCESS");
assertThat(response).containsEntry("results", asList(
Registrar.loadByClientId(CLIENT_ID).toJsonMap()));
}
@Test
public void testUpdate_emptyJsonObject_errorEmailFieldRequired() throws Exception {
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", ImmutableMap.of()));
assertThat(response).containsEntry("status", "ERROR");
assertThat(response).containsEntry("field", "emailAddress");
assertThat(response).containsEntry("message", "This field is required.");
assertNoTasksEnqueued("sheet");
}
@Test
public void testUpdate_badEmail_errorEmailField() throws Exception {
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", ImmutableMap.of(
"emailAddress", "lolcat")));
assertThat(response).containsEntry("status", "ERROR");
assertThat(response).containsEntry("field", "emailAddress");
assertThat(response).containsEntry("message", "Please enter a valid email address.");
assertNoTasksEnqueued("sheet");
}
@Test
public void testPost_nonAsciiCharacters_getsAngry() throws Exception {
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", ImmutableMap.of(
"emailAddress", "ヘ(◕。◕ヘ)@example.com")));
assertThat(response).containsEntry("status", "ERROR");
assertThat(response).containsEntry("field", "emailAddress");
assertThat(response).containsEntry("message", "Please only use ASCII-US characters.");
assertNoTasksEnqueued("sheet");
}
}

View file

@ -17,14 +17,20 @@ package google.registry.ui.server.registrar;
import static google.registry.security.JsonHttpTestUtils.createJsonPayload;
import static google.registry.security.JsonHttpTestUtils.createJsonResponseSupplier;
import static google.registry.security.XsrfTokenManager.generateToken;
import static google.registry.util.ResourceUtils.readResourceUtf8;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.when;
import com.google.appengine.api.modules.ModulesService;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import google.registry.export.sheet.SyncRegistrarsSheetAction;
import google.registry.model.ofy.Ofy;
import google.registry.model.registrar.Registrar;
import google.registry.request.JsonActionRunner;
import google.registry.request.JsonResponse;
import google.registry.request.ResponseImpl;
import google.registry.testing.AppEngineRule;
import google.registry.testing.ExceptionRule;
import google.registry.testing.FakeClock;
@ -41,15 +47,17 @@ import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.joda.time.DateTime;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
import org.junit.Before;
import org.junit.Rule;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
/** Base class for tests using {@link RegistrarServlet}. */
/** Base class for tests using {@link RegistrarAction}. */
@RunWith(MockitoJUnitRunner.class)
public class RegistrarServletTestCase {
public class RegistrarActionTestCase {
static final String CLIENT_ID = "TheRegistrar";
@ -71,26 +79,32 @@ public class RegistrarServletTestCase {
@Mock
HttpServletResponse rsp;
@Mock
SessionUtils sessionUtils;
@Mock
SendEmailService emailService;
@Mock
ModulesService modulesService;
@Mock
SessionUtils sessionUtils;
Message message;
final RegistrarServlet servlet = new RegistrarServlet();
final RegistrarAction action = new RegistrarAction();
final StringWriter writer = new StringWriter();
final Supplier<Map<String, Object>> json = createJsonResponseSupplier(writer);
final FakeClock clock = new FakeClock(DateTime.parse("2014-01-01T00:00:00Z"));
@Before
public void setUp() throws Exception {
action.request = req;
action.sessionUtils = sessionUtils;
action.initialRegistrar = Registrar.loadByClientId(CLIENT_ID);
action.jsonActionRunner = new JsonActionRunner(
ImmutableMap.<String, Object>of(), new JsonResponse(new ResponseImpl(rsp)));
action.registrarChangesNotificationEmailAddresses = ImmutableList.of(
"notification@test.example", "notification2@test.example");
inject.setStaticField(Ofy.class, "clock", clock);
inject.setStaticField(ResourceServlet.class, "sessionUtils", sessionUtils);
inject.setStaticField(SendEmailUtils.class, "emailService", emailService);
inject.setStaticField(SyncRegistrarsSheetAction.class, "modulesService", modulesService);
message = new MimeMessage(Session.getDefaultInstance(new Properties(), null));
@ -105,4 +119,13 @@ public class RegistrarServletTestCase {
when(sessionUtils.getRegistrarClientId(req)).thenReturn(CLIENT_ID);
when(modulesService.getVersionHostname("backend", null)).thenReturn("backend.hostname");
}
protected Map<String, Object> readJsonFromFile(String filename) {
String contents = readResourceUtf8(getClass(), filename);
try {
return (Map<String, Object>) JSONValue.parseWithException(contents);
} catch (ParseException ex) {
throw new RuntimeException(ex);
}
}
}

View file

@ -1,168 +0,0 @@
// Copyright 2016 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.ui.server.registrar;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.security.JsonHttpTestUtils.createJsonPayload;
import static google.registry.testing.TaskQueueHelper.assertNoTasksEnqueued;
import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
import static google.registry.util.ResourceUtils.readResourceUtf8;
import static java.util.Arrays.asList;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableMap;
import google.registry.export.sheet.SyncRegistrarsSheetAction;
import google.registry.model.registrar.Registrar;
import google.registry.testing.TaskQueueHelper.TaskMatcher;
import javax.mail.internet.InternetAddress;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
/** Tests for {@link RegistrarServlet}. */
@RunWith(MockitoJUnitRunner.class)
public class RegistrarServletTest extends RegistrarServletTestCase {
@Test
public void testSuccess_updateRegistrarInfo_andSendsNotificationEmail() throws Exception {
String jsonPostData = readResourceUtf8(getClass(), "testdata/update_registrar.json");
String expectedEmailBody = readResourceUtf8(getClass(), "testdata/update_registrar_email.txt");
when(req.getReader()).thenReturn(createJsonPayload(jsonPostData));
servlet.service(req, rsp);
verify(rsp).setStatus(SC_OK);
verify(emailService).createMessage();
verify(emailService).sendMessage(message);
assertThat(message.getAllRecipients()).asList().containsExactly(
new InternetAddress("notification@test.example"),
new InternetAddress("notification2@test.example"));
assertThat(message.getContent()).isEqualTo(expectedEmailBody);
assertTasksEnqueued("sheet", new TaskMatcher()
.url(SyncRegistrarsSheetAction.PATH)
.method("GET")
.header("Host", "backend.hostname"));
}
@Test
public void testFailure_updateRegistrarInfo_duplicateContacts() throws Exception {
String jsonPostData =
readResourceUtf8(getClass(), "testdata/update_registrar_duplicate_contacts.json");
when(req.getReader()).thenReturn(createJsonPayload(jsonPostData));
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "ERROR");
assertThat((String) json.get().get("message")).startsWith("One email address");
}
@Test
public void testRead_missingXsrfToken_failure() throws Exception {
when(req.getHeader(eq("X-CSRF-Token"))).thenReturn("");
servlet.service(req, rsp);
verify(rsp).sendError(403, "Invalid X-CSRF-Token");
assertNoTasksEnqueued("sheet");
}
@Test
public void testRead_invalidXsrfToken_failure() throws Exception {
when(req.getHeader(eq("X-CSRF-Token"))).thenReturn("humbug");
servlet.service(req, rsp);
verify(rsp).sendError(403, "Invalid X-CSRF-Token");
assertNoTasksEnqueued("sheet");
}
@Test
public void testRead_notLoggedIn_failure() throws Exception {
when(sessionUtils.isLoggedIn()).thenReturn(false);
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "ERROR");
assertThat(json.get()).containsEntry("message", "Not logged in");
assertNoTasksEnqueued("sheet");
}
@Test
public void testRead_notAuthorized_failure() throws Exception {
when(sessionUtils.checkRegistrarConsoleLogin(req)).thenReturn(false);
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "ERROR");
assertThat((String) json.get().get("message")).startsWith("Not authorized");
assertNoTasksEnqueued("sheet");
}
@Test
public void testRead_emptyPayload_failure() throws Exception {
when(req.getReader()).thenReturn(createJsonPayload(""));
servlet.service(req, rsp);
verify(rsp).sendError(400, "Malformed JSON");
assertNoTasksEnqueued("sheet");
}
/**
* This is the default read test for the registrar settings servlets.
*/
@Test
public void testRead_authorized_returnsRegistrarJson() throws Exception {
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "SUCCESS");
assertThat(json.get()).containsEntry("results", asList(
Registrar.loadByClientId(CLIENT_ID).toJsonMap()));
}
@Test
public void testRead_authorized_nilClientId_failure() throws Exception {
String nilClientId = "doesnotexist";
when(sessionUtils.getRegistrarClientId(req)).thenReturn(nilClientId);
servlet.service(req, rsp);
verify(rsp).sendError(404, "No registrar exists with the given client id: " + nilClientId);
}
@Test
public void testUpdate_emptyJsonObject_errorEmailFieldRequired() throws Exception {
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
"op", "update",
"args", ImmutableMap.of())));
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "ERROR");
assertThat(json.get()).containsEntry("field", "emailAddress");
assertThat(json.get()).containsEntry("message", "This field is required.");
assertNoTasksEnqueued("sheet");
}
@Test
public void testUpdate_badEmail_errorEmailField() throws Exception {
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
"op", "update",
"args", ImmutableMap.of(
"emailAddress", "lolcat"))));
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "ERROR");
assertThat(json.get()).containsEntry("field", "emailAddress");
assertThat(json.get()).containsEntry("message", "Please enter a valid email address.");
assertNoTasksEnqueued("sheet");
}
@Test
public void testPost_nonAsciiCharacters_getsAngry() throws Exception {
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
"op", "update",
"args", ImmutableMap.of(
"emailAddress", "ヘ(◕。◕ヘ)@example.com"))));
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "ERROR");
assertThat(json.get()).containsEntry("field", "emailAddress");
assertThat(json.get()).containsEntry("message", "Please only use ASCII-US characters.");
assertNoTasksEnqueued("sheet");
}
}

View file

@ -15,15 +15,12 @@
package google.registry.ui.server.registrar;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.security.JsonHttpTestUtils.createJsonPayload;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT2;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT2_HASH;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT_HASH;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static java.util.Arrays.asList;
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableMap;
import google.registry.config.RegistryEnvironment;
@ -34,31 +31,30 @@ import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
/**
* Unit tests for security_settings.js use of {@link RegistrarServlet}.
* Unit tests for security_settings.js use of {@link RegistrarAction}.
*
* <p>The default read and session validation tests are handled by the
* superclass.
*/
@RunWith(MockitoJUnitRunner.class)
public class SecuritySettingsTest extends RegistrarServletTestCase {
public class SecuritySettingsTest extends RegistrarActionTestCase {
@Test
public void testPost_updateCert_success() throws Exception {
Registrar modified = Registrar.loadByClientId(CLIENT_ID).asBuilder()
.setClientCertificate(SAMPLE_CERT, clock.nowUtc())
.build();
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", modified.toJsonMap())));
servlet.service(req, rsp);
"args", modified.toJsonMap()));
// Empty whoisServer and referralUrl fields should be set to defaults by server.
modified = modified.asBuilder()
.setWhoisServer(RegistryEnvironment.get().config().getRegistrarDefaultWhoisServer())
.setReferralUrl(
RegistryEnvironment.get().config().getRegistrarDefaultReferralUrl().toString())
.build();
assertThat(json.get()).containsEntry("status", "SUCCESS");
assertThat(json.get()).containsEntry("results", asList(modified.toJsonMap()));
assertThat(response).containsEntry("status", "SUCCESS");
assertThat(response).containsEntry("results", asList(modified.toJsonMap()));
assertThat(Registrar.loadByClientId(CLIENT_ID)).isEqualTo(modified);
}
@ -66,12 +62,11 @@ public class SecuritySettingsTest extends RegistrarServletTestCase {
public void testPost_updateCert_failure() throws Exception {
Map<String, Object> reqJson = Registrar.loadByClientId(CLIENT_ID).toJsonMap();
reqJson.put("clientCertificate", "BLAH");
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", reqJson)));
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "ERROR");
assertThat(json.get()).containsEntry("message", "Invalid X.509 PEM certificate");
"args", reqJson));
assertThat(response).containsEntry("status", "ERROR");
assertThat(response).containsEntry("message", "Invalid X.509 PEM certificate");
}
@Test
@ -79,10 +74,9 @@ public class SecuritySettingsTest extends RegistrarServletTestCase {
Map<String, Object> jsonMap = Registrar.loadByClientId(CLIENT_ID).toJsonMap();
jsonMap.put("clientCertificate", SAMPLE_CERT);
jsonMap.put("failoverClientCertificate", null);
when(req.getReader()).thenReturn(
createJsonPayload(ImmutableMap.of("op", "update", "args", jsonMap)));
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "SUCCESS");
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update", "args", jsonMap));
assertThat(response).containsEntry("status", "SUCCESS");
Registrar registrar = Registrar.loadByClientId(CLIENT_ID);
assertThat(registrar.getClientCertificate()).isEqualTo(SAMPLE_CERT);
assertThat(registrar.getClientCertificateHash()).isEqualTo(SAMPLE_CERT_HASH);
@ -94,10 +88,9 @@ public class SecuritySettingsTest extends RegistrarServletTestCase {
public void testChangeFailoverCertificate() throws Exception {
Map<String, Object> jsonMap = Registrar.loadByClientId(CLIENT_ID).toJsonMap();
jsonMap.put("failoverClientCertificate", SAMPLE_CERT2);
when(req.getReader()).thenReturn(
createJsonPayload(ImmutableMap.of("op", "update", "args", jsonMap)));
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "SUCCESS");
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update", "args", jsonMap));
assertThat(response).containsEntry("status", "SUCCESS");
Registrar registrar = Registrar.loadByClientId(CLIENT_ID);
assertThat(registrar.getFailoverClientCertificate()).isEqualTo(SAMPLE_CERT2);
assertThat(registrar.getFailoverClientCertificateHash()).isEqualTo(SAMPLE_CERT2_HASH);
@ -105,18 +98,17 @@ public class SecuritySettingsTest extends RegistrarServletTestCase {
@Test
public void testEmptyOrNullCertificate_doesNotClearOutCurrentOne() throws Exception {
persistResource(
action.initialRegistrar =
Registrar.loadByClientId(CLIENT_ID).asBuilder()
.setClientCertificate(SAMPLE_CERT, START_OF_TIME)
.setFailoverClientCertificate(SAMPLE_CERT2, START_OF_TIME)
.build());
Map<String, Object> jsonMap = Registrar.loadByClientId(CLIENT_ID).toJsonMap();
.build();
Map<String, Object> jsonMap = action.initialRegistrar.toJsonMap();
jsonMap.put("clientCertificate", null);
jsonMap.put("failoverClientCertificate", "");
when(req.getReader()).thenReturn(
createJsonPayload(ImmutableMap.of("op", "update", "args", jsonMap)));
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "SUCCESS");
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update", "args", jsonMap));
assertThat(response).containsEntry("status", "SUCCESS");
Registrar registrar = Registrar.loadByClientId(CLIENT_ID);
assertThat(registrar.getClientCertificate()).isEqualTo(SAMPLE_CERT);
assertThat(registrar.getClientCertificateHash()).isEqualTo(SAMPLE_CERT_HASH);

View file

@ -16,25 +16,24 @@ package google.registry.ui.server.registrar;
import static com.google.common.base.Strings.repeat;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.security.JsonHttpTestUtils.createJsonPayload;
import static java.util.Arrays.asList;
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarAddress;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
/**
* Unit tests for security_settings.js use of {@link RegistrarServlet}.
* Unit tests for security_settings.js use of {@link RegistrarAction}.
*
* <p>The default read and session validation tests are handled by the superclass.
*/
@RunWith(MockitoJUnitRunner.class)
public class WhoisSettingsTest extends RegistrarServletTestCase {
public class WhoisSettingsTest extends RegistrarActionTestCase {
@Test
public void testPost_update_success() throws Exception {
@ -52,12 +51,11 @@ public class WhoisSettingsTest extends RegistrarServletTestCase {
.setCountryCode("US")
.build())
.build();
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", modified.toJsonMap())));
servlet.service(req, rsp);
assertThat(json.get().get("status")).isEqualTo("SUCCESS");
assertThat(json.get().get("results")).isEqualTo(asList(modified.toJsonMap()));
"args", modified.toJsonMap()));
assertThat(response.get("status")).isEqualTo("SUCCESS");
assertThat(response.get("results")).isEqualTo(asList(modified.toJsonMap()));
assertThat(Registrar.loadByClientId(CLIENT_ID)).isEqualTo(modified);
}
@ -75,13 +73,12 @@ public class WhoisSettingsTest extends RegistrarServletTestCase {
.setCountryCode("US")
.build())
.build();
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", modified.toJsonMap())));
servlet.service(req, rsp);
assertThat(json.get().get("status")).isEqualTo("ERROR");
assertThat(json.get().get("field")).isEqualTo("localizedAddress.state");
assertThat(json.get().get("message")).isEqualTo("Unknown US state code.");
"args", modified.toJsonMap()));
assertThat(response.get("status")).isEqualTo("ERROR");
assertThat(response.get("field")).isEqualTo("localizedAddress.state");
assertThat(response.get("message")).isEqualTo("Unknown US state code.");
assertThat(Registrar.loadByClientId(CLIENT_ID)).isNotEqualTo(modified);
}
@ -99,13 +96,12 @@ public class WhoisSettingsTest extends RegistrarServletTestCase {
.setCountryCode("US")
.build())
.build();
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", modified.toJsonMap())));
servlet.service(req, rsp);
assertThat(json.get().get("status")).isEqualTo("ERROR");
assertThat(json.get().get("field")).isEqualTo("localizedAddress.street[1]");
assertThat((String) json.get().get("message"))
"args", modified.toJsonMap()));
assertThat(response.get("status")).isEqualTo("ERROR");
assertThat(response.get("field")).isEqualTo("localizedAddress.street[1]");
assertThat((String) response.get("message"))
.contains("Number of characters (600) not in range");
assertThat(Registrar.loadByClientId(CLIENT_ID)).isNotEqualTo(modified);
}
@ -115,13 +111,12 @@ public class WhoisSettingsTest extends RegistrarServletTestCase {
Registrar modified = Registrar.loadByClientId(CLIENT_ID).asBuilder()
.setWhoisServer("tears@dry.tragical.lol")
.build();
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", modified.toJsonMap())));
servlet.service(req, rsp);
assertThat(json.get().get("status")).isEqualTo("ERROR");
assertThat(json.get().get("field")).isEqualTo("whoisServer");
assertThat(json.get().get("message")).isEqualTo("Not a valid hostname.");
"args", modified.toJsonMap()));
assertThat(response.get("status")).isEqualTo("ERROR");
assertThat(response.get("field")).isEqualTo("whoisServer");
assertThat(response.get("message")).isEqualTo("Not a valid hostname.");
assertThat(Registrar.loadByClientId(CLIENT_ID)).isNotEqualTo(modified);
}
}