mv com/google/domain/registry google/registry

This change renames directories in preparation for the great package
rename. The repository is now in a broken state because the code
itself hasn't been updated. However this should ensure that git
correctly preserves history for each file.
This commit is contained in:
Justine Tunney 2016-05-13 18:55:08 -04:00
parent a41677aea1
commit 5012893c1d
2396 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,23 @@
package(default_visibility = ["//java/com/google/domain/registry:registry_project"])
load("//java/com/google/testing/builddefs:GenTestRules.bzl", "GenTestRules")
java_library(
name = "server",
srcs = glob(["*.java"]),
deps = [
"//java/com/google/domain/registry/ui/forms",
"//java/com/google/domain/registry/ui/server",
"//javatests/com/google/domain/registry/testing",
"//third_party/java/hamcrest",
"//third_party/java/junit",
"//third_party/java/truth",
],
)
GenTestRules(
name = "GeneratedTestRules",
test_files = glob(["*Test.java"]),
deps = [":server"],
)

View file

@ -0,0 +1,65 @@
// Copyright 2016 The Domain Registry 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 com.google.domain.registry.ui.server;
import static com.google.common.truth.Truth.assertThat;
import static org.hamcrest.Matchers.equalTo;
import com.google.domain.registry.testing.CertificateSamples;
import com.google.domain.registry.ui.forms.FormFieldException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link RegistrarFormFields}. */
@RunWith(JUnit4.class)
public class RegistrarFormFieldsTest {
@Rule
public final ExpectedException thrown = ExpectedException.none();
@Test
public void testValidCertificate_doesntThrowError() {
assertThat(RegistrarFormFields.CLIENT_CERTIFICATE_FIELD.convert(CertificateSamples.SAMPLE_CERT))
.hasValue(CertificateSamples.SAMPLE_CERT);
}
@Test
public void testBadCertificate_throwsFfe() {
thrown.expect(equalTo(
new FormFieldException("Invalid X.509 PEM certificate")
.propagate("clientCertificate")));
RegistrarFormFields.CLIENT_CERTIFICATE_FIELD.convert("palfun");
}
@Test
public void testValidCertificateHash_doesntThrowError() {
assertThat(
RegistrarFormFields.CLIENT_CERTIFICATE_HASH_FIELD.convert(
CertificateSamples.SAMPLE_CERT_HASH))
.hasValue(CertificateSamples.SAMPLE_CERT_HASH);
}
@Test
public void testBadCertificateHash_throwsFfe() {
thrown.expect(equalTo(
new FormFieldException("Field must contain a base64 value.")
.propagate("clientCertificateHash")));
RegistrarFormFields.CLIENT_CERTIFICATE_HASH_FIELD.convert("~~~");
}
}

View file

@ -0,0 +1,27 @@
package(default_visibility = ["//java/com/google/domain/registry:registry_project"])
load("//java/com/google/testing/builddefs:GenTestRules.bzl", "GenTestRules")
java_library(
name = "api",
srcs = glob(["*.java"]),
deps = [
"//java/com/google/common/collect",
"//java/com/google/domain/registry/model",
"//java/com/google/domain/registry/ui/server/api",
"//javatests/com/google/domain/registry/testing",
"//third_party/java/appengine:appengine-api-testonly",
"//third_party/java/json_simple",
"//third_party/java/junit",
"//third_party/java/mockito",
"//third_party/java/servlet/servlet_api",
"//third_party/java/truth",
],
)
GenTestRules(
name = "GeneratedTestRules",
test_files = glob(["*Test.java"]),
deps = [":api"],
)

View file

@ -0,0 +1,193 @@
// Copyright 2016 The Domain Registry 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 com.google.domain.registry.ui.server.api;
import static com.google.common.truth.Truth.assertThat;
import static com.google.domain.registry.testing.DatastoreHelper.createTld;
import static com.google.domain.registry.testing.DatastoreHelper.persistActiveDomain;
import static com.google.domain.registry.testing.DatastoreHelper.persistReservedList;
import static com.google.domain.registry.testing.DatastoreHelper.persistResource;
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.domain.registry.model.registrar.Registrar;
import com.google.domain.registry.model.registry.Registry;
import com.google.domain.registry.testing.AppEngineRule;
import org.json.simple.JSONValue;
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;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/** Tests for {@link CheckApiServlet}. */
@RunWith(MockitoJUnitRunner.class)
public class CheckApiServletTest {
@Rule
public final AppEngineRule appEngine = AppEngineRule.builder()
.withDatastore()
.build();
@Mock HttpServletRequest req;
@Mock HttpServletResponse rsp;
private final StringWriter writer = new StringWriter();
private final CheckApiServlet servlet = new CheckApiServlet();
@Before
public void init() throws Exception {
createTld("example");
persistResource(
Registry.get("example")
.asBuilder()
.setReservedLists(persistReservedList("example-reserved", "foo,FULLY_BLOCKED"))
.build());
when(rsp.getWriter()).thenReturn(new PrintWriter(writer));
}
private void doTest(Map<String, ?> expected) throws Exception {
servlet.doGet(req, rsp);
assertThat(JSONValue.parse(writer.toString())).isEqualTo(expected);
}
@Test
public void testFailure_nullDomain() throws Exception {
doTest(ImmutableMap.of(
"status", "error",
"reason", "Must supply a valid second level domain name"));
}
@Test
public void testFailure_emptyDomain() throws Exception {
when(req.getParameter("domain")).thenReturn("");
doTest(ImmutableMap.of(
"status", "error",
"reason", "Must supply a valid second level domain name"));
}
@Test
public void testFailure_invalidDomain() throws Exception {
when(req.getParameter("domain")).thenReturn("@#$%^");
doTest(ImmutableMap.of(
"status", "error",
"reason", "Must supply a valid second level domain name"));
}
@Test
public void testFailure_singlePartDomain() throws Exception {
when(req.getParameter("domain")).thenReturn("foo");
doTest(ImmutableMap.of(
"status", "error",
"reason", "Must supply a valid second level domain name"));
}
@Test
public void testFailure_nonExistentTld() throws Exception {
when(req.getParameter("domain")).thenReturn("foo.bar");
doTest(ImmutableMap.of(
"status", "error",
"reason", "Domain name is under tld bar which doesn't exist"));
}
@Test
public void testFailure_unauthorizedTld() throws Exception {
createTld("foo");
persistResource(
Registrar.loadByClientId("TheRegistrar")
.asBuilder()
.setAllowedTlds(ImmutableSet.of("foo"))
.build());
when(req.getParameter("domain")).thenReturn("timmy.example");
doTest(ImmutableMap.of(
"status", "error",
"reason", "Registrar is not authorized to access the TLD example"));
}
@Test
public void testSuccess_availableStandard() throws Exception {
when(req.getParameter("domain")).thenReturn("somedomain.example");
doTest(ImmutableMap.of(
"status", "success",
"available", true,
"tier", "standard"));
}
@Test
public void testSuccess_availableCapital() throws Exception {
when(req.getParameter("domain")).thenReturn("SOMEDOMAIN.EXAMPLE");
doTest(ImmutableMap.of(
"status", "success",
"available", true,
"tier", "standard"));
}
@Test
public void testSuccess_availableUnicode() throws Exception {
when(req.getParameter("domain")).thenReturn("ééé.example");
doTest(ImmutableMap.of(
"status", "success",
"available", true,
"tier", "standard"));
}
@Test
public void testSuccess_availablePunycode() throws Exception {
when(req.getParameter("domain")).thenReturn("xn--9caaa.example");
doTest(ImmutableMap.of(
"status", "success",
"available", true,
"tier", "standard"));
}
@Test
public void testSuccess_availablePremium() throws Exception {
when(req.getParameter("domain")).thenReturn("rich.example");
doTest(ImmutableMap.of(
"status", "success",
"available", true,
"tier", "premium"));
}
@Test
public void testSuccess_alreadyRegistered() throws Exception {
persistActiveDomain("somedomain.example");
when(req.getParameter("domain")).thenReturn("somedomain.example");
doTest(ImmutableMap.of(
"status", "success",
"available", false,
"reason", "In use"));
}
@Test
public void testSuccess_reserved() throws Exception {
when(req.getParameter("domain")).thenReturn("foo.example");
doTest(ImmutableMap.of(
"status", "success",
"available", false,
"reason", "Reserved"));
}
}

View file

@ -0,0 +1,43 @@
package(default_visibility = ["//java/com/google/domain/registry:registry_project"])
load("//java/com/google/testing/builddefs:GenTestRules.bzl", "GenTestRules")
java_library(
name = "registrar",
srcs = glob(["*.java"]),
resources = glob(["testdata/*"]),
deps = [
"//java/com/google/common/base",
"//java/com/google/common/collect",
"//java/com/google/common/io",
"//java/com/google/common/net",
"//java/com/google/common/testing",
"//java/com/google/domain/registry/braintree",
"//java/com/google/domain/registry/config",
"//java/com/google/domain/registry/export/sheet",
"//java/com/google/domain/registry/model",
"//java/com/google/domain/registry/security",
"//java/com/google/domain/registry/ui/server/registrar",
"//java/com/google/domain/registry/ui/soy/registrar:soy_java_wrappers",
"//java/com/google/domain/registry/util",
"//javatests/com/google/domain/registry/security",
"//javatests/com/google/domain/registry/testing",
"//third_party/java/appengine:appengine-api-testonly",
"//third_party/java/braintree",
"//third_party/java/joda_money",
"//third_party/java/joda_time",
"//third_party/java/json_simple",
"//third_party/java/junit",
"//third_party/java/mockito",
"//third_party/java/objectify:objectify-v4_1",
"//third_party/java/servlet/servlet_api",
"//third_party/java/truth",
],
)
GenTestRules(
name = "GeneratedTestRules",
test_files = glob(["*Test.java"]),
deps = [":registrar"],
)

View file

@ -0,0 +1,101 @@
// Copyright 2016 The Domain Registry 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 com.google.domain.registry.ui.server.registrar;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.when;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.common.net.MediaType;
import com.google.domain.registry.testing.AppEngineRule;
import com.google.domain.registry.testing.FakeResponse;
import com.google.domain.registry.testing.UserInfo;
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;
import javax.servlet.http.HttpServletRequest;
/** Unit tests for {@link ConsoleUiAction}. */
@RunWith(MockitoJUnitRunner.class)
public class ConsoleUiActionTest {
@Rule
public final AppEngineRule appEngineRule = AppEngineRule.builder()
.withDatastore()
.withUserService(UserInfo.create("marla.singer@example.com", "12345"))
.build();
@Mock
private SessionUtils sessionUtils;
private final FakeResponse response = new FakeResponse();
private final ConsoleUiAction action = new ConsoleUiAction();
@Before
public void setUp() throws Exception {
action.enabled = true;
action.response = response;
action.sessionUtils = sessionUtils;
action.userService = UserServiceFactory.getUserService();
when(sessionUtils.checkRegistrarConsoleLogin(any(HttpServletRequest.class))).thenReturn(true);
when(sessionUtils.getRegistrarClientId(any(HttpServletRequest.class)))
.thenReturn("TheRegistrar");
}
@Test
public void webPage_disallowsIframe() throws Exception {
action.run();
assertThat(response.getHeaders()).containsEntry("X-Frame-Options", "SAMEORIGIN");
}
@Test
public void webPage_setsHtmlUtf8ContentType() throws Exception {
action.run();
assertThat(response.getContentType()).isEqualTo(MediaType.HTML_UTF_8);
}
@Test
public void webPage_containsUserNickname() throws Exception {
action.run();
assertThat(response.getPayload()).contains("marla.singer");
}
@Test
public void userHasAccessAsTheRegistrar_showsRegistrarConsole() throws Exception {
action.run();
assertThat(response.getPayload()).contains("Registrar Console");
assertThat(response.getPayload()).contains("reg-content-and-footer");
}
@Test
public void consoleDisabled_showsDisabledPage() throws Exception {
action.enabled = false;
action.run();
assertThat(response.getPayload()).contains("<h1>Console is disabled</h1>");
}
@Test
public void userDoesntHaveAccessToAnyRegistrar_showsWhoAreYouPage() throws Exception {
when(sessionUtils.checkRegistrarConsoleLogin(any(HttpServletRequest.class))).thenReturn(false);
action.run();
assertThat(response.getPayload()).contains("<h1>You need permission</h1>");
}
}

View file

@ -0,0 +1,139 @@
// Copyright 2016 The Domain Registry 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 com.google.domain.registry.ui.server.registrar;
import static com.google.common.truth.Truth.assertThat;
import static com.google.domain.registry.security.JsonHttpTestUtils.createJsonPayload;
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.domain.registry.model.registrar.Registrar;
import com.google.domain.registry.model.registrar.RegistrarContact;
import com.google.domain.registry.testing.AppEngineRule;
import com.google.domain.registry.testing.DatastoreHelper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Unit tests for contact_settings.js use of {@link RegistrarServlet}.
*
* <p>The default read and session validation tests are handled by the
* superclass.
*/
@RunWith(MockitoJUnitRunner.class)
public class ContactSettingsTest extends RegistrarServletTestCase {
@Test
public void testPost_readContacts_success() throws Exception {
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
"op", "read",
"args", ImmutableMap.of())));
servlet.service(req, rsp);
@SuppressWarnings("unchecked")
List<Map<String, ?>> results = (List<Map<String, ?>>) json.get().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(
"op", "update",
"args", Registrar.loadByClientId(CLIENT_ID).toJsonMap())));
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "SUCCESS");
}
@Test
public void testPost_updateContacts_success() throws Exception {
// Remove all the contacts but the first by updating with list of
// just it.
Map<String, /* @Nullable */ Object> adminContact1 = new HashMap<>();
adminContact1.put("name", "contact1");
adminContact1.put("emailAddress", "contact1@email.com");
adminContact1.put("phoneNumber", "+1.2125650001");
// Have to keep ADMIN or else expect FormException for at-least-one.
adminContact1.put("types", "ADMIN");
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(
"op", "update",
"args", regMap)));
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "SUCCESS");
RegistrarContact newContact = new RegistrarContact.Builder()
.setParent(registrar)
.setName((String) adminContact1.get("name"))
.setEmailAddress((String) adminContact1.get("emailAddress"))
.setPhoneNumber((String) adminContact1.get("phoneNumber"))
.setTypes(ImmutableList.of(RegistrarContact.Type.ADMIN))
.build();
assertThat(Registrar.loadByClientId(CLIENT_ID).getContacts())
.containsExactlyElementsIn(ImmutableSet.of(newContact));
}
@Test
public void testPost_updateContacts_requiredTypes_error() throws Exception {
Map<String, Object> reqJson = Registrar.loadByClientId(CLIENT_ID).toJsonMap();
reqJson.put("contacts",
ImmutableList.of(AppEngineRule.makeRegistrarContact2()
.asBuilder()
.setTypes(ImmutableList.<RegistrarContact.Type>of())
.build().toJsonMap()));
when(req.getReader()).thenReturn(createJsonPayload(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 "
+ RegistrarContact.Type.ADMIN.getDisplayName() + " contact");
}
@Test
public void testPost_updateContacts_requireTechPhone_error() throws Exception {
// First make the contact a tech contact as well.
Registrar registrar = Registrar.loadByClientId(CLIENT_ID);
RegistrarContact rc = AppEngineRule.makeRegistrarContact2()
.asBuilder()
.setTypes(ImmutableSet.of(RegistrarContact.Type.ADMIN, RegistrarContact.Type.TECH))
.build();
// Lest we anger the timestamp inversion bug.
DatastoreHelper.persistResource(registrar);
DatastoreHelper.persistSimpleGlobalResources(ImmutableSet.of(rc));
// Now try to remove the phone number.
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(
"op", "update",
"args", reqJson)));
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "ERROR");
assertThat(json.get()).containsEntry("message", "At least one "
+ RegistrarContact.Type.TECH.getDisplayName() + " contact must have a phone number");
}
}

View file

@ -0,0 +1,446 @@
// Copyright 2016 The Domain Registry 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 com.google.domain.registry.ui.server.registrar;
import static com.google.common.truth.Truth.assertThat;
import static com.google.domain.registry.testing.ReflectiveFieldExtractor.extractField;
import static java.util.Arrays.asList;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableMap;
import com.google.domain.registry.model.registrar.Registrar;
import com.google.domain.registry.testing.AppEngineRule;
import com.braintreegateway.BraintreeGateway;
import com.braintreegateway.Result;
import com.braintreegateway.Transaction;
import com.braintreegateway.Transaction.GatewayRejectionReason;
import com.braintreegateway.TransactionGateway;
import com.braintreegateway.TransactionRequest;
import com.braintreegateway.ValidationError;
import com.braintreegateway.ValidationErrorCode;
import com.braintreegateway.ValidationErrors;
import org.joda.money.CurrencyUnit;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import java.math.BigDecimal;
/** Tests for {@link RegistrarPaymentAction}. */
@RunWith(MockitoJUnitRunner.class)
public class RegistrarPaymentActionTest {
@Rule
public final AppEngineRule appEngine = AppEngineRule.builder().withDatastore().build();
@Mock
private BraintreeGateway braintreeGateway;
@Mock
private TransactionGateway transactionGateway;
@Mock
private Result<Transaction> result;
@Mock
private Transaction transaction;
@Mock
private ValidationErrors validationErrors;
@Captor
private ArgumentCaptor<TransactionRequest> transactionRequestCaptor;
private final RegistrarPaymentAction paymentAction = new RegistrarPaymentAction();
@Before
public void before() throws Exception {
paymentAction.registrar = Registrar.loadByClientId("TheRegistrar");
paymentAction.accountIds =
ImmutableMap.of(
CurrencyUnit.USD, "merchant-account-usd",
CurrencyUnit.JPY, "merchant-account-jpy");
paymentAction.braintreeGateway = braintreeGateway;
when(braintreeGateway.transaction()).thenReturn(transactionGateway);
when(transactionGateway.sale(any(TransactionRequest.class))).thenReturn(result);
}
@Test
public void testCurrencyIsUsd_usesAmericanMerchantAccount() throws Exception {
when(result.isSuccess()).thenReturn(true);
when(result.getTarget()).thenReturn(transaction);
when(transaction.getId()).thenReturn("omg-im-an-id");
when(transaction.getAmount()).thenReturn(BigDecimal.valueOf(123.4));
when(transaction.getCurrencyIsoCode()).thenReturn("USD");
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", " 123.4 ",
"currency", "USD",
"paymentMethodNonce", "abc-123")))
.containsExactly(
"status", "SUCCESS",
"message", "Payment processed successfully",
"results", asList(
ImmutableMap.of(
"id", "omg-im-an-id",
"formattedAmount", "$123.40")));
verify(transactionGateway).sale(transactionRequestCaptor.capture());
TransactionRequest transactionRequest = transactionRequestCaptor.getAllValues().get(0);
assertThat(extractField(BigDecimal.class, transactionRequest, "amount"))
.isEqualTo(BigDecimal.valueOf(123.4).setScale(2));
assertThat(extractField(String.class, transactionRequest, "merchantAccountId"))
.isEqualTo("merchant-account-usd");
assertThat(extractField(String.class, transactionRequest, "customerId"))
.isEqualTo("TheRegistrar");
}
@Test
public void testCurrencyIsJpy_usesJapaneseMerchantAccount() throws Exception {
when(result.isSuccess()).thenReturn(true);
when(result.getTarget()).thenReturn(transaction);
when(transaction.getId()).thenReturn("omg-im-an-id");
when(transaction.getAmount()).thenReturn(BigDecimal.valueOf(123));
when(transaction.getCurrencyIsoCode()).thenReturn("JPY");
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", "123",
"currency", "JPY",
"paymentMethodNonce", "abc-123")))
.containsExactly(
"status", "SUCCESS",
"message", "Payment processed successfully",
"results", asList(
ImmutableMap.of(
"id", "omg-im-an-id",
"formattedAmount", "JPY 123")));
verify(transactionGateway).sale(transactionRequestCaptor.capture());
TransactionRequest transactionRequest = transactionRequestCaptor.getAllValues().get(0);
assertThat(extractField(BigDecimal.class, transactionRequest, "amount"))
.isEqualTo(BigDecimal.valueOf(123));
assertThat(extractField(String.class, transactionRequest, "merchantAccountId"))
.isEqualTo("merchant-account-jpy");
}
@Test
public void testAmountNotPresent_returnsErrorOnAmountField() throws Exception {
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"currency", "JPY",
"paymentMethodNonce", "abc-123")))
.containsExactly(
"status", "ERROR",
"message", "This field is required.",
"field", "amount",
"results", asList());
}
@Test
public void testAmountNotNumber_returnsErrorOnAmountField() throws Exception {
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", "abc",
"currency", "JPY",
"paymentMethodNonce", "abc-123")))
.containsExactly(
"status", "ERROR",
"message", "Invalid number.",
"field", "amount",
"results", asList());
}
@Test
public void testNegativeAmount_returnsErrorOnAmountField() throws Exception {
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", "-10",
"currency", "JPY",
"paymentMethodNonce", "abc-123")))
.containsExactly(
"status", "ERROR",
"message", "Must be a positive number.",
"field", "amount",
"results", asList());
}
@Test
public void testZeroAmount_returnsErrorOnAmountField() throws Exception {
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", "0",
"currency", "JPY",
"paymentMethodNonce", "abc-123")))
.containsExactly(
"status", "ERROR",
"message", "Must be a positive number.",
"field", "amount",
"results", asList());
}
@Test
public void testAmountHasMorePrecisionThanUsdCurrencyAllows_returnsError() throws Exception {
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", "123.456",
"currency", "USD",
"paymentMethodNonce", "abc-123")))
.containsExactly(
"status", "ERROR",
"message", "Scale of amount 123.456 is greater than the scale of the currency USD",
"field", "amount",
"results", asList());
}
@Test
public void testAmountHasMorePrecisionThanJpyCurrencyAllows_returnsError() throws Exception {
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", "1.1",
"currency", "JPY",
"paymentMethodNonce", "abc-123")))
.containsExactly(
"status", "ERROR",
"message", "Scale of amount 1.1 is greater than the scale of the currency JPY",
"field", "amount",
"results", asList());
}
@Test
public void testCurrencyValidButNotSupported_returnsErrorOnCurrencyField() throws Exception {
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", "123",
"currency", "EUR",
"paymentMethodNonce", "abc-123")))
.containsExactly(
"status", "ERROR",
"message", "Unsupported currency.",
"field", "currency",
"results", asList());
}
@Test
public void testCurrencyBogus_returnsErrorOnCurrencyField() throws Exception {
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", "123",
"currency", "rm -rf /etc/passwd",
"paymentMethodNonce", "abc-123")))
.containsExactly(
"status", "ERROR",
"message", "Invalid currency code.",
"field", "currency",
"results", asList());
}
@Test
public void testCurrencyCodeNotAssigned_returnsErrorOnCurrencyField() throws Exception {
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", "123",
"currency", "ZZZ",
"paymentMethodNonce", "abc-123")))
.containsExactly(
"status", "ERROR",
"message", "Unknown ISO currency code.",
"field", "currency",
"results", asList());
}
@Test
public void testCurrencyMissing_returnsErrorOnCurrencyField() throws Exception {
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", "123",
"paymentMethodNonce", "omg")))
.containsExactly(
"status", "ERROR",
"message", "This field is required.",
"field", "currency",
"results", asList());
}
@Test
public void testPaymentMethodMissing_returnsErrorOnPaymentMethodField() throws Exception {
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", "123",
"currency", "JPY")))
.containsExactly(
"status", "ERROR",
"message", "This field is required.",
"field", "paymentMethodNonce",
"results", asList());
}
@Test
public void testProcessorDeclined_returnsErrorResponse() throws Exception {
when(result.isSuccess()).thenReturn(false);
when(result.getTransaction()).thenReturn(transaction);
when(transaction.getStatus()).thenReturn(Transaction.Status.PROCESSOR_DECLINED);
when(transaction.getProcessorResponseText())
.thenReturn("You don't know the power of the dark side");
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", "123",
"currency", "USD",
"paymentMethodNonce", "abc-123")))
.containsExactly(
"status", "ERROR",
"message", "Payment declined: You don't know the power of the dark side",
"results", asList());
}
@Test
public void testGatewayRejectedDueToCvv_returnsErrorResponse() throws Exception {
when(result.isSuccess()).thenReturn(false);
when(result.getTransaction()).thenReturn(transaction);
when(transaction.getStatus()).thenReturn(Transaction.Status.GATEWAY_REJECTED);
when(transaction.getGatewayRejectionReason()).thenReturn(GatewayRejectionReason.CVV);
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", "123",
"currency", "USD",
"paymentMethodNonce", "abc-123")))
.containsExactly(
"status", "ERROR",
"message", "Payment rejected: Invalid CVV code.",
"results", asList());
}
@Test
public void testGatewayRejectedDueToAddress_returnsErrorResponse() throws Exception {
when(result.isSuccess()).thenReturn(false);
when(result.getTransaction()).thenReturn(transaction);
when(transaction.getStatus()).thenReturn(Transaction.Status.GATEWAY_REJECTED);
when(transaction.getGatewayRejectionReason()).thenReturn(GatewayRejectionReason.AVS);
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", "123",
"currency", "USD",
"paymentMethodNonce", "abc-123")))
.containsExactly(
"status", "ERROR",
"message", "Payment rejected: Invalid address.",
"results", asList());
}
@Test
public void testSettlementDeclined_returnsErrorResponse() throws Exception {
when(result.isSuccess()).thenReturn(false);
when(result.getTransaction()).thenReturn(transaction);
when(transaction.getStatus()).thenReturn(Transaction.Status.SETTLEMENT_DECLINED);
when(transaction.getProcessorSettlementResponseText())
.thenReturn("mine eyes have seen the glory of the coming of the borg");
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", "123",
"currency", "USD",
"paymentMethodNonce", "abc-123")))
.containsExactly(
"status", "ERROR",
"message", "Payment declined: mine eyes have seen the glory of the coming of the borg",
"results", asList());
}
@Test
public void testHasTransactionObjectWithWeirdStatus_returnsErrorResponse() throws Exception {
when(result.isSuccess()).thenReturn(false);
when(result.getTransaction()).thenReturn(transaction);
when(transaction.getStatus()).thenReturn(Transaction.Status.UNRECOGNIZED);
when(transaction.getProcessorResponseText())
.thenReturn("he is preempting the instance where the deadlocked shards are stored");
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", "123",
"currency", "USD",
"paymentMethodNonce", "abc-123")))
.containsExactly(
"status", "ERROR",
"message", "Payment failure: "
+ "he is preempting the instance where the deadlocked shards are stored",
"results", asList());
}
@Test
public void testFailedWithWeirdStatusButNoHelpfulText_usesWeirdStatusAsMsg() throws Exception {
when(result.isSuccess()).thenReturn(false);
when(result.getTransaction()).thenReturn(transaction);
when(transaction.getStatus()).thenReturn(Transaction.Status.FAILED);
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", "123",
"currency", "USD",
"paymentMethodNonce", "abc-123")))
.containsExactly(
"status", "ERROR",
"message", "Payment failure: FAILED",
"results", asList());
}
@Test
public void testRemoteValidationError_showsErrorOnlyOnFirstFormField() throws Exception {
when(result.isSuccess()).thenReturn(false);
when(result.getErrors()).thenReturn(validationErrors);
when(validationErrors.getAllDeepValidationErrors())
.thenReturn(asList(
new ValidationError(
"amount",
ValidationErrorCode.TRANSACTION_SETTLEMENT_AMOUNT_IS_LESS_THAN_SERVICE_FEE_AMOUNT,
"Gimmeh moar moneys"),
new ValidationError(
"fax",
ValidationErrorCode.CUSTOMER_FAX_IS_TOO_LONG,
"Fax is too long")));
assertThat(
paymentAction.handleJsonRequest(
ImmutableMap.of(
"amount", "123",
"currency", "USD",
"paymentMethodNonce", "abc-123")))
.containsExactly(
"status", "ERROR",
"message", "Gimmeh moar moneys",
"field", "amount",
"results", asList());
}
}

View file

@ -0,0 +1,112 @@
// Copyright 2016 The Domain Registry 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 com.google.domain.registry.ui.server.registrar;
import static com.google.common.truth.Truth.assertThat;
import static java.util.Arrays.asList;
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 com.google.domain.registry.braintree.BraintreeRegistrarSyncer;
import com.google.domain.registry.model.registrar.Registrar;
import com.google.domain.registry.testing.AppEngineRule;
import com.braintreegateway.BraintreeGateway;
import com.braintreegateway.ClientTokenGateway;
import org.joda.money.CurrencyUnit;
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;
/** Tests for {@link RegistrarPaymentSetupAction}. */
@RunWith(MockitoJUnitRunner.class)
public class RegistrarPaymentSetupActionTest {
@Rule
public final AppEngineRule appEngine = AppEngineRule.builder()
.withDatastore()
.build();
@Mock
private BraintreeGateway braintreeGateway;
@Mock
private ClientTokenGateway clientTokenGateway;
@Mock
private BraintreeRegistrarSyncer customerSyncer;
private final RegistrarPaymentSetupAction action = new RegistrarPaymentSetupAction();
@Before
public void before() throws Exception {
action.braintreeGateway = braintreeGateway;
action.customerSyncer = customerSyncer;
action.registrar =
Registrar.loadByClientId("TheRegistrar").asBuilder()
.setBillingMethod(Registrar.BillingMethod.BRAINTREE)
.build();
when(braintreeGateway.clientToken()).thenReturn(clientTokenGateway);
}
@Test
public void testTokenGeneration() throws Exception {
action.brainframe = "/doodle";
action.accountIds =
ImmutableMap.of(
CurrencyUnit.USD, "sorrow",
CurrencyUnit.JPY, "torment");
String blanketsOfSadness = "our hearts are beating, but no one is breathing";
when(clientTokenGateway.generate()).thenReturn(blanketsOfSadness);
assertThat(action.handleJsonRequest(ImmutableMap.<String, Object>of()))
.containsExactly(
"status", "SUCCESS",
"message", "Success",
"results", asList(
ImmutableMap.of(
"token", blanketsOfSadness,
"currencies", asList("USD", "JPY"),
"brainframe", "/doodle")));
verify(customerSyncer).sync(eq(action.registrar));
}
@Test
public void testNonEmptyRequestObject_returnsError() throws Exception {
assertThat(action.handleJsonRequest(ImmutableMap.of("oh", "no")))
.containsExactly(
"status", "ERROR",
"message", "JSON request object must be empty",
"results", asList());
}
@Test
public void testNotOnCreditCardBillingTerms_showsErrorPage() throws Exception {
action.registrar =
Registrar.loadByClientId("TheRegistrar").asBuilder()
.setBillingMethod(Registrar.BillingMethod.EXTERNAL)
.build();
assertThat(action.handleJsonRequest(ImmutableMap.<String, Object>of()))
.containsExactly(
"status", "ERROR",
"message", "not-using-cc-billing",
"results", asList());
}
}

View file

@ -0,0 +1,170 @@
// Copyright 2016 The Domain Registry 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 com.google.domain.registry.ui.server.registrar;
import static com.google.common.truth.Truth.assertThat;
import static com.google.domain.registry.security.JsonHttpTestUtils.createJsonPayload;
import static com.google.domain.registry.testing.TaskQueueHelper.assertNoTasksEnqueued;
import static com.google.domain.registry.testing.TaskQueueHelper.assertTasksEnqueued;
import static com.google.domain.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 com.google.domain.registry.export.sheet.SyncRegistrarsSheetAction;
import com.google.domain.registry.model.registrar.Registrar;
import com.google.domain.registry.testing.TaskQueueHelper.TaskMatcher;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import javax.mail.internet.InternetAddress;
/** 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

@ -0,0 +1,112 @@
// Copyright 2016 The Domain Registry 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 com.google.domain.registry.ui.server.registrar;
import static com.google.domain.registry.security.JsonHttpTestUtils.createJsonPayload;
import static com.google.domain.registry.security.JsonHttpTestUtils.createJsonResponseSupplier;
import static com.google.domain.registry.security.XsrfTokenManager.generateToken;
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.ImmutableMap;
import com.google.domain.registry.export.sheet.SyncRegistrarsSheetAction;
import com.google.domain.registry.model.ofy.Ofy;
import com.google.domain.registry.testing.AppEngineRule;
import com.google.domain.registry.testing.ExceptionRule;
import com.google.domain.registry.testing.FakeClock;
import com.google.domain.registry.testing.InjectRule;
import com.google.domain.registry.util.SendEmailService;
import com.google.domain.registry.util.SendEmailUtils;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Rule;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Map;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/** Base class for tests using {@link RegistrarServlet}. */
@RunWith(MockitoJUnitRunner.class)
public class RegistrarServletTestCase {
static final String CLIENT_ID = "TheRegistrar";
@Rule
public final AppEngineRule appEngine = AppEngineRule.builder()
.withDatastore()
.withTaskQueue()
.build();
@Rule
public final InjectRule inject = new InjectRule();
@Rule
public final ExceptionRule thrown = new ExceptionRule();
@Mock
HttpServletRequest req;
@Mock
HttpServletResponse rsp;
@Mock
SessionUtils sessionUtils;
@Mock
SendEmailService emailService;
@Mock
ModulesService modulesService;
Message message;
final RegistrarServlet servlet = new RegistrarServlet();
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 {
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));
when(emailService.createMessage()).thenReturn(message);
when(req.getMethod()).thenReturn("POST");
when(rsp.getWriter()).thenReturn(new PrintWriter(writer));
when(req.getContentType()).thenReturn("application/json");
when(req.getHeader(eq("X-CSRF-Token"))).thenReturn(generateToken("console"));
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of("op", "read")));
when(sessionUtils.isLoggedIn()).thenReturn(true);
when(sessionUtils.redirectIfNotLoggedIn(req, rsp)).thenReturn(true);
when(sessionUtils.checkRegistrarConsoleLogin(req)).thenReturn(true);
when(sessionUtils.getRegistrarClientId(req)).thenReturn(CLIENT_ID);
when(modulesService.getVersionHostname("backend", null)).thenReturn("backend.hostname");
}
}

View file

@ -0,0 +1,148 @@
// Copyright 2016 The Domain Registry 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 com.google.domain.registry.ui.server.registrar;
import static com.google.common.truth.Truth.assertThat;
import static com.google.domain.registry.security.JsonHttpTestUtils.createJsonPayload;
import static com.google.domain.registry.testing.CertificateSamples.SAMPLE_CERT;
import static com.google.domain.registry.testing.CertificateSamples.SAMPLE_CERT2;
import static com.google.domain.registry.testing.CertificateSamples.SAMPLE_CERT2_HASH;
import static com.google.domain.registry.testing.CertificateSamples.SAMPLE_CERT_HASH;
import static com.google.domain.registry.testing.DatastoreHelper.persistResource;
import static com.google.domain.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 com.google.domain.registry.config.RegistryEnvironment;
import com.google.domain.registry.model.registrar.Registrar;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.Map;
/**
* Unit tests for security_settings.js use of {@link RegistrarServlet}.
*
* <p>The default read and session validation tests are handled by the
* superclass.
*/
@RunWith(MockitoJUnitRunner.class)
public class SecuritySettingsTest extends RegistrarServletTestCase {
@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(
"op", "update",
"args", modified.toJsonMap())));
servlet.service(req, rsp);
// 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(Registrar.loadByClientId(CLIENT_ID)).isEqualTo(modified);
}
@Test
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(
"op", "update",
"args", reqJson)));
servlet.service(req, rsp);
assertThat(json.get()).containsEntry("status", "ERROR");
assertThat(json.get()).containsEntry("message", "Invalid X.509 PEM certificate");
}
@Test
public void testChangeCertificates() throws Exception {
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");
Registrar registrar = Registrar.loadByClientId(CLIENT_ID);
assertThat(registrar.getClientCertificate()).isEqualTo(SAMPLE_CERT);
assertThat(registrar.getClientCertificateHash()).isEqualTo(SAMPLE_CERT_HASH);
assertThat(registrar.getFailoverClientCertificate()).isNull();
assertThat(registrar.getFailoverClientCertificateHash()).isNull();
}
@Test
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");
Registrar registrar = Registrar.loadByClientId(CLIENT_ID);
assertThat(registrar.getFailoverClientCertificate()).isEqualTo(SAMPLE_CERT2);
assertThat(registrar.getFailoverClientCertificateHash()).isEqualTo(SAMPLE_CERT2_HASH);
}
@Test
public void testEmptyOrNullCertificate_doesNotClearOutCurrentOne() throws Exception {
persistResource(
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();
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");
Registrar registrar = Registrar.loadByClientId(CLIENT_ID);
assertThat(registrar.getClientCertificate()).isEqualTo(SAMPLE_CERT);
assertThat(registrar.getClientCertificateHash()).isEqualTo(SAMPLE_CERT_HASH);
assertThat(registrar.getFailoverClientCertificate()).isEqualTo(SAMPLE_CERT2);
assertThat(registrar.getFailoverClientCertificateHash()).isEqualTo(SAMPLE_CERT2_HASH);
}
@Test
public void testToJsonMap_containsCertificate() throws Exception {
Map<String, Object> jsonMap = Registrar.loadByClientId(CLIENT_ID).asBuilder()
.setClientCertificate(SAMPLE_CERT2, START_OF_TIME)
.build()
.toJsonMap();
assertThat(jsonMap).containsEntry("clientCertificate", SAMPLE_CERT2);
assertThat(jsonMap).containsEntry("clientCertificateHash", SAMPLE_CERT2_HASH);
}
@Test
public void testToJsonMap_containsFailoverCertificate() throws Exception {
Map<String, Object> jsonMap = Registrar.loadByClientId(CLIENT_ID).asBuilder()
.setFailoverClientCertificate(SAMPLE_CERT2, START_OF_TIME)
.build()
.toJsonMap();
assertThat(jsonMap).containsEntry("failoverClientCertificate", SAMPLE_CERT2);
assertThat(jsonMap).containsEntry("failoverClientCertificateHash", SAMPLE_CERT2_HASH);
}
}

View file

@ -0,0 +1,146 @@
// Copyright 2016 The Domain Registry 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 com.google.domain.registry.ui.server.registrar;
import static com.google.common.truth.Truth.assertThat;
import static com.google.domain.registry.testing.AppEngineRule.THE_REGISTRAR_GAE_USER_ID;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.common.testing.NullPointerTester;
import com.google.domain.registry.model.registrar.Registrar;
import com.google.domain.registry.model.registrar.RegistrarContact;
import com.google.domain.registry.testing.AppEngineRule;
import com.google.domain.registry.testing.ExceptionRule;
import com.google.domain.registry.testing.InjectRule;
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;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/** Unit tests for {@link SessionUtils}. */
@RunWith(MockitoJUnitRunner.class)
public class SessionUtilsTest {
@Rule
public final AppEngineRule appEngine = AppEngineRule.builder()
.withDatastore()
.build();
@Rule
public final ExceptionRule thrown = new ExceptionRule();
@Rule
public final InjectRule inject = new InjectRule();
@Mock
private UserService userService;
@Mock
private HttpServletRequest req;
@Mock
private HttpServletResponse rsp;
@Mock
private HttpSession session;
private SessionUtils sessionUtils;
private final User jart = new User("jart@google.com", "google.com", THE_REGISTRAR_GAE_USER_ID);
private final User bozo = new User("bozo@bing.com", "bing.com", "badGaeUserId");
@Before
public void before() throws Exception {
sessionUtils = new SessionUtils(userService);
when(req.getSession()).thenReturn(session);
}
@Test
public void testRedirectIfNotLoggedIn_loggedIn_doesNothing() throws Exception {
when(userService.isUserLoggedIn()).thenReturn(true);
assertThat(sessionUtils.redirectIfNotLoggedIn(req, rsp)).isTrue();
verifyZeroInteractions(req, rsp);
}
@Test
public void testRedirectIfNotLoggedIn_notLoggedIn_sendsTemporaryRedirect() throws Exception {
when(userService.isUserLoggedIn()).thenReturn(false);
when(req.getRequestURI()).thenReturn("foo");
when(userService.createLoginURL(eq("foo"))).thenReturn("bar");
assertThat(sessionUtils.redirectIfNotLoggedIn(req, rsp)).isFalse();
verify(rsp).setStatus(eq(302));
verify(rsp).setHeader(eq("Location"), eq("bar"));
verifyNoMoreInteractions(rsp);
}
@Test
public void testCheckRegistrarConsoleLogin_authedButNoSession_createsSession() throws Exception {
when(userService.getCurrentUser()).thenReturn(jart);
assertThat(sessionUtils.checkRegistrarConsoleLogin(req)).isTrue();
verify(session).setAttribute(eq("clientId"), eq("TheRegistrar"));
}
@Test
public void testCheckRegistrarConsoleLogin_authedWithValidSession_doesNothing() throws Exception {
when(session.getAttribute("clientId")).thenReturn("TheRegistrar");
when(userService.getCurrentUser()).thenReturn(jart);
assertThat(sessionUtils.checkRegistrarConsoleLogin(req)).isTrue();
verify(session).getAttribute("clientId");
verifyNoMoreInteractions(session);
}
@Test
public void testCheckRegistrarConsoleLogin_sessionRevoked_invalidates() throws Exception {
RegistrarContact.updateContacts(
Registrar.loadByClientId("TheRegistrar"),
new java.util.HashSet<RegistrarContact>());
when(session.getAttribute("clientId")).thenReturn("TheRegistrar");
when(userService.getCurrentUser()).thenReturn(jart);
assertThat(sessionUtils.checkRegistrarConsoleLogin(req)).isFalse();
verify(session).invalidate();
}
@Test
public void testCheckRegistrarConsoleLogin_notLoggedIn_throwsIse() throws Exception {
thrown.expect(IllegalStateException.class);
assertThat(sessionUtils.checkRegistrarConsoleLogin(req)).isNull();
}
@Test
public void testCheckRegistrarConsoleLogin_notAllowed_returnsFalse() throws Exception {
when(userService.getCurrentUser()).thenReturn(bozo);
assertThat(sessionUtils.checkRegistrarConsoleLogin(req)).isFalse();
}
@Test
public void testNullness() throws Exception {
new NullPointerTester()
.setDefault(HttpServletRequest.class, req)
.setDefault(HttpServletResponse.class, rsp)
.testAllPublicStaticMethods(SessionUtils.class);
}
}

View file

@ -0,0 +1,128 @@
// Copyright 2016 The Domain Registry 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 com.google.domain.registry.ui.server.registrar;
import static com.google.common.base.Strings.repeat;
import static com.google.common.truth.Truth.assertThat;
import static com.google.domain.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 com.google.domain.registry.model.registrar.Registrar;
import com.google.domain.registry.model.registrar.RegistrarAddress;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
/**
* Unit tests for security_settings.js use of {@link RegistrarServlet}.
*
* <p>The default read and session validation tests are handled by the superclass.
*/
@RunWith(MockitoJUnitRunner.class)
public class WhoisSettingsTest extends RegistrarServletTestCase {
@Test
public void testPost_update_success() throws Exception {
Registrar modified = Registrar.loadByClientId(CLIENT_ID).asBuilder()
.setEmailAddress("hello.kitty@example.com")
.setPhoneNumber("+1.2125650000")
.setFaxNumber("+1.2125650001")
.setReferralUrl("http://acme.com/")
.setWhoisServer("ns1.foo.bar")
.setLocalizedAddress(new RegistrarAddress.Builder()
.setStreet(ImmutableList.of("76 Ninth Avenue", "Eleventh Floor"))
.setCity("New York")
.setState("NY")
.setZip("10009")
.setCountryCode("US")
.build())
.build();
when(req.getReader()).thenReturn(createJsonPayload(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()));
assertThat(Registrar.loadByClientId(CLIENT_ID)).isEqualTo(modified);
}
@Test
public void testPost_badUsStateCode_returnsFormFieldError() throws Exception {
Registrar modified = Registrar.loadByClientId(CLIENT_ID).asBuilder()
.setEmailAddress("hello.kitty@example.com")
.setPhoneNumber("+1.2125650000")
.setFaxNumber("+1.2125650001")
.setLocalizedAddress(new RegistrarAddress.Builder()
.setStreet(ImmutableList.of("76 Ninth Avenue", "Eleventh Floor"))
.setCity("New York")
.setState("ZZ")
.setZip("10009")
.setCountryCode("US")
.build())
.build();
when(req.getReader()).thenReturn(createJsonPayload(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.");
assertThat(Registrar.loadByClientId(CLIENT_ID)).isNotEqualTo(modified);
}
@Test
public void testPost_badAddress_returnsFormFieldError() throws Exception {
Registrar modified = Registrar.loadByClientId(CLIENT_ID).asBuilder()
.setEmailAddress("hello.kitty@example.com")
.setPhoneNumber("+1.2125650000")
.setFaxNumber("+1.2125650001")
.setLocalizedAddress(new RegistrarAddress.Builder()
.setStreet(ImmutableList.of("76 Ninth Avenue", repeat("lol", 200)))
.setCity("New York")
.setState("NY")
.setZip("10009")
.setCountryCode("US")
.build())
.build();
when(req.getReader()).thenReturn(createJsonPayload(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"))
.contains("Number of characters (600) not in range");
assertThat(Registrar.loadByClientId(CLIENT_ID)).isNotEqualTo(modified);
}
@Test
public void testPost_badWhoisServer_returnsFormFieldError() throws Exception {
Registrar modified = Registrar.loadByClientId(CLIENT_ID).asBuilder()
.setWhoisServer("tears@dry.tragical.lol")
.build();
when(req.getReader()).thenReturn(createJsonPayload(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.");
assertThat(Registrar.loadByClientId(CLIENT_ID)).isNotEqualTo(modified);
}
}

View file

@ -0,0 +1,59 @@
{
"op": "update",
"args": {
"clientIdentifier": "theregistrar",
"driveFolderId": null,
"registrarName": "The Registrar",
"lastUpdateTime": "2015-01-22T17:27:36.999Z",
"state": "ACTIVE",
"type": "REAL",
"contacts": [
{
"visibleInWhoisAsAdmin": true,
"faxNumber": null,
"phoneNumber": null,
"name": "Extra Terrestrial",
"visibleInWhoisAsTech": false,
"emailAddress": "etphonehome@example.com",
"gaeUserId": null,
"types": "ADMIN,BILLING,TECH,WHOIS"
}
],
"allowedTlds": [
"ga"
],
"clientCertificateHash": null,
"faxNumber": "",
"ianaIdentifier": "1",
"phoneNumber": "+1.2223335555",
"internationalizedAddress": null,
"whoisServer": "foo.bar.baz",
"creationTime": "2014-04-15T21:57:54.765Z",
"clientCertificate": null,
"emailAddress": "thase@the.registrar",
"ipAddressWhitelist": [
"1.1.1.1\/32",
"2.2.2.2\/32",
"4.4.4.4\/32"
],
"localizedAddress": {
"street": [
"123 Street Rd",
"Ste 156",
""
],
"city": "New York",
"state": "NY",
"zip": "10011",
"countryCode": "US"
},
"billingIdentifier": null,
"url": null,
"icannReferralEmail": "asdf@asdf.com",
"phonePasscode": null,
"referralUrl": "",
"blockPremiumNames": false,
"lastCertificateUpdateTime": null,
"e": false
}
}

View file

@ -0,0 +1,69 @@
{
"op": "update",
"args": {
"clientIdentifier": "theregistrar",
"driveFolderId": null,
"registrarName": "The Registrar",
"lastUpdateTime": "2015-01-22T17:27:36.999Z",
"state": "ACTIVE",
"type": "REAL",
"contacts": [
{
"visibleInWhoisAsAdmin": true,
"faxNumber": null,
"phoneNumber": null,
"name": "Extra Terrestrial",
"visibleInWhoisAsTech": false,
"emailAddress": "etphonehome@example.com",
"gaeUserId": null,
"types": "ADMIN,BILLING,TECH,WHOIS"
},
{
"visibleInWhoisAsAdmin": true,
"faxNumber": null,
"phoneNumber": null,
"name": "E.T.",
"visibleInWhoisAsTech": false,
"emailAddress": "etphonehome@example.com",
"gaeUserId": null,
"types": "MARKETING"
}
],
"allowedTlds": [
"ga"
],
"clientCertificateHash": null,
"faxNumber": "",
"ianaIdentifier": "1",
"phoneNumber": "+1.2223335555",
"internationalizedAddress": null,
"whoisServer": "foo.bar.baz",
"creationTime": "2014-04-15T21:57:54.765Z",
"clientCertificate": null,
"emailAddress": "thase@the.registrar",
"ipAddressWhitelist": [
"1.1.1.1\/32",
"2.2.2.2\/32",
"4.4.4.4\/32"
],
"localizedAddress": {
"street": [
"123 Street Rd",
"Ste 156",
""
],
"city": "New York",
"state": "NY",
"zip": "10011",
"countryCode": "US"
},
"billingIdentifier": null,
"url": null,
"icannReferralEmail": "asdf@asdf.com",
"phonePasscode": null,
"referralUrl": "",
"blockPremiumNames": false,
"lastCertificateUpdateTime": null,
"e": false
}
}

View file

@ -0,0 +1,16 @@
The following changes were made to the registrar:
whoisServer -> [null, foo.bar.baz]
ipAddressWhitelist -> [null, [1.1.1.1/32, 2.2.2.2/32, 4.4.4.4/32]]
localizedAddress.street.0 -> [123 Example Bőulevard, 123 Street Rd]
localizedAddress.street.1 -> [null, Ste 156]
localizedAddress.city -> [Williamsburg, New York]
localizedAddress.zip -> [11211, 10011]
phoneNumber -> [+1.2223334444, +1.2223335555]
emailAddress -> [new.registrar@example.com, thase@the.registrar]
contacts ->
ADDED:
{parent=Key<?>(EntityGroupRoot("cross-tld")/Registrar("TheRegistrar")), name=Extra Terrestrial, emailAddress=etphonehome@example.com, phoneNumber=null, faxNumber=null, types=[ADMIN, BILLING, TECH, WHOIS], gaeUserId=null, visibleInWhoisAsAdmin=true, visibleInWhoisAsTech=false}
REMOVED:
{parent=Key<?>(EntityGroupRoot("cross-tld")/Registrar("TheRegistrar")), name=John Doe, emailAddress=johndoe@theregistrar.com, phoneNumber=+1.1234567890, faxNumber=null, types=[ADMIN], gaeUserId=31337, visibleInWhoisAsAdmin=false, visibleInWhoisAsTech=false}
FINAL CONTENTS:
{parent=Key<?>(EntityGroupRoot("cross-tld")/Registrar("TheRegistrar")), name=Extra Terrestrial, emailAddress=etphonehome@example.com, phoneNumber=null, faxNumber=null, types=[ADMIN, BILLING, TECH, WHOIS], gaeUserId=null, visibleInWhoisAsAdmin=true, visibleInWhoisAsTech=false}