killbill-memoizeit
Changes
junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DisabledDuration.java 12(+10 -2)
Details
diff --git a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DisabledDuration.java b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DisabledDuration.java
index 78633b9..d8f7870 100644
--- a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DisabledDuration.java
+++ b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DisabledDuration.java
@@ -19,6 +19,8 @@ package org.killbill.billing.junction.plumbing.billing;
import org.joda.time.DateTime;
+import com.google.common.base.Preconditions;
+
class DisabledDuration implements Comparable<DisabledDuration> {
private final DateTime start;
@@ -105,11 +107,17 @@ class DisabledDuration implements Comparable<DisabledDuration> {
// |---------| this
// |---| o
public boolean isDisjoint(final DisabledDuration o) {
- return end.compareTo(o.getStart()) < 0;
+ return end!= null && end.compareTo(o.getStart()) < 0;
}
public static DisabledDuration mergeDuration(DisabledDuration d1, DisabledDuration d2) {
- final DateTime endDate = d1.getEnd().compareTo(d2.getEnd()) < 0 ? d2.getEnd() : d1.getEnd();
+ Preconditions.checkState(d1.getStart().compareTo(d2.getStart()) <=0 );
+ Preconditions.checkState(!d1.isDisjoint(d2));
+
+ final DateTime endDate = (d1.getEnd() != null && d2.getEnd() != null) ?
+ d1.getEnd().compareTo(d2.getEnd()) < 0 ? d2.getEnd() : d1.getEnd() :
+ null;
+
return new DisabledDuration(d1.getStart(), endDate);
}
diff --git a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBlockingStateNesting.java b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBlockingStateNesting.java
index b4e0806..adf4e8d 100644
--- a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBlockingStateNesting.java
+++ b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBlockingStateNesting.java
@@ -55,10 +55,10 @@ public class TestBlockingStateNesting extends JunctionTestSuiteNoDB {
final DateTimeZone tz = DateTimeZone.forID("America/Los_Angeles");
final DateTime testInit = new DateTime(2017, 04, 29, 14, 15, 53, tz);
clock.setTime(testInit);
- input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, "SVC", true, testInit));
- input.add(createBillingBlockingState(BlockingStateType.SUBSCRIPTION_BUNDLE, "SVC", true, testInit.plusDays(1)));
- input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, "SVC", false, testInit.plusDays(2)));
- input.add(createBillingBlockingState(BlockingStateType.SUBSCRIPTION_BUNDLE, "SVC", false, testInit.plusDays(3)));
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, true, testInit));
+ input.add(createBillingBlockingState(BlockingStateType.SUBSCRIPTION_BUNDLE, true, testInit.plusDays(1)));
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, false, testInit.plusDays(2)));
+ input.add(createBillingBlockingState(BlockingStateType.SUBSCRIPTION_BUNDLE, false, testInit.plusDays(3)));
final BlockingStateNesting test = new BlockingStateNesting();
for (BlockingState cur : input) {
@@ -86,9 +86,9 @@ public class TestBlockingStateNesting extends JunctionTestSuiteNoDB {
final DateTimeZone tz = DateTimeZone.forID("America/Los_Angeles");
final DateTime testInit = new DateTime(2017, 04, 29, 14, 15, 53, tz);
clock.setTime(testInit);
- input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, "SVC", true, testInit));
- input.add(createBillingBlockingState(BlockingStateType.SUBSCRIPTION_BUNDLE, "SVC", true, testInit.plusDays(1)));
- input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, "SVC", false, testInit.plusDays(2)));
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, true, testInit));
+ input.add(createBillingBlockingState(BlockingStateType.SUBSCRIPTION_BUNDLE, true, testInit.plusDays(1)));
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, false, testInit.plusDays(2)));
final BlockingStateNesting test = new BlockingStateNesting();
for (BlockingState cur : input) {
@@ -115,10 +115,10 @@ public class TestBlockingStateNesting extends JunctionTestSuiteNoDB {
final DateTimeZone tz = DateTimeZone.forID("America/Los_Angeles");
final DateTime testInit = new DateTime(2017, 04, 29, 14, 15, 53, tz);
clock.setTime(testInit);
- input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, "SVC", true, testInit));
- input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, "SVC", false, testInit.plusDays(1)));
- input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, "SVC", true, testInit.plusDays(2)));
- input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, "SVC", false, testInit.plusDays(3)));
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, true, testInit));
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, false, testInit.plusDays(1)));
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, true, testInit.plusDays(2)));
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, false, testInit.plusDays(3)));
final BlockingStateNesting test = new BlockingStateNesting();
for (BlockingState cur : input) {
@@ -147,10 +147,10 @@ public class TestBlockingStateNesting extends JunctionTestSuiteNoDB {
final DateTimeZone tz = DateTimeZone.forID("America/Los_Angeles");
final DateTime testInit = new DateTime(2017, 04, 29, 14, 15, 53, tz);
clock.setTime(testInit);
- input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, "SVC", true, testInit));
- input.add(createBillingBlockingState(BlockingStateType.SUBSCRIPTION_BUNDLE, "SVC", true, testInit));
- input.add(createBillingBlockingState(BlockingStateType.SUBSCRIPTION_BUNDLE, "SVC", false, testInit.plusDays(1)));
- input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, "SVC", false, testInit.plusDays(2)));
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, true, testInit));
+ input.add(createBillingBlockingState(BlockingStateType.SUBSCRIPTION_BUNDLE, true, testInit));
+ input.add(createBillingBlockingState(BlockingStateType.SUBSCRIPTION_BUNDLE, false, testInit.plusDays(1)));
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, false, testInit.plusDays(2)));
final BlockingStateNesting test = new BlockingStateNesting();
for (BlockingState cur : input) {
@@ -178,8 +178,8 @@ public class TestBlockingStateNesting extends JunctionTestSuiteNoDB {
final DateTimeZone tz = DateTimeZone.forID("America/Los_Angeles");
final DateTime testInit = new DateTime(2017, 04, 29, 14, 15, 53, tz);
clock.setTime(testInit);
- input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, "SVC", true, testInit));
- input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, "SVC", false, testInit));
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, true, testInit));
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, false, testInit));
final BlockingStateNesting test = new BlockingStateNesting();
for (BlockingState cur : input) {
@@ -200,15 +200,15 @@ public class TestBlockingStateNesting extends JunctionTestSuiteNoDB {
// Expected: None
//
@Test(groups = "fast")
- public void testBlockingUnblockingDatesLessThanADay() throws Exception {
+ public void testBlockingUnblockingDatesLessThanADay1() throws Exception {
final List<BlockingState> input = new ArrayList<BlockingState>();
final DateTimeZone tz = DateTimeZone.forID("America/Los_Angeles");
final DateTime testInit = new DateTime(2017, 04, 29, 14, 15, 53, tz);
clock.setTime(testInit);
- input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, "SVC", true, testInit));
- input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, "SVC", false, testInit.plusHours(10)));
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, true, testInit));
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, false, testInit.plusHours(10)));
final BlockingStateNesting test = new BlockingStateNesting();
for (BlockingState cur : input) {
@@ -222,6 +222,67 @@ public class TestBlockingStateNesting extends JunctionTestSuiteNoDB {
}
+ // B BU
+ // |-------|
+ // A AA
+ //
+ // Expected: B--------
+ //
+ @Test(groups = "fast")
+ public void testBlockingUnblockingDatesLessThanADay2() throws Exception {
+
+ final List<BlockingState> input = new ArrayList<BlockingState>();
+
+ final DateTimeZone tz = DateTimeZone.forID("America/Los_Angeles");
+ final DateTime testInit = new DateTime(2017, 04, 29, 14, 15, 53, tz);
+ clock.setTime(testInit);
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, true, testInit));
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, false, testInit.plusDays(1)));
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, true, testInit.plusDays(1)));
+
+ final BlockingStateNesting test = new BlockingStateNesting();
+ for (BlockingState cur : input) {
+ test.addBlockingState(cur);
+ }
+ final List<DisabledDuration> result = test.build();
+
+ final List<DisabledDuration> expected = ImmutableList.of(new DisabledDuration(testInit, testInit.plusDays(1)),
+ new DisabledDuration(testInit.plusDays(1), null));
+
+ verify(result, expected);
+ }
+
+
+ // B BU
+ // |-------|
+ // A AA
+ //
+ // Expected: B--------
+ //
+ @Test(groups = "fast")
+ public void testBlockingUnblockingDatesLessThanADay3() throws Exception {
+
+ final List<BlockingState> input = new ArrayList<BlockingState>();
+
+ final DateTimeZone tz = DateTimeZone.forID("America/Los_Angeles");
+ final DateTime testInit = new DateTime(2017, 04, 29, 14, 15, 53, tz);
+ clock.setTime(testInit);
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, true, testInit));
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, true, testInit.plusDays(1)));
+ input.add(createBillingBlockingState(BlockingStateType.ACCOUNT, false, testInit.plusDays(1)));
+
+ final BlockingStateNesting test = new BlockingStateNesting();
+ for (BlockingState cur : input) {
+ test.addBlockingState(cur);
+ }
+ final List<DisabledDuration> result = test.build();
+
+ final List<DisabledDuration> expected = ImmutableList.of(new DisabledDuration(testInit, null));
+
+ verify(result, expected);
+ }
+
+
private void verify(final List<DisabledDuration> actual, final List<DisabledDuration> expected) {
assertEquals(expected.size(), actual.size());
@@ -230,8 +291,8 @@ public class TestBlockingStateNesting extends JunctionTestSuiteNoDB {
}
}
- private BlockingState createBillingBlockingState(final BlockingStateType type, final String service, final boolean blockBilling, final DateTime effectiveDate) {
- return new DefaultBlockingState(UUID.randomUUID(), type, UUID.randomUUID().toString(), service, false, false, blockBilling, effectiveDate);
+ private BlockingState createBillingBlockingState(final BlockingStateType type, final boolean blockBilling, final DateTime effectiveDate) {
+ return new DefaultBlockingState(UUID.randomUUID(), type, UUID.randomUUID().toString(), "SVC", false, false, blockBilling, effectiveDate);
}
}
\ No newline at end of file
diff --git a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDisabledDuration.java b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDisabledDuration.java
new file mode 100644
index 0000000..64f323b
--- /dev/null
+++ b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDisabledDuration.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you 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 org.killbill.billing.junction.plumbing.billing;
+
+import org.joda.time.DateTime;
+import org.killbill.billing.junction.JunctionTestSuiteNoDB;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+public class TestDisabledDuration extends JunctionTestSuiteNoDB {
+
+ @Test(groups = "fast")
+ public void testCompare0() throws Exception {
+ final DateTime now = clock.getUTCNow();
+ final DisabledDuration d1 = new DisabledDuration(now, now.plusHours(10));
+ final DisabledDuration d2 = new DisabledDuration(now, now.plusHours(10));
+ assertEquals(d1.compareTo(d2), 0);
+ assertTrue(d1.equals(d2));
+ }
+
+ @Test(groups = "fast")
+ public void testCompare1() throws Exception {
+ final DateTime now = clock.getUTCNow();
+ final DisabledDuration d1 = new DisabledDuration(now, now.plusHours(10));
+ final DisabledDuration d2 = new DisabledDuration(now.plusSeconds(1), now.plusHours(10));
+ assertEquals(d1.compareTo(d2), -1);
+ assertEquals(d2.compareTo(d1), 1);
+ }
+
+ @Test(groups = "fast")
+ public void testCompare2() throws Exception {
+ final DateTime now = clock.getUTCNow();
+ final DisabledDuration d1 = new DisabledDuration(now, now.plusHours(10));
+ final DisabledDuration d2 = new DisabledDuration(now.plusSeconds(1), now.plusHours(10));
+ assertEquals(d1.compareTo(d2), -1);
+ assertEquals(d2.compareTo(d1), 1);
+ }
+
+ @Test(groups = "fast")
+ public void testCompare3() throws Exception {
+ final DateTime now = clock.getUTCNow();
+ final DisabledDuration d1 = new DisabledDuration(now, now.plusDays(1));
+ final DisabledDuration d2 = new DisabledDuration(now, now.plusDays(2));
+ assertEquals(d1.compareTo(d2), -1);
+ assertEquals(d2.compareTo(d1), 1);
+ }
+
+ @Test(groups = "fast")
+ public void testCompare4() throws Exception {
+ final DateTime now = clock.getUTCNow();
+ final DisabledDuration d1 = new DisabledDuration(now, now.plusDays(1));
+ final DisabledDuration d2 = new DisabledDuration(now, null);
+ assertEquals(d1.compareTo(d2), -1);
+ assertEquals(d2.compareTo(d1), 1);
+ }
+
+ @Test(groups = "fast")
+ public void testCompare5() throws Exception {
+ final DateTime now = clock.getUTCNow();
+ final DisabledDuration d1 = new DisabledDuration(now, null);
+ final DisabledDuration d2 = new DisabledDuration(now, now.plusDays(1));
+ assertEquals(d1.compareTo(d2), 1);
+ assertEquals(d2.compareTo(d1), -1);
+ }
+
+
+
+ // Case 1: this contained into o => false
+ // |---------| this
+ // |--------------| o
+ @Test(groups = "fast")
+ public void testDisjoint1() throws Exception {
+ final DateTime now = clock.getUTCNow();
+ final DisabledDuration d1 = new DisabledDuration(now, now.plusDays(1));
+ final DisabledDuration d2 = new DisabledDuration(now, now.plusDays(2));
+ assertFalse(d1.isDisjoint(d2));
+ }
+
+ // Case 2: this overlaps with o => false
+ // |---------| this
+ // |--------------| o
+ @Test(groups = "fast")
+ public void testDisjoint2() throws Exception {
+ final DateTime now = clock.getUTCNow();
+ final DisabledDuration d1 = new DisabledDuration(now, now.plusDays(10));
+ final DisabledDuration d2 = new DisabledDuration(now.plusDays(1), now.plusDays(12));
+ assertFalse(d1.isDisjoint(d2));
+ }
+
+ // Case 3: o contains into this => false
+ // |---------| this
+ // |---| o
+ @Test(groups = "fast")
+ public void testDisjoint3() throws Exception {
+ final DateTime now = clock.getUTCNow();
+ final DisabledDuration d1 = new DisabledDuration(now, now.plusDays(10));
+ final DisabledDuration d2 = new DisabledDuration(now.plusDays(1), now.plusDays(4));
+ assertFalse(d1.isDisjoint(d2));
+ }
+
+ // Case 4: this and o are adjacent => false
+ // |---------| this
+ // |---| o
+ @Test(groups = "fast")
+ public void testDisjoint4() throws Exception {
+ final DateTime now = clock.getUTCNow();
+ final DisabledDuration d1 = new DisabledDuration(now, now.plusDays(10));
+ final DisabledDuration d2 = new DisabledDuration(now.plusDays(10), now.plusDays(15));
+ assertFalse(d1.isDisjoint(d2));
+ }
+
+ // Case 5: this and o are disjoint => true
+ // |---------| this
+ // |---| o
+ @Test(groups = "fast")
+ public void testDisjoint5() throws Exception {
+ final DateTime now = clock.getUTCNow();
+ final DisabledDuration d1 = new DisabledDuration(now, now.plusDays(10));
+ final DisabledDuration d2 = new DisabledDuration(now.plusDays(11), now.plusDays(15));
+ assertTrue(d1.isDisjoint(d2));
+ }
+
+
+ @Test(groups = "fast")
+ public void testMergeDuration1() throws Exception {
+ final DateTime now = clock.getUTCNow();
+ final DisabledDuration d1 = new DisabledDuration(now, now.plusDays(10));
+ final DisabledDuration d2 = new DisabledDuration(now.plusDays(1), now.plusDays(15));
+
+ final DisabledDuration result = DisabledDuration.mergeDuration(d1, d2);
+ assertEquals(result.getStart().compareTo(now), 0);
+ assertEquals(result.getEnd().compareTo(now.plusDays(15)), 0);
+ }
+
+ @Test(groups = "fast")
+ public void testMergeDuration2() throws Exception {
+ final DateTime now = clock.getUTCNow();
+ final DisabledDuration d1 = new DisabledDuration(now, now.plusDays(15));
+ final DisabledDuration d2 = new DisabledDuration(now.plusDays(1), now.plusDays(10));
+
+ final DisabledDuration result = DisabledDuration.mergeDuration(d1, d2);
+ assertEquals(result.getStart().compareTo(now), 0);
+ assertEquals(result.getEnd().compareTo(now.plusDays(15)), 0);
+ }
+
+ @Test(groups = "fast")
+ public void testMergeDuration3() throws Exception {
+ final DateTime now = clock.getUTCNow();
+ final DisabledDuration d1 = new DisabledDuration(now, null);
+ final DisabledDuration d2 = new DisabledDuration(now.plusDays(1), now.plusDays(10));
+
+ final DisabledDuration result = DisabledDuration.mergeDuration(d1, d2);
+ assertEquals(result.getStart().compareTo(now), 0);
+ assertNull(result.getEnd());
+ }
+
+ @Test(groups = "fast")
+ public void testMergeDuration4() throws Exception {
+ final DateTime now = clock.getUTCNow();
+ final DisabledDuration d1 = new DisabledDuration(now, now.plusDays(10));
+ final DisabledDuration d2 = new DisabledDuration(now.plusDays(1), null);
+
+ final DisabledDuration result = DisabledDuration.mergeDuration(d1, d2);
+ assertEquals(result.getStart().compareTo(now), 0);
+ assertNull(result.getEnd());
+ }
+
+ @Test(groups = "fast", expectedExceptions = IllegalStateException.class)
+ public void testMergeDurationInvalid1() throws Exception {
+ final DateTime now = clock.getUTCNow();
+ final DisabledDuration d1 = new DisabledDuration(now, now.plusDays(10));
+ final DisabledDuration d2 = new DisabledDuration(now.plusDays(11), null);
+
+ DisabledDuration.mergeDuration(d1, d2);
+ }
+
+ @Test(groups = "fast", expectedExceptions = IllegalStateException.class)
+ public void testMergeDurationInvalid2() throws Exception {
+ final DateTime now = clock.getUTCNow();
+ final DisabledDuration d1 = new DisabledDuration(now.plusDays(1), now.plusDays(10));
+ final DisabledDuration d2 = new DisabledDuration(now, null);
+
+ DisabledDuration.mergeDuration(d1, d2);
+ }
+
+}
\ No newline at end of file