Coupon.java

1
package com.rbctcsworld.ecommerce.coupon;
2
3
import jakarta.persistence.Column;
4
import jakarta.persistence.Entity;
5
import jakarta.persistence.GeneratedValue;
6
import jakarta.persistence.GenerationType;
7
import jakarta.persistence.Id;
8
import jakarta.persistence.Table;
9
10
import java.math.BigDecimal;
11
import java.math.RoundingMode;
12
import java.time.LocalDateTime;
13
14
@Entity
15
@Table(name = "coupons")
16
public class Coupon {
17
18
    public static final String PERCENT = "PERCENT";
19
    public static final String FIXED = "FIXED";
20
21
    @Id
22
    @GeneratedValue(strategy = GenerationType.IDENTITY)
23
    private Long id;
24
25
    @Column(nullable = false, unique = true, length = 40)
26
    private String code;
27
28
    @Column(nullable = false, length = 10)
29
    private String type;
30
31
    @Column(name = "discount_value", nullable = false, precision = 12, scale = 2)
32
    private BigDecimal discountValue;
33
34
    @Column(name = "min_order_amount", nullable = false, precision = 12, scale = 2)
35
    private BigDecimal minOrderAmount = BigDecimal.ZERO;
36
37
    @Column(name = "max_uses")
38
    private Integer maxUses;
39
40
    @Column(name = "used_count", nullable = false)
41
    private int usedCount;
42
43
    @Column(name = "valid_from")
44
    private LocalDateTime validFrom;
45
46
    @Column(name = "valid_until")
47
    private LocalDateTime validUntil;
48
49
    @Column(nullable = false)
50
    private boolean active = true;
51
52
    protected Coupon() {
53
    }
54
55
    public Coupon(String code, String type, BigDecimal discountValue, BigDecimal minOrderAmount, Integer maxUses,
56
                  LocalDateTime validFrom, LocalDateTime validUntil) {
57
        this.code = code;
58
        this.type = type;
59
        this.discountValue = discountValue;
60 1 1. <init> : removed conditional - replaced equality check with false → KILLED
        this.minOrderAmount = minOrderAmount == null ? BigDecimal.ZERO : minOrderAmount;
61
        this.maxUses = maxUses;
62
        this.validFrom = validFrom;
63
        this.validUntil = validUntil;
64
    }
65
66
    /** Discount amount for a given subtotal (PERCENT of subtotal, or FIXED amount), never above the subtotal. */
67
    public BigDecimal discountFor(BigDecimal subtotal) {
68 1 1. discountFor : removed conditional - replaced equality check with false → KILLED
        BigDecimal d = PERCENT.equals(type)
69
                ? subtotal.multiply(discountValue).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP)
70
                : discountValue;
71 1 1. discountFor : replaced return value with null for com/rbctcsworld/ecommerce/coupon/Coupon::discountFor → KILLED
        return d.min(subtotal).setScale(2, RoundingMode.HALF_UP);
72
    }
73
74
    public boolean usageLimitReached() {
75 4 1. usageLimitReached : removed conditional - replaced comparison check with false → KILLED
2. usageLimitReached : changed conditional boundary → KILLED
3. usageLimitReached : replaced boolean return with true for com/rbctcsworld/ecommerce/coupon/Coupon::usageLimitReached → KILLED
4. usageLimitReached : removed conditional - replaced equality check with false → KILLED
        return maxUses != null && usedCount >= maxUses;
76
    }
77
78 1 1. getId : replaced Long return value with 0L for com/rbctcsworld/ecommerce/coupon/Coupon::getId → KILLED
    public Long getId() { return id; }
79 1 1. getCode : replaced return value with "" for com/rbctcsworld/ecommerce/coupon/Coupon::getCode → KILLED
    public String getCode() { return code; }
80 1 1. getType : replaced return value with "" for com/rbctcsworld/ecommerce/coupon/Coupon::getType → KILLED
    public String getType() { return type; }
81 1 1. getDiscountValue : replaced return value with null for com/rbctcsworld/ecommerce/coupon/Coupon::getDiscountValue → KILLED
    public BigDecimal getDiscountValue() { return discountValue; }
82 1 1. getMinOrderAmount : replaced return value with null for com/rbctcsworld/ecommerce/coupon/Coupon::getMinOrderAmount → KILLED
    public BigDecimal getMinOrderAmount() { return minOrderAmount; }
83 1 1. getMaxUses : replaced Integer return value with 0 for com/rbctcsworld/ecommerce/coupon/Coupon::getMaxUses → KILLED
    public Integer getMaxUses() { return maxUses; }
84 1 1. getUsedCount : replaced int return with 0 for com/rbctcsworld/ecommerce/coupon/Coupon::getUsedCount → KILLED
    public int getUsedCount() { return usedCount; }
85 1 1. getValidFrom : replaced return value with null for com/rbctcsworld/ecommerce/coupon/Coupon::getValidFrom → KILLED
    public LocalDateTime getValidFrom() { return validFrom; }
86 1 1. getValidUntil : replaced return value with null for com/rbctcsworld/ecommerce/coupon/Coupon::getValidUntil → KILLED
    public LocalDateTime getValidUntil() { return validUntil; }
87 2 1. isActive : replaced boolean return with false for com/rbctcsworld/ecommerce/coupon/Coupon::isActive → KILLED
2. isActive : replaced boolean return with true for com/rbctcsworld/ecommerce/coupon/Coupon::isActive → KILLED
    public boolean isActive() { return active; }
88
89
    public void setActive(boolean active) { this.active = active; }
90
91
    /** Changes the terms; the code and the usage count stay. */
92
    public void update(String type, BigDecimal discountValue, BigDecimal minOrderAmount, Integer maxUses,
93
                       LocalDateTime validFrom, LocalDateTime validUntil) {
94
        this.type = type;
95
        this.discountValue = discountValue;
96 1 1. update : removed conditional - replaced equality check with false → KILLED
        this.minOrderAmount = minOrderAmount == null ? BigDecimal.ZERO : minOrderAmount;
97
        this.maxUses = maxUses;
98
        this.validFrom = validFrom;
99
        this.validUntil = validUntil;
100
    }
101
}

Mutations

60

1.1
Location : <init>
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:couponWithoutMinimumAmountAcceptsAnyOrder()]
removed conditional - replaced equality check with false → KILLED

68

1.1
Location : discountFor
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:discountMaths()]
removed conditional - replaced equality check with false → KILLED

71

1.1
Location : discountFor
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:discountMaths()]
replaced return value with null for com/rbctcsworld/ecommerce/coupon/Coupon::discountFor → KILLED

75

1.1
Location : usageLimitReached
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:theStateIsWhatACustomerWouldExperienceNow()]
removed conditional - replaced comparison check with false → KILLED

2.2
Location : usageLimitReached
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:theStateIsWhatACustomerWouldExperienceNow()]
changed conditional boundary → KILLED

3.3
Location : usageLimitReached
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:codeIsCaseInsensitiveAndTrimmed()]
replaced boolean return with true for com/rbctcsworld/ecommerce/coupon/Coupon::usageLimitReached → KILLED

4.4
Location : usageLimitReached
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:theStateIsWhatACustomerWouldExperienceNow()]
removed conditional - replaced equality check with false → KILLED

78

1.1
Location : getId
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:redeemFailsWhenAtomicCounterSaysLimitReached()]
replaced Long return value with 0L for com/rbctcsworld/ecommerce/coupon/Coupon::getId → KILLED

79

1.1
Location : getCode
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:redeemFailsWhenAtomicCounterSaysLimitReached()]
replaced return value with "" for com/rbctcsworld/ecommerce/coupon/Coupon::getCode → KILLED

80

1.1
Location : getType
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:createStoresANormalisedCouponAndAllowsExactly100Percent()]
replaced return value with "" for com/rbctcsworld/ecommerce/coupon/Coupon::getType → KILLED

81

1.1
Location : getDiscountValue
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:createStoresANormalisedCouponAndAllowsExactly100Percent()]
replaced return value with null for com/rbctcsworld/ecommerce/coupon/Coupon::getDiscountValue → KILLED

82

1.1
Location : getMinOrderAmount
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:codeIsCaseInsensitiveAndTrimmed()]
replaced return value with null for com/rbctcsworld/ecommerce/coupon/Coupon::getMinOrderAmount → KILLED

83

1.1
Location : getMaxUses
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:createStoresANormalisedCouponAndAllowsExactly100Percent()]
replaced Integer return value with 0 for com/rbctcsworld/ecommerce/coupon/Coupon::getMaxUses → KILLED

84

1.1
Location : getUsedCount
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:usageLimitIsReachedExactlyAtMaxUses()]
replaced int return with 0 for com/rbctcsworld/ecommerce/coupon/Coupon::getUsedCount → KILLED

85

1.1
Location : getValidFrom
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:theStateIsWhatACustomerWouldExperienceNow()]
replaced return value with null for com/rbctcsworld/ecommerce/coupon/Coupon::getValidFrom → KILLED

86

1.1
Location : getValidUntil
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:theStateIsWhatACustomerWouldExperienceNow()]
replaced return value with null for com/rbctcsworld/ecommerce/coupon/Coupon::getValidUntil → KILLED

87

1.1
Location : isActive
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:theStateIsWhatACustomerWouldExperienceNow()]
replaced boolean return with false for com/rbctcsworld/ecommerce/coupon/Coupon::isActive → KILLED

2.2
Location : isActive
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:unknownOrInactiveCodeIsInvalid()]
replaced boolean return with true for com/rbctcsworld/ecommerce/coupon/Coupon::isActive → KILLED

96

1.1
Location : update
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:anEditFollowsTheSameRulesAsCreate()]
removed conditional - replaced equality check with false → KILLED

Active mutators

Tests examined


Report generated by PIT 1.30.0 support