mirror of
https://github.com/google/nomulus.git
synced 2025-05-27 22:50:08 +02:00
Support premium list updating in Cloud SQL (#422)
* Support premium list updating in Cloud SQL This also removes the requirement to specify --also_cloud_sql in nomulus premium list tooling, instead always persisting to Cloud SQL. It removes a non-USD premium label in the global test premium list (the Cloud SQL schema doesn't support a mix of currency units in a single premium list). And it adds a method to PremiumListDao to grab the most recent version of a given list. * Merge branch 'master' into premium-lists-always-cloud-sql * Revert test change * Create new PremiumListUtils class and refactor out existing method * Fix tests and update an existing premium price
This commit is contained in:
parent
c17a5c489c
commit
8f67c4b9cf
18 changed files with 199 additions and 165 deletions
|
@ -80,7 +80,7 @@ public class PremiumListDao {
|
|||
* <p>Note that this does not load <code>PremiumList.labelsToPrices</code>! If you need to check
|
||||
* prices, use {@link #getPremiumPrice}.
|
||||
*/
|
||||
static Optional<PremiumList> getLatestRevision(String premiumListName) {
|
||||
public static Optional<PremiumList> getLatestRevision(String premiumListName) {
|
||||
return jpaTm()
|
||||
.transact(
|
||||
() ->
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright 2019 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.schema.tld;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import google.registry.model.registry.label.PremiumList.PremiumListEntry;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
|
||||
/** Static utility methods for {@link PremiumList}. */
|
||||
public class PremiumListUtils {
|
||||
|
||||
public static PremiumList parseToPremiumList(String name, String inputData) {
|
||||
List<String> inputDataPreProcessed =
|
||||
Splitter.on('\n').omitEmptyStrings().splitToList(inputData);
|
||||
|
||||
ImmutableMap<String, PremiumListEntry> prices =
|
||||
new google.registry.model.registry.label.PremiumList.Builder()
|
||||
.setName(name)
|
||||
.build()
|
||||
.parse(inputDataPreProcessed);
|
||||
ImmutableSet<CurrencyUnit> currencies =
|
||||
prices.values().stream()
|
||||
.map(e -> e.getValue().getCurrencyUnit())
|
||||
.distinct()
|
||||
.collect(toImmutableSet());
|
||||
checkArgument(
|
||||
currencies.size() == 1,
|
||||
"The Cloud SQL schema requires exactly one currency, but got: %s",
|
||||
ImmutableSortedSet.copyOf(currencies));
|
||||
CurrencyUnit currency = Iterables.getOnlyElement(currencies);
|
||||
|
||||
Map<String, BigDecimal> priceAmounts =
|
||||
Maps.transformValues(prices, ple -> ple.getValue().getAmount());
|
||||
return google.registry.schema.tld.PremiumList.create(name, currency, priceAmounts);
|
||||
}
|
||||
|
||||
private PremiumListUtils() {}
|
||||
}
|
|
@ -16,7 +16,6 @@ package google.registry.tools;
|
|||
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
import static google.registry.security.JsonHttp.JSON_SAFETY_PREFIX;
|
||||
import static google.registry.tools.server.CreateOrUpdatePremiumListAction.ALSO_CLOUD_SQL_PARAM;
|
||||
import static google.registry.tools.server.CreateOrUpdatePremiumListAction.INPUT_PARAM;
|
||||
import static google.registry.tools.server.CreateOrUpdatePremiumListAction.NAME_PARAM;
|
||||
import static google.registry.util.ListNamingUtils.convertFilePathToName;
|
||||
|
@ -58,12 +57,6 @@ abstract class CreateOrUpdatePremiumListCommand extends ConfirmingCommand
|
|||
required = true)
|
||||
Path inputFile;
|
||||
|
||||
@Parameter(
|
||||
names = {"--also_cloud_sql"},
|
||||
description =
|
||||
"Persist premium list to Cloud SQL in addition to Datastore; defaults to false.")
|
||||
boolean alsoCloudSql;
|
||||
|
||||
protected AppEngineConnection connection;
|
||||
protected int inputLineCount;
|
||||
|
||||
|
@ -97,7 +90,6 @@ abstract class CreateOrUpdatePremiumListCommand extends ConfirmingCommand
|
|||
public String execute() throws Exception {
|
||||
ImmutableMap.Builder<String, String> params = new ImmutableMap.Builder<>();
|
||||
params.put(NAME_PARAM, name);
|
||||
params.put(ALSO_CLOUD_SQL_PARAM, Boolean.toString(alsoCloudSql));
|
||||
String inputFileContents = new String(Files.readAllBytes(inputFile), UTF_8);
|
||||
String requestBody =
|
||||
Joiner.on('&').withKeyValueSeparator("=").join(
|
||||
|
|
|
@ -14,26 +14,13 @@
|
|||
|
||||
package google.registry.tools.server;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.common.flogger.LazyArgs.lazy;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import google.registry.model.registry.label.PremiumList;
|
||||
import google.registry.model.registry.label.PremiumList.PremiumListEntry;
|
||||
import google.registry.request.JsonResponse;
|
||||
import google.registry.request.Parameter;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
|
||||
/** Abstract base class for actions that update premium lists. */
|
||||
public abstract class CreateOrUpdatePremiumListAction implements Runnable {
|
||||
|
@ -44,7 +31,6 @@ public abstract class CreateOrUpdatePremiumListAction implements Runnable {
|
|||
|
||||
public static final String NAME_PARAM = "name";
|
||||
public static final String INPUT_PARAM = "inputData";
|
||||
public static final String ALSO_CLOUD_SQL_PARAM = "alsoCloudSql";
|
||||
|
||||
@Inject JsonResponse response;
|
||||
|
||||
|
@ -56,10 +42,6 @@ public abstract class CreateOrUpdatePremiumListAction implements Runnable {
|
|||
@Parameter(INPUT_PARAM)
|
||||
String inputData;
|
||||
|
||||
@Inject
|
||||
@Parameter(ALSO_CLOUD_SQL_PARAM)
|
||||
boolean alsoCloudSql;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
|
@ -76,40 +58,15 @@ public abstract class CreateOrUpdatePremiumListAction implements Runnable {
|
|||
return;
|
||||
}
|
||||
|
||||
if (alsoCloudSql) {
|
||||
try {
|
||||
saveToCloudSql();
|
||||
} catch (Throwable e) {
|
||||
logger.atSevere().withCause(e).log(
|
||||
"Unexpected error saving premium list to Cloud SQL from nomulus tool command");
|
||||
response.setPayload(ImmutableMap.of("error", e.toString(), "status", "error"));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
saveToCloudSql();
|
||||
} catch (Throwable e) {
|
||||
logger.atSevere().withCause(e).log(
|
||||
"Unexpected error saving premium list to Cloud SQL from nomulus tool command");
|
||||
response.setPayload(ImmutableMap.of("error", e.toString(), "status", "error"));
|
||||
}
|
||||
}
|
||||
|
||||
google.registry.schema.tld.PremiumList parseInputToPremiumList() {
|
||||
List<String> inputDataPreProcessed =
|
||||
Splitter.on('\n').omitEmptyStrings().splitToList(inputData);
|
||||
|
||||
ImmutableMap<String, PremiumListEntry> prices =
|
||||
new PremiumList.Builder().setName(name).build().parse(inputDataPreProcessed);
|
||||
ImmutableSet<CurrencyUnit> currencies =
|
||||
prices.values().stream()
|
||||
.map(e -> e.getValue().getCurrencyUnit())
|
||||
.distinct()
|
||||
.collect(toImmutableSet());
|
||||
checkArgument(
|
||||
currencies.size() == 1,
|
||||
"The Cloud SQL schema requires exactly one currency, but got: %s",
|
||||
ImmutableSortedSet.copyOf(currencies));
|
||||
CurrencyUnit currency = Iterables.getOnlyElement(currencies);
|
||||
|
||||
Map<String, BigDecimal> priceAmounts =
|
||||
Maps.transformValues(prices, ple -> ple.getValue().getAmount());
|
||||
return google.registry.schema.tld.PremiumList.create(name, currency, priceAmounts);
|
||||
}
|
||||
|
||||
/** Logs the premium list data at INFO, truncated if too long. */
|
||||
void logInputData() {
|
||||
logger.atInfo().log(
|
||||
|
|
|
@ -19,6 +19,7 @@ import static google.registry.model.registry.Registries.assertTldExists;
|
|||
import static google.registry.model.registry.label.PremiumListUtils.doesPremiumListExist;
|
||||
import static google.registry.model.registry.label.PremiumListUtils.savePremiumListAndEntries;
|
||||
import static google.registry.request.Action.Method.POST;
|
||||
import static google.registry.schema.tld.PremiumListUtils.parseToPremiumList;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
@ -81,7 +82,7 @@ public class CreatePremiumListAction extends CreateOrUpdatePremiumListAction {
|
|||
logger.atInfo().log("Saving premium list to Cloud SQL for TLD %s", name);
|
||||
// TODO(mcilwain): Call logInputData() here once Datastore persistence is removed.
|
||||
|
||||
google.registry.schema.tld.PremiumList premiumList = parseInputToPremiumList();
|
||||
google.registry.schema.tld.PremiumList premiumList = parseToPremiumList(name, inputData);
|
||||
PremiumListDao.saveNew(premiumList);
|
||||
|
||||
String message =
|
||||
|
|
|
@ -60,12 +60,6 @@ public class ToolsServerModule {
|
|||
return extractRequiredParameter(req, CreatePremiumListAction.INPUT_PARAM);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Parameter("alsoCloudSql")
|
||||
static boolean provideAlsoCloudSql(HttpServletRequest req) {
|
||||
return extractBooleanParameter(req, CreatePremiumListAction.ALSO_CLOUD_SQL_PARAM);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Parameter("premiumListName")
|
||||
static String provideName(HttpServletRequest req) {
|
||||
|
|
|
@ -17,6 +17,7 @@ package google.registry.tools.server;
|
|||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.model.registry.label.PremiumListUtils.savePremiumListAndEntries;
|
||||
import static google.registry.request.Action.Method.POST;
|
||||
import static google.registry.schema.tld.PremiumListUtils.parseToPremiumList;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
@ -24,6 +25,7 @@ import com.google.common.flogger.FluentLogger;
|
|||
import google.registry.model.registry.label.PremiumList;
|
||||
import google.registry.request.Action;
|
||||
import google.registry.request.auth.Auth;
|
||||
import google.registry.schema.tld.PremiumListDao;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import javax.inject.Inject;
|
||||
|
@ -68,10 +70,17 @@ public class UpdatePremiumListAction extends CreateOrUpdatePremiumListAction {
|
|||
response.setPayload(ImmutableMap.of("status", "success", "message", message));
|
||||
}
|
||||
|
||||
// TODO(mcilwain): Implement this in a subsequent PR.
|
||||
@Override
|
||||
protected void saveToCloudSql() {
|
||||
throw new UnsupportedOperationException(
|
||||
"Updating of premium lists in Cloud SQL is not supported yet");
|
||||
logger.atInfo().log("Updating premium list '%s' in Cloud SQL.", name);
|
||||
// TODO(mcilwain): Add logInputData() call here once DB migration is complete.
|
||||
google.registry.schema.tld.PremiumList premiumList = parseToPremiumList(name, inputData);
|
||||
PremiumListDao.update(premiumList);
|
||||
String message =
|
||||
String.format(
|
||||
"Updated premium list '%s' with %d entries.",
|
||||
premiumList.getName(), premiumList.getLabelsToPrices().size());
|
||||
logger.atInfo().log(message);
|
||||
// TODO(mcilwain): Call response.setPayload() here once DB migration is complete.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,13 @@ import google.registry.model.registry.RegistryLockDaoTest;
|
|||
import google.registry.model.transaction.JpaTestRules.JpaIntegrationTestRule;
|
||||
import google.registry.schema.cursor.CursorDaoTest;
|
||||
import google.registry.schema.tld.PremiumListDaoTest;
|
||||
import google.registry.schema.tld.PremiumListUtilsTest;
|
||||
import google.registry.schema.tld.ReservedListDaoTest;
|
||||
import google.registry.schema.tmch.ClaimsListDaoTest;
|
||||
import google.registry.tools.CreateReservedListCommandTest;
|
||||
import google.registry.tools.UpdateReservedListCommandTest;
|
||||
import google.registry.tools.server.CreatePremiumListActionTest;
|
||||
import google.registry.tools.server.UpdatePremiumListActionTest;
|
||||
import google.registry.ui.server.registrar.RegistryLockGetActionTest;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
|
@ -41,10 +44,13 @@ import org.junit.runners.Suite.SuiteClasses;
|
|||
ClaimsListDaoTest.class,
|
||||
CreateReservedListCommandTest.class,
|
||||
CursorDaoTest.class,
|
||||
CreatePremiumListActionTest.class,
|
||||
PremiumListDaoTest.class,
|
||||
PremiumListUtilsTest.class,
|
||||
RegistryLockDaoTest.class,
|
||||
RegistryLockGetActionTest.class,
|
||||
ReservedListDaoTest.class,
|
||||
UpdatePremiumListActionTest.class,
|
||||
UpdateReservedListCommandTest.class
|
||||
})
|
||||
public class SqlIntegrationTestSuite {}
|
||||
|
|
|
@ -32,8 +32,8 @@ import google.registry.model.transaction.JpaTestRules;
|
|||
import google.registry.model.transaction.JpaTestRules.JpaIntegrationTestRule;
|
||||
import google.registry.testing.AppEngineRule;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
import org.joda.money.Money;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
@ -66,13 +66,9 @@ public class PremiumListDaoTest {
|
|||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
PremiumList persistedList =
|
||||
jpaTm()
|
||||
.getEntityManager()
|
||||
.createQuery(
|
||||
"SELECT pl FROM PremiumList pl WHERE pl.name = :name", PremiumList.class)
|
||||
.setParameter("name", "testname")
|
||||
.getSingleResult();
|
||||
Optional<PremiumList> persistedListOpt = PremiumListDao.getLatestRevision("testname");
|
||||
assertThat(persistedListOpt).isPresent();
|
||||
PremiumList persistedList = persistedListOpt.get();
|
||||
assertThat(persistedList.getLabelsToPrices()).containsExactlyEntriesIn(TEST_PRICES);
|
||||
assertThat(persistedList.getCreationTimestamp())
|
||||
.isEqualTo(jpaRule.getTxnClock().nowUtc());
|
||||
|
@ -81,26 +77,40 @@ public class PremiumListDaoTest {
|
|||
|
||||
@Test
|
||||
public void update_worksSuccessfully() {
|
||||
PremiumListDao.saveNew(
|
||||
PremiumListDao.saveNew(PremiumList.create("testname", CurrencyUnit.USD, TEST_PRICES));
|
||||
Optional<PremiumList> persistedList = PremiumListDao.getLatestRevision("testname");
|
||||
assertThat(persistedList).isPresent();
|
||||
long firstRevisionId = persistedList.get().getRevisionId();
|
||||
PremiumListDao.update(
|
||||
PremiumList.create(
|
||||
"testname", USD, ImmutableMap.of("firstversion", BigDecimal.valueOf(123.45))));
|
||||
PremiumListDao.update(PremiumList.create("testname", USD, TEST_PRICES));
|
||||
"testname",
|
||||
CurrencyUnit.USD,
|
||||
ImmutableMap.of(
|
||||
"update",
|
||||
BigDecimal.valueOf(55343.12),
|
||||
"new",
|
||||
BigDecimal.valueOf(0.01),
|
||||
"silver",
|
||||
BigDecimal.valueOf(30.03))));
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
List<PremiumList> persistedLists =
|
||||
jpaTm()
|
||||
.getEntityManager()
|
||||
.createQuery(
|
||||
"SELECT pl FROM PremiumList pl WHERE pl.name = :name ORDER BY"
|
||||
+ " pl.revisionId",
|
||||
PremiumList.class)
|
||||
.setParameter("name", "testname")
|
||||
.getResultList();
|
||||
assertThat(persistedLists).hasSize(2);
|
||||
assertThat(persistedLists.get(1).getLabelsToPrices())
|
||||
.containsExactlyEntriesIn(TEST_PRICES);
|
||||
assertThat(persistedLists.get(1).getCreationTimestamp())
|
||||
Optional<PremiumList> updatedListOpt = PremiumListDao.getLatestRevision("testname");
|
||||
assertThat(updatedListOpt).isPresent();
|
||||
PremiumList updatedList = updatedListOpt.get();
|
||||
assertThat(updatedList.getLabelsToPrices())
|
||||
.containsExactlyEntriesIn(
|
||||
ImmutableMap.of(
|
||||
"update",
|
||||
BigDecimal.valueOf(55343.12),
|
||||
"new",
|
||||
BigDecimal.valueOf(0.01),
|
||||
"silver",
|
||||
BigDecimal.valueOf(30.03)));
|
||||
assertThat(updatedList.getCreationTimestamp())
|
||||
.isEqualTo(jpaRule.getTxnClock().nowUtc());
|
||||
assertThat(updatedList.getRevisionId()).isGreaterThan(firstRevisionId);
|
||||
assertThat(updatedList.getCreationTimestamp())
|
||||
.isEqualTo(jpaRule.getTxnClock().nowUtc());
|
||||
});
|
||||
}
|
||||
|
@ -116,7 +126,7 @@ public class PremiumListDaoTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void update_throwsWhenPremiumListDoesntExist() {
|
||||
public void update_throwsWhenListDoesntExist() {
|
||||
IllegalArgumentException thrown =
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
|
||||
// Copyright 2019 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.
|
||||
|
@ -12,43 +12,35 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.tools.server;
|
||||
package google.registry.schema.tld;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.common.truth.Truth8.assertThat;
|
||||
import static google.registry.schema.tld.PremiumListUtils.parseToPremiumList;
|
||||
import static google.registry.testing.JUnitBackports.assertThrows;
|
||||
|
||||
import google.registry.schema.tld.PremiumList;
|
||||
import google.registry.model.transaction.JpaTestRules;
|
||||
import google.registry.model.transaction.JpaTestRules.JpaIntegrationTestRule;
|
||||
import google.registry.testing.AppEngineRule;
|
||||
import google.registry.testing.FakeJsonResponse;
|
||||
import java.math.BigDecimal;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/** Unit tests for {@link CreateOrUpdatePremiumListAction}. */
|
||||
/** Unit tests for {@link PremiumListUtils}. */
|
||||
@RunWith(JUnit4.class)
|
||||
public class CreateOrUpdatePremiumListActionTest {
|
||||
public class PremiumListUtilsTest {
|
||||
|
||||
@Rule public final AppEngineRule appEngine = AppEngineRule.builder().withDatastore().build();
|
||||
|
||||
private CreatePremiumListAction action;
|
||||
private FakeJsonResponse response;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
action = new CreatePremiumListAction();
|
||||
response = new FakeJsonResponse();
|
||||
action.response = response;
|
||||
action.name = "testlist";
|
||||
}
|
||||
@Rule
|
||||
public final JpaIntegrationTestRule jpaRule =
|
||||
new JpaTestRules.Builder().buildIntegrationTestRule();
|
||||
|
||||
@Test
|
||||
public void parseInputToPremiumList_works() {
|
||||
action.inputData = "foo,USD 99.50\n" + "bar,USD 30\n" + "baz,USD 10\n";
|
||||
PremiumList premiumList = action.parseInputToPremiumList();
|
||||
PremiumList premiumList =
|
||||
parseToPremiumList("testlist", "foo,USD 99.50\n" + "bar,USD 30\n" + "baz,USD 10\n");
|
||||
assertThat(premiumList.getName()).isEqualTo("testlist");
|
||||
assertThat(premiumList.getLabelsToPrices())
|
||||
.containsExactly("foo", twoDigits(99.50), "bar", twoDigits(30), "baz", twoDigits(10));
|
||||
|
@ -56,9 +48,12 @@ public class CreateOrUpdatePremiumListActionTest {
|
|||
|
||||
@Test
|
||||
public void parseInputToPremiumList_throwsOnInconsistentCurrencies() {
|
||||
action.inputData = "foo,USD 99.50\n" + "bar,USD 30\n" + "baz,JPY 990\n";
|
||||
IllegalArgumentException thrown =
|
||||
assertThrows(IllegalArgumentException.class, () -> action.parseInputToPremiumList());
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() ->
|
||||
parseToPremiumList(
|
||||
"testlist", "foo,USD 99.50\n" + "bar,USD 30\n" + "baz,JPY 990\n"));
|
||||
assertThat(thrown)
|
||||
.hasMessageThat()
|
||||
.isEqualTo("The Cloud SQL schema requires exactly one currency, but got: [JPY, USD]");
|
|
@ -16,9 +16,13 @@ package google.registry.tools;
|
|||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.testing.DatastoreHelper.createTld;
|
||||
import static google.registry.testing.DatastoreHelper.persistPremiumList;
|
||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
||||
import static google.registry.testing.JUnitBackports.assertThrows;
|
||||
|
||||
import com.beust.jcommander.ParameterException;
|
||||
import google.registry.model.registry.Registry;
|
||||
import google.registry.model.registry.label.PremiumList;
|
||||
import google.registry.testing.DeterministicStringGenerator;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -91,7 +95,14 @@ public class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomain
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_premiumDomain() throws Exception {
|
||||
public void testSuccess_premiumJpyDomain() throws Exception {
|
||||
createTld("baar");
|
||||
persistPremiumList("baar", "parajiumu,JPY 96083");
|
||||
persistResource(
|
||||
Registry.get("baar")
|
||||
.asBuilder()
|
||||
.setPremiumList(PremiumList.getUncached("baar").get())
|
||||
.build());
|
||||
runCommandForced(
|
||||
"--client=NewRegistrar",
|
||||
"--registrant=crr-admin",
|
||||
|
@ -99,10 +110,10 @@ public class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomain
|
|||
"--techs=crr-tech",
|
||||
"--period=3",
|
||||
"--force_premiums",
|
||||
"parajiumu.tld");
|
||||
"parajiumu.baar");
|
||||
eppVerifier.verifySent("domain_create_parajiumu_3yrs.xml");
|
||||
assertInStdout(
|
||||
"parajiumu.tld is premium at JPY 96083 per year; "
|
||||
"parajiumu.baar is premium at JPY 96083 per year; "
|
||||
+ "sending total cost for 3 year(s) of JPY 288249.");
|
||||
}
|
||||
|
||||
|
|
|
@ -67,13 +67,7 @@ public class CreatePremiumListCommandTest<C extends CreatePremiumListCommand>
|
|||
verifySentParams(
|
||||
connection,
|
||||
servletPath,
|
||||
ImmutableMap.of(
|
||||
"name",
|
||||
"foo",
|
||||
"inputData",
|
||||
generateInputData(premiumTermsPath),
|
||||
"alsoCloudSql",
|
||||
"false"));
|
||||
ImmutableMap.of("name", "foo", "inputData", generateInputData(premiumTermsPath)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -84,28 +78,7 @@ public class CreatePremiumListCommandTest<C extends CreatePremiumListCommand>
|
|||
connection,
|
||||
servletPath,
|
||||
ImmutableMap.of(
|
||||
"name",
|
||||
"example_premium_terms",
|
||||
"inputData",
|
||||
generateInputData(premiumTermsPath),
|
||||
"alsoCloudSql",
|
||||
"false"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun_alsoCloudSql() throws Exception {
|
||||
runCommandForced("-i=" + premiumTermsPath, "-n=foo", "--also_cloud_sql");
|
||||
assertInStdout("Successfully");
|
||||
verifySentParams(
|
||||
connection,
|
||||
servletPath,
|
||||
ImmutableMap.of(
|
||||
"name",
|
||||
"foo",
|
||||
"inputData",
|
||||
generateInputData(premiumTermsPath),
|
||||
"alsoCloudSql",
|
||||
"true"));
|
||||
"name", "example_premium_terms", "inputData", generateInputData(premiumTermsPath)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -57,13 +57,7 @@ public class UpdatePremiumListCommandTest<C extends UpdatePremiumListCommand>
|
|||
verifySentParams(
|
||||
connection,
|
||||
servletPath,
|
||||
ImmutableMap.of(
|
||||
"name",
|
||||
"foo",
|
||||
"inputData",
|
||||
generateInputData(premiumTermsPath),
|
||||
"alsoCloudSql",
|
||||
"false"));
|
||||
ImmutableMap.of("name", "foo", "inputData", generateInputData(premiumTermsPath)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -74,11 +68,6 @@ public class UpdatePremiumListCommandTest<C extends UpdatePremiumListCommand>
|
|||
connection,
|
||||
servletPath,
|
||||
ImmutableMap.of(
|
||||
"name",
|
||||
"example_premium_terms",
|
||||
"inputData",
|
||||
generateInputData(premiumTermsPath),
|
||||
"alsoCloudSql",
|
||||
"false"));
|
||||
"name", "example_premium_terms", "inputData", generateInputData(premiumTermsPath)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ import static javax.servlet.http.HttpServletResponse.SC_OK;
|
|||
|
||||
import google.registry.model.registry.Registry;
|
||||
import google.registry.model.registry.label.PremiumList;
|
||||
import google.registry.model.transaction.JpaTestRules;
|
||||
import google.registry.model.transaction.JpaTestRules.JpaIntegrationTestRule;
|
||||
import google.registry.testing.AppEngineRule;
|
||||
import google.registry.testing.FakeJsonResponse;
|
||||
import org.joda.money.Money;
|
||||
|
@ -39,6 +41,10 @@ import org.junit.runners.JUnit4;
|
|||
@RunWith(JUnit4.class)
|
||||
public class CreatePremiumListActionTest {
|
||||
|
||||
@Rule
|
||||
public final JpaIntegrationTestRule jpaRule =
|
||||
new JpaTestRules.Builder().buildIntegrationTestRule();
|
||||
|
||||
@Rule public final AppEngineRule appEngine = AppEngineRule.builder().withDatastore().build();
|
||||
CreatePremiumListAction action;
|
||||
FakeJsonResponse response;
|
||||
|
|
|
@ -17,14 +17,22 @@ package google.registry.tools.server;
|
|||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.common.truth.Truth8.assertThat;
|
||||
import static google.registry.model.registry.label.PremiumListUtils.getPremiumPrice;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.jpaTm;
|
||||
import static google.registry.schema.tld.PremiumListUtils.parseToPremiumList;
|
||||
import static google.registry.testing.DatastoreHelper.createTlds;
|
||||
import static google.registry.testing.DatastoreHelper.loadPremiumListEntries;
|
||||
import static google.registry.util.ResourceUtils.readResourceUtf8;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
||||
|
||||
import google.registry.model.registry.Registry;
|
||||
import google.registry.model.registry.label.PremiumList;
|
||||
import google.registry.model.transaction.JpaTestRules;
|
||||
import google.registry.model.transaction.JpaTestRules.JpaIntegrationTestRule;
|
||||
import google.registry.schema.tld.PremiumListDao;
|
||||
import google.registry.testing.AppEngineRule;
|
||||
import google.registry.testing.DatastoreHelper;
|
||||
import google.registry.testing.FakeJsonResponse;
|
||||
import java.math.BigDecimal;
|
||||
import org.joda.money.Money;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
|
@ -38,10 +46,11 @@ import org.junit.runners.JUnit4;
|
|||
@RunWith(JUnit4.class)
|
||||
public class UpdatePremiumListActionTest {
|
||||
|
||||
@Rule public final AppEngineRule appEngine = AppEngineRule.builder().withDatastore().build();
|
||||
|
||||
@Rule
|
||||
public final AppEngineRule appEngine = AppEngineRule.builder()
|
||||
.withDatastore()
|
||||
.build();
|
||||
public final JpaIntegrationTestRule jpaRule =
|
||||
new JpaTestRules.Builder().buildIntegrationTestRule();
|
||||
|
||||
UpdatePremiumListAction action;
|
||||
FakeJsonResponse response;
|
||||
|
@ -75,6 +84,9 @@ public class UpdatePremiumListActionTest {
|
|||
|
||||
@Test
|
||||
public void test_success() {
|
||||
PremiumListDao.saveNew(
|
||||
parseToPremiumList(
|
||||
"foo", readResourceUtf8(DatastoreHelper.class, "default_premium_list_testdata.csv")));
|
||||
action.name = "foo";
|
||||
action.inputData = "rich,USD 75\nricher,USD 5000\npoor, USD 0.99";
|
||||
action.run();
|
||||
|
@ -85,5 +97,19 @@ public class UpdatePremiumListActionTest {
|
|||
assertThat(getPremiumPrice("richer", registry)).hasValue(Money.parse("USD 5000"));
|
||||
assertThat(getPremiumPrice("poor", registry)).hasValue(Money.parse("USD 0.99"));
|
||||
assertThat(getPremiumPrice("diamond", registry)).isEmpty();
|
||||
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
google.registry.schema.tld.PremiumList persistedList =
|
||||
PremiumListDao.getLatestRevision("foo").get();
|
||||
assertThat(persistedList.getLabelsToPrices())
|
||||
.containsEntry("rich", new BigDecimal("75.00"));
|
||||
assertThat(persistedList.getLabelsToPrices())
|
||||
.containsEntry("richer", new BigDecimal("5000.00"));
|
||||
assertThat(persistedList.getLabelsToPrices())
|
||||
.containsEntry("poor", BigDecimal.valueOf(0.99));
|
||||
assertThat(persistedList.getLabelsToPrices()).doesNotContainKey("diamond");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,4 +10,3 @@ palladium,USD 877
|
|||
aluminum,USD 11
|
||||
copper,USD 15
|
||||
brass,USD 20
|
||||
parajiumu,JPY 96083
|
||||
|
|
|
|
@ -4,7 +4,7 @@
|
|||
<create>
|
||||
<domain:create
|
||||
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>parajiumu.tld</domain:name>
|
||||
<domain:name>parajiumu.baar</domain:name>
|
||||
<domain:period unit="y">3</domain:period>
|
||||
<domain:registrant>crr-admin</domain:registrant>
|
||||
<domain:contact type="admin">crr-admin</domain:contact>
|
||||
|
|
|
@ -29,7 +29,9 @@ public abstract class EmailMessage {
|
|||
public abstract String body();
|
||||
public abstract ImmutableList<InternetAddress> recipients();
|
||||
public abstract InternetAddress from();
|
||||
|
||||
public abstract ImmutableList<InternetAddress> bccs();
|
||||
|
||||
public abstract Optional<MediaType> contentType();
|
||||
public abstract Optional<Attachment> attachment();
|
||||
|
||||
|
@ -55,11 +57,14 @@ public abstract class EmailMessage {
|
|||
public abstract Builder setBody(String body);
|
||||
public abstract Builder setRecipients(Collection<InternetAddress> recipients);
|
||||
public abstract Builder setFrom(InternetAddress from);
|
||||
|
||||
public abstract Builder setBccs(Collection<InternetAddress> bccs);
|
||||
|
||||
public abstract Builder setContentType(MediaType contentType);
|
||||
public abstract Builder setAttachment(Attachment attachment);
|
||||
|
||||
abstract ImmutableList.Builder<InternetAddress> recipientsBuilder();
|
||||
|
||||
abstract ImmutableList.Builder<InternetAddress> bccsBuilder();
|
||||
|
||||
public Builder addRecipient(InternetAddress value) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue