Skip to content

Commit f27c784

Browse files
committed
feat: ensure tier range is created only with named constructor
1 parent 28f6047 commit f27c784

File tree

4 files changed

+41
-69
lines changed

4 files changed

+41
-69
lines changed

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

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,51 @@ public final class SubscriptionTierRange {
88
private final int numberOfSubscriptionsFrom;
99
private final int numberOfSubscriptionsTo;
1010

11-
public SubscriptionTierRange(int numberOfSubscriptionsFrom, int numberOfSubscriptionsTo) {
11+
private SubscriptionTierRange(int numberOfSubscriptionsFrom, int numberOfSubscriptionsTo) {
1212
this.numberOfSubscriptionsFrom = numberOfSubscriptionsFrom;
1313
this.numberOfSubscriptionsTo = numberOfSubscriptionsTo;
1414
}
1515

1616
public static SubscriptionTierRange first(int numberOfSubscriptions) {
17-
if (numberOfSubscriptions < 1) {
18-
throw new InvalidSubscriptionTierRange(
19-
"Number of subscriptions must be greater than 0");
20-
}
17+
validate(numberOfSubscriptions);
2118
return new SubscriptionTierRange(1, numberOfSubscriptions);
2219
}
2320

21+
public static SubscriptionTierRange last(final SubscriptionTierRange range) {
22+
validate(range);
23+
return new SubscriptionTierRange(range.numberOfSubscriptionsTo + 1, Integer.MAX_VALUE);
24+
}
25+
2426
public static SubscriptionTierRange from(
2527
final SubscriptionTierRange range,
2628
final int numberOfSubscriptions) {
2729

30+
validate(range);
31+
validate(numberOfSubscriptions);
32+
2833
final int numberOfSubscriptionsFrom = range.numberOfSubscriptionsTo + 1;
2934
final int numberOfSubscriptionsTo = numberOfSubscriptionsFrom + numberOfSubscriptions;
3035
return new SubscriptionTierRange(numberOfSubscriptionsFrom, numberOfSubscriptionsTo);
3136
}
3237

33-
public static SubscriptionTierRange last(int numberOfSubscriptionsFrom) {
34-
return new SubscriptionTierRange(numberOfSubscriptionsFrom, Integer.MAX_VALUE);
38+
39+
private static void validate(final int numberOfSubscriptions) {
40+
if (numberOfSubscriptions < 1) {
41+
throw new InvalidSubscriptionTierRange(
42+
"Number of subscriptions must be greater than 0");
43+
}
3544
}
3645

37-
public static SubscriptionTierRange last(final SubscriptionTierRange range) {
38-
return new SubscriptionTierRange(range.numberOfSubscriptionsTo + 1, Integer.MAX_VALUE);
46+
private static void validate(final SubscriptionTierRange range) {
47+
if (range == null) {
48+
throw new InvalidSubscriptionTierRange(
49+
"Cannot create a new subscription tier range from a null one");
50+
}
51+
52+
if (range.isLast()) {
53+
throw new InvalidSubscriptionTierRange(
54+
"Cannot create a new subscription tier range after the last one");
55+
}
3956
}
4057

4158
public boolean isFirst() {

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

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package tv.codely.checkout;
22

3-
import java.util.HashSet;
43
import java.util.List;
54

65
public final class SubscriptionTiers {
@@ -24,20 +23,6 @@ private static void validate(final List<SubscriptionTier> tiers) {
2423
if (tiers.stream().noneMatch(SubscriptionTier::isLast)) {
2524
throw new InvalidSubscriptionTiers("There must be a last subscription tier");
2625
}
27-
28-
if (tiers.size() == 1) {
29-
return;
30-
}
31-
32-
final var validTiers = new HashSet<SubscriptionTier>();
33-
for (final SubscriptionTier tier : tiers) {
34-
if (tiers.stream()
35-
.anyMatch(
36-
t -> !validTiers.contains(t) && !t.equals(tier) && !t.isAfter(tier))) {
37-
throw new InvalidSubscriptionTiers("All tiers must be after the previous one");
38-
}
39-
validTiers.add(tier);
40-
}
4126
}
4227

4328
private SubscriptionTier findSuitableTier(int subscriptions) {

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

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -118,33 +118,11 @@ void throw_invalid_subscription_tiers_if_there_is_no_tiers() {
118118
assertThrows(InvalidSubscriptionTiers.class, () -> new TieredPricing(List.of()));
119119
}
120120

121-
@Test
122-
void throw_invalid_subscription_tiers_if_first_tier_range_does_not_start_at_1() {
123-
final var subscriptionTiers =
124-
List.of(SubscriptionTierMother.create(SubscriptionTierRangeMother.create(2, 10),
125-
SubscriptionTierPriceMother.random()));
126-
127-
assertThrows(InvalidSubscriptionTiers.class, () -> new TieredPricing(subscriptionTiers));
128-
}
129-
130121
@Test
131122
void throw_invalid_subscription_tiers_if_there_is_no_last_tier() {
132-
final var subscriptionTiers =
133-
List.of(SubscriptionTierMother.create(SubscriptionTierRangeMother.create(1, 10),
134-
SubscriptionTierPriceMother.random()));
135-
136-
assertThrows(InvalidSubscriptionTiers.class, () -> new TieredPricing(subscriptionTiers));
137-
}
138-
139-
@Test
140-
void throw_invalid_subscription_tiers_if_tiers_are_not_in_order() {
141123
final var subscriptionTiers =
142124
List.of(SubscriptionTierMother.create(SubscriptionTierRangeMother.first(10),
143-
SubscriptionTierPriceMother.random()),
144-
SubscriptionTierMother.create(SubscriptionTierRangeMother.create(9, 20),
145-
SubscriptionTierPriceMother.random()),
146-
SubscriptionTierMother.create(SubscriptionTierRangeMother.last(2),
147-
SubscriptionTierPriceMother.random()));
125+
SubscriptionTierPriceMother.random()));
148126

149127
assertThrows(InvalidSubscriptionTiers.class, () -> new TieredPricing(subscriptionTiers));
150128
}

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

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,39 @@
66

77
public final class SubscriptionTierRangeMother {
88

9-
public static SubscriptionTierRange create(
10-
final int numberOfSubscriptionsFrom,
11-
final int numberOfSubscriptionsTo) {
12-
13-
return new SubscriptionTierRange(numberOfSubscriptionsFrom, numberOfSubscriptionsTo);
14-
}
15-
169
public static SubscriptionTierRange first(final int numberOfSubscriptions) {
1710
return SubscriptionTierRange.first(numberOfSubscriptions);
1811
}
1912

20-
public static SubscriptionTierRange last(final int numberOfSubscriptionsFrom) {
21-
return SubscriptionTierRange.last(numberOfSubscriptionsFrom);
13+
public static SubscriptionTierRange last(final SubscriptionTierRange range) {
14+
return SubscriptionTierRange.last(range);
2215
}
2316

2417
public static List<SubscriptionTierRange> randoms() {
25-
final var subscriptionTiers = new ArrayList<SubscriptionTierRange>();
18+
final var tierRanges = new ArrayList<SubscriptionTierRange>();
2619
final var numberOfTiers = IntegerMother.randomBetween(1, 6);
2720
final var minSubscriptionsInTier = 3;
2821
final var maxSubscriptionsInTier =
2922
IntegerMother.randomBetween(minSubscriptionsInTier + 1, 20);
30-
31-
var lastNumberOfSubscriptionsTo = 0;
23+
var currentTierRange = first(
24+
IntegerMother.randomBetween(minSubscriptionsInTier, maxSubscriptionsInTier));
25+
tierRanges.add(currentTierRange);
3226

3327
for (int i = 0; i < numberOfTiers; i++) {
3428
if (i == numberOfTiers - 1) {
35-
subscriptionTiers.add(last(lastNumberOfSubscriptionsTo + 1));
29+
tierRanges.add(last(currentTierRange));
3630
break;
3731
}
3832

39-
final var numberOfSubscriptionsFrom = lastNumberOfSubscriptionsTo + 1;
40-
final var numberOfSubscriptionsTo =
41-
IntegerMother.randomBetween(
42-
numberOfSubscriptionsFrom + 1,
43-
maxSubscriptionsInTier * (i + 1));
44-
45-
lastNumberOfSubscriptionsTo = numberOfSubscriptionsTo;
33+
final var numberOfSubscriptions =
34+
IntegerMother.randomBetween(minSubscriptionsInTier, maxSubscriptionsInTier);
35+
final var tierRange = SubscriptionTierRange.from(currentTierRange,
36+
numberOfSubscriptions);
4637

47-
subscriptionTiers.add(create(numberOfSubscriptionsFrom, numberOfSubscriptionsTo));
38+
currentTierRange = tierRange;
39+
tierRanges.add(tierRange);
4840
}
4941

50-
return subscriptionTiers;
42+
return tierRanges;
5143
}
5244
}

0 commit comments

Comments
 (0)