Skip to content

Commit 5ae5708

Browse files
committed
feat: throw PriceNotFound when number of subscriptions is invalid
1 parent f27c784 commit 5ae5708

File tree

7 files changed

+51
-48
lines changed

7 files changed

+51
-48
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package tv.codely.checkout;
2+
3+
public final class PriceNotFound extends RuntimeException {
4+
5+
public PriceNotFound(int subscriptions) {
6+
super(String.format("Price not found for %d subscriptions", subscriptions));
7+
}
8+
}

exercises/tiered_pricing/solutions/adrianliz/java/src/main/java/tv/codely/checkout/SubscriptionTier.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@ public boolean isLast() {
2323
return range.isLast();
2424
}
2525

26-
public boolean isAfter(final SubscriptionTier other) {
27-
return range.isAfter(other.range);
28-
}
29-
3026
public boolean isInRange(int numberOfSubscriptions) {
3127
return this.range.isSuitableFor(numberOfSubscriptions);
3228
}

exercises/tiered_pricing/solutions/adrianliz/java/src/main/java/tv/codely/checkout/SubscriptionTierRange.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,6 @@ public boolean isLast() {
6363
return numberOfSubscriptionsTo == Integer.MAX_VALUE;
6464
}
6565

66-
public boolean isAfter(final SubscriptionTierRange other) {
67-
return numberOfSubscriptionsFrom > other.numberOfSubscriptionsTo;
68-
}
69-
7066
public boolean isSuitableFor(int numberOfSubscriptions) {
7167
return numberOfSubscriptions >= numberOfSubscriptionsFrom
7268
&& numberOfSubscriptions <= numberOfSubscriptionsTo;
Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
package tv.codely.checkout;
22

3-
import java.util.List;
3+
import java.util.Set;
44

55
public final class SubscriptionTiers {
66

7-
private final List<SubscriptionTier> tiers;
7+
private final Set<SubscriptionTier> tiers;
88

9-
public SubscriptionTiers(List<SubscriptionTier> tiers) {
9+
public SubscriptionTiers(final Set<SubscriptionTier> tiers) {
1010
validate(tiers);
1111
this.tiers = tiers;
1212
}
1313

14-
private static void validate(final List<SubscriptionTier> tiers) {
14+
private static void validate(final Set<SubscriptionTier> tiers) {
1515
if (tiers == null || tiers.isEmpty()) {
1616
throw new InvalidSubscriptionTiers("There must be at least one subscription tier");
1717
}
@@ -25,19 +25,18 @@ private static void validate(final List<SubscriptionTier> tiers) {
2525
}
2626
}
2727

28-
private SubscriptionTier findSuitableTier(int subscriptions) {
28+
private SubscriptionTier findSuitableTier(int numberOfSubscriptions) {
2929
return tiers.stream()
30-
.filter(tier -> tier.isInRange(subscriptions))
30+
.filter(tier -> tier.isInRange(numberOfSubscriptions))
3131
.findFirst()
32-
.orElseThrow(() -> new InvalidSubscriptionTiers(
33-
"There is no subscription tier for " + subscriptions + " subscriptions"));
32+
.orElseThrow(() -> new PriceNotFound(numberOfSubscriptions));
3433
}
3534

36-
public double getTotalPrice(int subscriptions) {
37-
return findSuitableTier(subscriptions).getTotalPrice(subscriptions);
35+
public double getTotalPrice(int numberOfSubscriptions) {
36+
return findSuitableTier(numberOfSubscriptions).getTotalPrice(numberOfSubscriptions);
3837
}
3938

40-
public double getBasePrice(int subscriptions) {
41-
return findSuitableTier(subscriptions).unitPrice();
39+
public double getBasePrice(int numberOfSubscriptions) {
40+
return findSuitableTier(numberOfSubscriptions).unitPrice();
4241
}
4342
}
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
package tv.codely.checkout;
22

3-
import java.util.List;
3+
import java.util.Set;
44

55
public class TieredPricing {
6-
6+
77
private final SubscriptionTiers tiers;
88

99
public TieredPricing(final SubscriptionTiers subscriptionTiers) {
1010
this.tiers = subscriptionTiers;
1111
}
1212

13-
public TieredPricing(final List<SubscriptionTier> subscriptionTiers) {
13+
public TieredPricing(final Set<SubscriptionTier> subscriptionTiers) {
1414
this(new SubscriptionTiers(subscriptionTiers));
1515
}
1616

17-
public double getTotalPrice(int subscriptions) {
18-
return tiers.getTotalPrice(subscriptions);
17+
public double getTotalPrice(int numberOfSubscriptions) {
18+
return tiers.getTotalPrice(numberOfSubscriptions);
1919
}
2020

21-
public double getBasePrice(int subscriptions) {
22-
return tiers.getBasePrice(subscriptions);
21+
public double getBasePrice(int numberOfSubscriptions) {
22+
return tiers.getBasePrice(numberOfSubscriptions);
2323
}
2424
}

exercises/tiered_pricing/solutions/adrianliz/java/src/test/java/tv/codely/checkout/TieredPricingShould.java

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
package tv.codely.checkout;
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
4-
import static org.junit.jupiter.api.Assertions.assertNotNull;
54
import static org.junit.jupiter.api.Assertions.assertThrows;
65
import static org.junit.jupiter.api.Assertions.assertTrue;
76

8-
import java.util.List;
7+
import java.util.Set;
98
import org.junit.jupiter.api.Test;
109
import tv.codely.checkout.mother.IntegerMother;
1110
import tv.codely.checkout.mother.SubscriptionTierMother;
@@ -14,13 +13,13 @@
1413

1514
public class TieredPricingShould {
1615

17-
private static List<SubscriptionTier> defaultSubscriptionTiers() {
16+
private static Set<SubscriptionTier> defaultSubscriptionTiers() {
1817
final var firstTierRange = SubscriptionTierRange.first(2);
1918
final var secondTierRange = SubscriptionTierRange.from(firstTierRange, 7);
2019
final var thirdTierRange = SubscriptionTierRange.from(secondTierRange, 14);
2120
final var fourthTierRange = SubscriptionTierRange.from(thirdTierRange, 24);
2221
final var lastTierRange = SubscriptionTierRange.last(fourthTierRange);
23-
return List.of(
22+
return Set.of(
2423
new SubscriptionTier(
2524
firstTierRange,
2625
new SubscriptionTierPrice(299)),
@@ -56,18 +55,6 @@ void return_total_price_based_on_number_of_subscriptions() {
5655
assertEquals(expectedPrice, totalPrice);
5756
}
5857

59-
@Test
60-
void should_have_a_subscription_tier_range_with_no_upper_limit() {
61-
final var subscriptionTiers = SubscriptionTierMother.randoms();
62-
final var lastSubscriptionTier =
63-
subscriptionTiers.stream()
64-
.filter(SubscriptionTier::isLast)
65-
.findFirst()
66-
.orElse(null);
67-
68-
assertNotNull(lastSubscriptionTier);
69-
}
70-
7158
@Test
7259
void return_total_price_for_1_subscription() {
7360
final var tieredPricing = new TieredPricing(defaultSubscriptionTiers());
@@ -115,15 +102,31 @@ void return_total_price_for_51_subscriptions() {
115102

116103
@Test
117104
void throw_invalid_subscription_tiers_if_there_is_no_tiers() {
118-
assertThrows(InvalidSubscriptionTiers.class, () -> new TieredPricing(List.of()));
105+
assertThrows(InvalidSubscriptionTiers.class, () -> new TieredPricing(Set.of()));
119106
}
120107

121108
@Test
122109
void throw_invalid_subscription_tiers_if_there_is_no_last_tier() {
123110
final var subscriptionTiers =
124-
List.of(SubscriptionTierMother.create(SubscriptionTierRangeMother.first(10),
111+
Set.of(SubscriptionTierMother.create(SubscriptionTierRangeMother.first(10),
125112
SubscriptionTierPriceMother.random()));
126113

127114
assertThrows(InvalidSubscriptionTiers.class, () -> new TieredPricing(subscriptionTiers));
128115
}
116+
117+
@Test
118+
void throw_invalid_subscription_tier_range_if_number_of_susbcriptions_is_less_than_1() {
119+
assertThrows(InvalidSubscriptionTierRange.class, () -> SubscriptionTierRange.first(0));
120+
}
121+
122+
@Test
123+
void throw_invalid_subscription_tier_range_if_previous_range_does_not_exist() {
124+
assertThrows(InvalidSubscriptionTierRange.class, () -> SubscriptionTierRange.last(null));
125+
}
126+
127+
@Test
128+
void throw_price_not_found_if_number_of_subscriptions_is_not_valid() {
129+
final var tieredPricing = new TieredPricing(defaultSubscriptionTiers());
130+
assertThrows(PriceNotFound.class, () -> tieredPricing.getTotalPrice(0));
131+
}
129132
}

exercises/tiered_pricing/solutions/adrianliz/java/src/test/java/tv/codely/checkout/mother/SubscriptionTierMother.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package tv.codely.checkout.mother;
22

3-
import java.util.List;
3+
import java.util.Set;
44
import java.util.concurrent.atomic.AtomicReference;
5+
import java.util.stream.Collectors;
56
import tv.codely.checkout.SubscriptionTier;
67
import tv.codely.checkout.SubscriptionTierPrice;
78
import tv.codely.checkout.SubscriptionTierRange;
@@ -15,7 +16,7 @@ public static SubscriptionTier create(
1516
return new SubscriptionTier(range, price);
1617
}
1718

18-
public static List<SubscriptionTier> randoms() {
19+
public static Set<SubscriptionTier> randoms() {
1920
final var subscriptionTierRanges = SubscriptionTierRangeMother.randoms();
2021
final var previousSubscriptionTierPrice = new AtomicReference<>(299D);
2122

@@ -28,6 +29,6 @@ public static List<SubscriptionTier> randoms() {
2829
previousSubscriptionTierPrice.set(subscriptionTierPrice);
2930
return create(range, SubscriptionTierPriceMother.create(subscriptionTierPrice));
3031
})
31-
.toList();
32+
.collect(Collectors.toSet());
3233
}
3334
}

0 commit comments

Comments
 (0)