From b435e20cbe1269ac87208cb10ad840b7d833ccb1 Mon Sep 17 00:00:00 2001 From: ctingue Date: Thu, 5 May 2016 08:01:27 -0700 Subject: [PATCH] Add ability to expand TimeOfYear into instances Utilizing this function in the recurring billing event [], in order to abstract a lot of the expansion logic out of the MR itself. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=121579246 --- .../flows/domain/DomainDeleteFlow.java | 2 +- .../registry/model/common/TimeOfYear.java | 22 +++++- .../registry/model/common/TimeOfYearTest.java | 67 +++++++++++++++++-- 3 files changed, 81 insertions(+), 10 deletions(-) diff --git a/java/google/registry/flows/domain/DomainDeleteFlow.java b/java/google/registry/flows/domain/DomainDeleteFlow.java index 3f45b5f7d..24cc860b0 100644 --- a/java/google/registry/flows/domain/DomainDeleteFlow.java +++ b/java/google/registry/flows/domain/DomainDeleteFlow.java @@ -138,7 +138,7 @@ public class DomainDeleteFlow extends ResourceSyncDeleteFlow getInstancesInRange(DateTime lower, DateTime upper) { + checkArgument(isBeforeOrAt(lower, upper), "Lower bound is not before or at upper bound."); + ImmutableSet.Builder instances = ImmutableSet.builder(); + DateTime firstInstance = getNextInstanceAtOrAfter(lower); + for (int year = firstInstance.getYear(); + year <= getLastInstanceBeforeOrAt(upper).getYear(); + year++) { + instances.add(firstInstance.withYear(year)); + } + return instances.build(); + } + /** Get the first {@link DateTime} with this month/day/millis that is at or after the start. */ - public DateTime atOrAfter(DateTime start) { + public DateTime getNextInstanceAtOrAfter(DateTime start) { DateTime withSameYear = getDateTimeWithSameYear(start); return isAtOrAfter(withSameYear, start) ? withSameYear : withSameYear.plusYears(1); } /** Get the first {@link DateTime} with this month/day/millis that is at or before the end. */ - public DateTime beforeOrAt(DateTime end) { + public DateTime getLastInstanceBeforeOrAt(DateTime end) { DateTime withSameYear = getDateTimeWithSameYear(end); return isBeforeOrAt(withSameYear, end) ? withSameYear : withSameYear.minusYears(1); } diff --git a/javatests/google/registry/model/common/TimeOfYearTest.java b/javatests/google/registry/model/common/TimeOfYearTest.java index c5e59747a..019a8fa54 100644 --- a/javatests/google/registry/model/common/TimeOfYearTest.java +++ b/javatests/google/registry/model/common/TimeOfYearTest.java @@ -16,7 +16,12 @@ package google.registry.model.common; import static com.google.common.truth.Truth.assertThat; +import com.google.common.collect.ImmutableSet; + +import google.registry.testing.ExceptionRule; + import org.joda.time.DateTime; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -29,28 +34,76 @@ public class TimeOfYearTest { private static final DateTime february29 = DateTime.parse("2012-02-29T01:02:03.0Z"); private static final DateTime march1 = DateTime.parse("2012-03-01T01:02:03.0Z"); + @Rule + public final ExceptionRule thrown = new ExceptionRule(); + @Test - public void testFromDateTime() throws Exception { + public void testSuccess_fromDateTime() throws Exception { // We intentionally don't allow leap years in TimeOfYear, so February 29 should be February 28. assertThat(TimeOfYear.fromDateTime(february28)).isEqualTo(TimeOfYear.fromDateTime(february29)); assertThat(TimeOfYear.fromDateTime(february29)).isNotEqualTo(TimeOfYear.fromDateTime(march1)); } @Test - public void testNextAfter() throws Exception { + public void testSuccess_nextAfter() throws Exception { // This should be lossless because atOrAfter includes an exact match. - assertThat(TimeOfYear.fromDateTime(march1).atOrAfter(march1)).isEqualTo(march1); + assertThat(TimeOfYear.fromDateTime(march1).getNextInstanceAtOrAfter(march1)).isEqualTo(march1); // This should be a year later because we stepped forward a millisecond - assertThat(TimeOfYear.fromDateTime(march1).atOrAfter(march1.plusMillis(1))) + assertThat(TimeOfYear.fromDateTime(march1).getNextInstanceAtOrAfter(march1.plusMillis(1))) .isEqualTo(march1.plusYears(1)); } @Test - public void testNextBefore() throws Exception { + public void testSuccess_nextBefore() throws Exception { // This should be lossless because beforeOrAt includes an exact match. - assertThat(TimeOfYear.fromDateTime(march1).beforeOrAt(march1)).isEqualTo(march1); + assertThat(TimeOfYear.fromDateTime(march1).getLastInstanceBeforeOrAt(march1)).isEqualTo(march1); // This should be a year earlier because we stepped backward a millisecond - assertThat(TimeOfYear.fromDateTime(march1).beforeOrAt(march1.minusMillis(1))) + assertThat(TimeOfYear.fromDateTime(march1).getLastInstanceBeforeOrAt(march1.minusMillis(1))) .isEqualTo(march1.minusYears(1)); } + + @Test + public void testSuccess_getInstancesOfTimeOfYearInRange() { + DateTime startDate = DateTime.parse("2012-05-01T00:00:00Z"); + DateTime endDate = DateTime.parse("2016-02-01T00:00:00Z"); + TimeOfYear timeOfYear = TimeOfYear.fromDateTime(DateTime.parse("2012-10-01T00:00:00Z")); + ImmutableSet actual = timeOfYear.getInstancesInRange(startDate, endDate); + ImmutableSet expected = ImmutableSet.of( + DateTime.parse("2012-10-01T00:00:00Z"), + DateTime.parse("2013-10-01T00:00:00Z"), + DateTime.parse("2014-10-01T00:00:00Z"), + DateTime.parse("2015-10-01T00:00:00Z")); + assertThat(actual).containsExactlyElementsIn(expected); + } + + @Test + public void testSuccess_getInstancesOfTimeOfYearInRange_empty() { + DateTime startDate = DateTime.parse("2012-05-01T00:00:00Z"); + DateTime endDate = DateTime.parse("2013-02-01T00:00:00Z"); + TimeOfYear timeOfYear = TimeOfYear.fromDateTime(DateTime.parse("2012-03-01T00:00:00Z")); + ImmutableSet actual = timeOfYear.getInstancesInRange(startDate, endDate); + assertThat(actual).isEmpty(); + } + + @Test + public void testSuccess_getInstancesOfTimeOfYearInRange_inclusive() { + DateTime startDate = DateTime.parse("2012-05-01T00:00:00Z"); + DateTime endDate = DateTime.parse("2015-05-01T00:00:00Z"); + TimeOfYear timeOfYear = TimeOfYear.fromDateTime(DateTime.parse("2012-05-01T00:00:00Z")); + ImmutableSet actual = timeOfYear.getInstancesInRange(startDate, endDate); + ImmutableSet expected = ImmutableSet.of( + DateTime.parse("2012-05-01T00:00:00Z"), + DateTime.parse("2013-05-01T00:00:00Z"), + DateTime.parse("2014-05-01T00:00:00Z"), + DateTime.parse("2015-05-01T00:00:00Z")); + assertThat(actual).containsExactlyElementsIn(expected); + } + + @Test + public void testFailure_getInstancesOfTimeOfYearInRange_inverted() { + thrown.expect(IllegalArgumentException.class, "Lower bound is not before or at upper bound."); + TimeOfYear.fromDateTime(DateTime.parse("2013-10-01T00:00:00Z")).getInstancesInRange( + DateTime.parse("2015-10-01T00:00:00Z"), + DateTime.parse("2012-10-01T00:00:00Z")); + } }