Incorporate some of the fixes done in RegistrarPremiumPriceAckAction

This is in preparation for merging and then removing
RegistrarPremiumPriceAckAction.

This includes:

test that the data the UI sent isn't stale
---------------------------------------------
Our system is "read, modify, write". However, if between the "read" and the "write" someone else changed the registry, my write will undo their change even if I didn't touch any of their fields.
To solve that - we use the "lastUpdateTime" timestamp of the registrar. the UI reads it with the rest of the data, and sends it back on "write". We will now make sure the registrar currently in datastore has the same timestamp.

support premium-price-ack flag
---------------------------------
Add support for reading and writing this flag. We still won't be using it - that's in a followup CL, but we support it.

support changing the URL
------------------------
Add changing the URL in the UI, under the "whois" section

Will replace the Ack endpoint with this (and remove that endpoint) in a followup CL

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=192154078
This commit is contained in:
guyben 2018-04-09 11:08:48 -07:00 committed by Ben McIlwain
parent 3bbaf585e5
commit 38bf86c0fd
9 changed files with 237 additions and 147 deletions

View file

@ -113,7 +113,8 @@ public class ContactSettingsTest extends RegistrarSettingsActionTestCase {
.setTypes(ImmutableSet.of(RegistrarContact.Type.ADMIN, RegistrarContact.Type.TECH))
.build();
// Lest we anger the timestamp inversion bug.
persistResource(registrar);
// (we also update the registrar so we get the timestamp right)
registrar = persistResource(registrar);
persistSimpleResource(rc);
// Now try to remove the phone number.
@ -138,7 +139,8 @@ public class ContactSettingsTest extends RegistrarSettingsActionTestCase {
.setVisibleInDomainWhoisAsAbuse(true)
.build();
// Lest we anger the timestamp inversion bug.
persistResource(registrar);
// (we also update the registrar so we get the timestamp right)
registrar = persistResource(registrar);
persistSimpleResource(rc);
// Now try to remove the contact.
@ -164,7 +166,8 @@ public class ContactSettingsTest extends RegistrarSettingsActionTestCase {
.setVisibleInDomainWhoisAsAbuse(true)
.build();
// Lest we anger the timestamp inversion bug.
persistResource(registrar);
// (we also update the registrar so we get the timestamp right)
registrar = persistResource(registrar);
persistSimpleResource(rc);
// Now try to set the phone number to null.

View file

@ -36,6 +36,8 @@ import google.registry.testing.TaskQueueHelper.TaskMatcher;
import java.util.Map;
import javax.mail.internet.InternetAddress;
import javax.servlet.http.HttpServletRequest;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@ -47,7 +49,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
@Test
public void testSuccess_updateRegistrarInfo_andSendsNotificationEmail() throws Exception {
String expectedEmailBody = loadFile(getClass(), "update_registrar_email.txt");
action.handleJsonRequest(readJsonFromFile("update_registrar.json"));
action.handleJsonRequest(readJsonFromFile("update_registrar.json", getLastUpdateTime()));
verify(rsp, never()).setStatus(anyInt());
verify(emailService).createMessage();
verify(emailService).sendMessage(message);
@ -64,7 +66,8 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
@Test
public void testFailure_updateRegistrarInfo_duplicateContacts() throws Exception {
Map<String, Object> response =
action.handleJsonRequest(readJsonFromFile("update_registrar_duplicate_contacts.json"));
action.handleJsonRequest(
readJsonFromFile("update_registrar_duplicate_contacts.json", getLastUpdateTime()));
assertThat(response).containsEntry("status", "ERROR");
assertThat((String) response.get("message")).startsWith("One email address");
}
@ -89,11 +92,22 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
}
@Test
public void testUpdate_emptyJsonObject_errorEmailFieldRequired() throws Exception {
public void testUpdate_emptyJsonObject_errorLastUpdateTimeFieldRequired() throws Exception {
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", ImmutableMap.of()));
assertThat(response).containsEntry("status", "ERROR");
assertThat(response).containsEntry("field", "lastUpdateTime");
assertThat(response).containsEntry("message", "This field is required.");
assertNoTasksEnqueued("sheet");
}
@Test
public void testUpdate_noEmail_errorEmailFieldRequired() throws Exception {
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", ImmutableMap.of("lastUpdateTime", getLastUpdateTime())));
assertThat(response).containsEntry("status", "ERROR");
assertThat(response).containsEntry("field", "emailAddress");
assertThat(response).containsEntry("message", "This field is required.");
assertNoTasksEnqueued("sheet");
@ -105,7 +119,7 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", ImmutableMap.of()));
"args", ImmutableMap.of("lastUpdateTime", getLastUpdateTime())));
assertThat(response).containsEntry("status", "SUCCESS");
}
@ -113,23 +127,53 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
public void testUpdate_badEmail_errorEmailField() throws Exception {
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", ImmutableMap.of(
"emailAddress", "lolcat")));
"args", ImmutableMap.of("lastUpdateTime", getLastUpdateTime(), "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_nonParsableTime_getsAngry() throws Exception {
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", ImmutableMap.of("lastUpdateTime", "cookies")));
assertThat(response).containsEntry("status", "ERROR");
assertThat(response).containsEntry("field", "lastUpdateTime");
assertThat(response).containsEntry("message", "Not a valid ISO date-time string.");
assertNoTasksEnqueued("sheet");
}
@Test
public void testPost_nonAsciiCharacters_getsAngry() throws Exception {
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"args", ImmutableMap.of(
"lastUpdateTime", getLastUpdateTime(),
"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");
}
private static String getLastUpdateTime() {
return loadRegistrar(CLIENT_ID).getLastUpdateTime().toString();
}
static Map<String, Object> readJsonFromFile(String filename, String lastUpdateTime) {
String contents =
loadFile(
RegistrarSettingsActionTestCase.class,
filename,
ImmutableMap.of("LAST_UPDATE_TIME", lastUpdateTime));
try {
@SuppressWarnings("unchecked")
Map<String, Object> json = (Map<String, Object>) JSONValue.parseWithException(contents);
return json;
} catch (ParseException ex) {
throw new RuntimeException(ex);
}
}
}

View file

@ -19,7 +19,6 @@ import static google.registry.config.RegistryConfig.getGSuiteOutgoingEmailDispla
import static google.registry.security.JsonHttpTestUtils.createJsonPayload;
import static google.registry.security.JsonHttpTestUtils.createJsonResponseSupplier;
import static google.registry.testing.DatastoreHelper.loadRegistrar;
import static google.registry.testing.TestDataHelper.loadFile;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ -50,8 +49,6 @@ 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;
@ -114,15 +111,4 @@ public class RegistrarSettingsActionTestCase {
.thenAnswer(x -> loadRegistrar(CLIENT_ID));
when(modulesService.getVersionHostname("backend", null)).thenReturn("backend.hostname");
}
static Map<String, Object> readJsonFromFile(String filename) {
String contents = loadFile(RegistrarSettingsActionTestCase.class, filename);
try {
@SuppressWarnings("unchecked")
Map<String, Object> json = (Map<String, Object>) JSONValue.parseWithException(contents);
return json;
} catch (ParseException ex) {
throw new RuntimeException(ex);
}
}
}

View file

@ -4,7 +4,7 @@
"clientIdentifier": "theregistrar",
"driveFolderId": null,
"registrarName": "The Registrar",
"lastUpdateTime": "2015-01-22T17:27:36.999Z",
"lastUpdateTime": "%LAST_UPDATE_TIME%",
"state": "ACTIVE",
"type": "REAL",
"contacts": [

View file

@ -4,7 +4,7 @@
"clientIdentifier": "theregistrar",
"driveFolderId": null,
"registrarName": "The Registrar",
"lastUpdateTime": "2015-01-22T17:27:36.999Z",
"lastUpdateTime": "%LAST_UPDATE_TIME%",
"state": "ACTIVE",
"type": "REAL",
"contacts": [