CouponService.java

1
package com.rbctcsworld.ecommerce.coupon;
2
3
import com.rbctcsworld.ecommerce.audit.AuditChange;
4
import com.rbctcsworld.ecommerce.audit.AuditEvent;
5
import com.rbctcsworld.ecommerce.common.exception.NotFoundException;
6
import org.springframework.context.ApplicationEventPublisher;
7
import java.util.Locale;
8
import java.util.Map;
9
10
import com.rbctcsworld.ecommerce.common.exception.BusinessRuleException;
11
import com.rbctcsworld.ecommerce.common.exception.ConflictException;
12
import org.springframework.stereotype.Service;
13
import org.springframework.transaction.annotation.Transactional;
14
15
import java.math.BigDecimal;
16
import java.time.Clock;
17
import java.time.LocalDateTime;
18
import java.util.List;
19
20
/**
21
 * Coupon rules, checked in this order:
22
 *  1. code exists and is active                 -> else 400 "Invalid coupon code"
23
 *  2. now is inside valid_from .. valid_until    -> else 400 "Coupon has expired" / "Coupon is not active yet"
24
 *  3. subtotal >= min_order_amount              -> else 400 "Minimum order amount ..."
25
 *  4. this customer has not used it before       -> else 409 "Coupon already used"
26
 *  5. global usage limit not reached (atomic)   -> else 409 "Coupon usage limit reached"
27
 */
28
@Service
29
@Transactional
30
public class CouponService {
31
32
    private final CouponRepository coupons;
33
    private final CouponRedemptionRepository redemptions;
34
    private final Clock clock;
35
    private final ApplicationEventPublisher events;
36
37
    public CouponService(CouponRepository coupons, CouponRedemptionRepository redemptions, Clock clock,
38
                         ApplicationEventPublisher events) {
39
        this.coupons = coupons;
40
        this.redemptions = redemptions;
41
        this.clock = clock;
42
        this.events = events;
43
    }
44
45
    /** Validates rules 1-4 (and a non-atomic look at rule 5) and returns the coupon. Used by quote and order. */
46
    @Transactional(readOnly = true)
47
    public Coupon validate(String rawCode, Long userId, BigDecimal subtotal) {
48
        String code = normalize(rawCode);
49
        Coupon c = coupons.findByCode(code)
50
                .filter(Coupon::isActive)
51 1 1. lambda$validate$0 : replaced return value with null for com/rbctcsworld/ecommerce/coupon/CouponService::lambda$validate$0 → KILLED
                .orElseThrow(() -> new BusinessRuleException("Invalid coupon code: " + code));
52
53
        LocalDateTime now = LocalDateTime.now(clock);
54 2 1. validate : removed conditional - replaced equality check with false → KILLED
2. validate : removed conditional - replaced equality check with false → KILLED
        if (c.getValidFrom() != null && now.isBefore(c.getValidFrom())) {
55
            throw new BusinessRuleException("Coupon is not active yet: " + code);
56
        }
57 2 1. validate : removed conditional - replaced equality check with false → KILLED
2. validate : removed conditional - replaced equality check with false → KILLED
        if (c.getValidUntil() != null && now.isAfter(c.getValidUntil())) {
58
            throw new BusinessRuleException("Coupon has expired: " + code);
59
        }
60 2 1. validate : changed conditional boundary → KILLED
2. validate : removed conditional - replaced comparison check with false → KILLED
        if (subtotal.compareTo(c.getMinOrderAmount()) < 0) {
61
            throw new BusinessRuleException("Minimum order amount for " + code + " is " + c.getMinOrderAmount());
62
        }
63 1 1. validate : removed conditional - replaced equality check with false → KILLED
        if (redemptions.existsByCouponIdAndUserId(c.getId(), userId)) {
64
            throw new ConflictException("Coupon already used: " + code);
65
        }
66 1 1. validate : removed conditional - replaced equality check with false → KILLED
        if (c.usageLimitReached()) {
67
            throw new ConflictException("Coupon usage limit reached: " + code);
68
        }
69 1 1. validate : replaced return value with null for com/rbctcsworld/ecommerce/coupon/CouponService::validate → KILLED
        return c;
70
    }
71
72
    /** Records the redemption inside the order transaction; the atomic counter protects the global limit. */
73
    public void redeem(Coupon coupon, Long userId, Long orderId) {
74 1 1. redeem : removed conditional - replaced equality check with false → KILLED
        if (coupons.incrementUsage(coupon.getId()) == 0) {
75
            throw new ConflictException("Coupon usage limit reached: " + coupon.getCode());
76
        }
77
        redemptions.save(new CouponRedemption(coupon.getId(), userId, orderId));
78
    }
79
80
    public Coupon create(CouponDtos.CreateCouponRequest r) {
81
        String code = normalize(r.code());
82 1 1. create : removed conditional - replaced equality check with false → KILLED
        if (coupons.existsByCode(code)) {
83
            throw new ConflictException("Coupon code already exists: " + code);
84
        }
85 1 1. create : removed call to com/rbctcsworld/ecommerce/coupon/CouponService::checkTerms → KILLED
        checkTerms(r.type(), r.value(), r.validFrom(), r.validUntil());
86
        Coupon c = coupons.save(new Coupon(code, r.type(), r.value(), r.minOrderAmount(), r.maxUses(),
87
                r.validFrom(), r.validUntil()));
88 1 1. create : removed call to org/springframework/context/ApplicationEventPublisher::publishEvent → KILLED
        events.publishEvent(AuditEvent.of(AuditChange.diff(AuditChange.COUPON, c.getId(), "COUPON_CREATED", null,
89
                audited(c))));
90 1 1. create : replaced return value with null for com/rbctcsworld/ecommerce/coupon/CouponService::create → KILLED
        return c;
91
    }
92
93
    /** New terms for an existing coupon. maxUses may not go below the times it was already used. */
94
    public Coupon update(long id, CouponDtos.UpdateCouponRequest r) {
95 1 1. lambda$update$1 : replaced return value with null for com/rbctcsworld/ecommerce/coupon/CouponService::lambda$update$1 → KILLED
        Coupon c = coupons.findById(id).orElseThrow(() -> new NotFoundException("Coupon not found: " + id));
96 1 1. update : removed call to com/rbctcsworld/ecommerce/coupon/CouponService::checkTerms → KILLED
        checkTerms(r.type(), r.value(), r.validFrom(), r.validUntil());
97 3 1. update : removed conditional - replaced comparison check with false → KILLED
2. update : removed conditional - replaced equality check with false → KILLED
3. update : changed conditional boundary → KILLED
        if (r.maxUses() != null && r.maxUses() < c.getUsedCount()) {
98
            throw new BusinessRuleException("maxUses cannot be below the times already used (" + c.getUsedCount() + ")");
99
        }
100
        Map<String, Object> before = audited(c);
101 1 1. update : removed call to com/rbctcsworld/ecommerce/coupon/Coupon::update → KILLED
        c.update(r.type(), r.value(), r.minOrderAmount(), r.maxUses(), r.validFrom(), r.validUntil());
102 1 1. update : removed call to org/springframework/context/ApplicationEventPublisher::publishEvent → KILLED
        events.publishEvent(AuditEvent.of(AuditChange.diff(AuditChange.COUPON, id, "COUPON_UPDATED", before,
103
                audited(c))));
104 1 1. update : replaced return value with null for com/rbctcsworld/ecommerce/coupon/CouponService::update → KILLED
        return c;
105
    }
106
107
    /** Switches a coupon off (customers get "Invalid coupon code") or on again. Same state: nothing recorded. */
108
    public Coupon setActive(long id, boolean active) {
109 1 1. lambda$setActive$2 : replaced return value with null for com/rbctcsworld/ecommerce/coupon/CouponService::lambda$setActive$2 → KILLED
        Coupon c = coupons.findById(id).orElseThrow(() -> new NotFoundException("Coupon not found: " + id));
110 1 1. setActive : removed conditional - replaced equality check with false → KILLED
        if (c.isActive() != active) {
111 1 1. setActive : removed call to com/rbctcsworld/ecommerce/coupon/Coupon::setActive → KILLED
            c.setActive(active);
112 1 1. setActive : removed call to org/springframework/context/ApplicationEventPublisher::publishEvent → KILLED
            events.publishEvent(AuditEvent.of(List.of(new AuditChange(AuditChange.COUPON, id,
113 2 1. setActive : removed conditional - replaced equality check with false → KILLED
2. setActive : removed conditional - replaced equality check with false → KILLED
                    active ? "COUPON_ENABLED" : "COUPON_DISABLED", "active", Boolean.toString(!active),
114
                    Boolean.toString(active)))));
115
        }
116 1 1. setActive : replaced return value with null for com/rbctcsworld/ecommerce/coupon/CouponService::setActive → KILLED
        return c;
117
    }
118
119
    /**
120
     * Coupons for the admin list. q = part of the code; status = ACTIVE (usable now) | SCHEDULED (starts
121
     * later) | EXPIRED | USED_UP | DISABLED | null (all).
122
     */
123
    @Transactional(readOnly = true)
124
    public List<Coupon> search(String q, String status) {
125 1 1. search : removed conditional - replaced equality check with false → SURVIVED
        String part = q == null ? "" : normalize(q);
126 2 1. search : removed conditional - replaced equality check with false → KILLED
2. search : removed conditional - replaced equality check with false → KILLED
        String wanted = status == null || status.isBlank() ? null : status.trim().toUpperCase(Locale.ROOT);
127 2 1. search : removed conditional - replaced equality check with false → KILLED
2. search : removed conditional - replaced equality check with false → KILLED
        if (wanted != null && !STATES.contains(wanted)) {
128
            throw new BusinessRuleException("status must be one of " + STATES);
129
        }
130 1 1. search : replaced return value with Collections.emptyList for com/rbctcsworld/ecommerce/coupon/CouponService::search → KILLED
        return coupons.findAllByOrderByIdAsc().stream()
131 2 1. lambda$search$3 : replaced boolean return with true for com/rbctcsworld/ecommerce/coupon/CouponService::lambda$search$3 → KILLED
2. lambda$search$3 : replaced boolean return with false for com/rbctcsworld/ecommerce/coupon/CouponService::lambda$search$3 → KILLED
                .filter(c -> c.getCode().contains(part))
132 3 1. lambda$search$4 : removed conditional - replaced equality check with false → KILLED
2. lambda$search$4 : replaced boolean return with true for com/rbctcsworld/ecommerce/coupon/CouponService::lambda$search$4 → KILLED
3. lambda$search$4 : removed conditional - replaced equality check with false → KILLED
                .filter(c -> wanted == null || wanted.equals(state(c)))
133
                .toList();
134
    }
135
136
    public static final List<String> STATES = List.of("ACTIVE", "SCHEDULED", "EXPIRED", "USED_UP", "DISABLED");
137
138
    /** What a customer would experience with this coupon right now. */
139
    public String state(Coupon c) {
140
        LocalDateTime now = LocalDateTime.now(clock);
141 2 1. state : replaced return value with "" for com/rbctcsworld/ecommerce/coupon/CouponService::state → KILLED
2. state : removed conditional - replaced equality check with false → KILLED
        if (!c.isActive()) return "DISABLED";
142 3 1. state : removed conditional - replaced equality check with false → KILLED
2. state : replaced return value with "" for com/rbctcsworld/ecommerce/coupon/CouponService::state → KILLED
3. state : removed conditional - replaced equality check with false → KILLED
        if (c.getValidUntil() != null && now.isAfter(c.getValidUntil())) return "EXPIRED";
143 2 1. state : removed conditional - replaced equality check with false → KILLED
2. state : replaced return value with "" for com/rbctcsworld/ecommerce/coupon/CouponService::state → KILLED
        if (c.usageLimitReached()) return "USED_UP";
144 3 1. state : replaced return value with "" for com/rbctcsworld/ecommerce/coupon/CouponService::state → KILLED
2. state : removed conditional - replaced equality check with false → KILLED
3. state : removed conditional - replaced equality check with false → KILLED
        if (c.getValidFrom() != null && now.isBefore(c.getValidFrom())) return "SCHEDULED";
145 1 1. state : replaced return value with "" for com/rbctcsworld/ecommerce/coupon/CouponService::state → KILLED
        return "ACTIVE";
146
    }
147
148
    private static void checkTerms(String type, BigDecimal value, LocalDateTime from, LocalDateTime until) {
149 3 1. checkTerms : removed conditional - replaced equality check with false → KILLED
2. checkTerms : removed conditional - replaced comparison check with false → KILLED
3. checkTerms : changed conditional boundary → KILLED
        if (Coupon.PERCENT.equals(type) && value.compareTo(BigDecimal.valueOf(100)) > 0) {
150
            throw new BusinessRuleException("PERCENT coupon value must be between 0 and 100");
151
        }
152 3 1. checkTerms : removed conditional - replaced equality check with false → KILLED
2. checkTerms : removed conditional - replaced equality check with false → KILLED
3. checkTerms : removed conditional - replaced equality check with false → KILLED
        if (from != null && until != null && until.isBefore(from)) {
153
            throw new BusinessRuleException("validUntil must be after validFrom");
154
        }
155
    }
156
157
    static Map<String, Object> audited(Coupon c) {
158 1 1. audited : replaced return value with Collections.emptyMap for com/rbctcsworld/ecommerce/coupon/CouponService::audited → KILLED
        return AuditChange.fields("code", c.getCode(), "type", c.getType(), "value", c.getDiscountValue(),
159
                "minOrderAmount", c.getMinOrderAmount(), "maxUses", c.getMaxUses(), "validFrom", c.getValidFrom(),
160
                "validUntil", c.getValidUntil(), "active", c.isActive());
161
    }
162
163
    @Transactional(readOnly = true)
164
    public List<Coupon> all() {
165 1 1. all : replaced return value with Collections.emptyList for com/rbctcsworld/ecommerce/coupon/CouponService::all → KILLED
        return coupons.findAllByOrderByIdAsc();
166
    }
167
168
    public static String normalize(String code) {
169 2 1. normalize : replaced return value with "" for com/rbctcsworld/ecommerce/coupon/CouponService::normalize → KILLED
2. normalize : removed conditional - replaced equality check with false → KILLED
        return code == null ? "" : code.trim().toUpperCase();
170
    }
171
}

Mutations

51

1.1
Location : lambda$validate$0
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:unknownOrInactiveCodeIsInvalid()]
replaced return value with null for com/rbctcsworld/ecommerce/coupon/CouponService::lambda$validate$0 → KILLED

54

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

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

57

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

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

60

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

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

63

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

66

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

69

1.1
Location : validate
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/CouponService::validate → KILLED

74

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

82

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

85

1.1
Location : create
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:percentAbove100IsRejectedOnCreate()]
removed call to com/rbctcsworld/ecommerce/coupon/CouponService::checkTerms → KILLED

88

1.1
Location : create
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:aNewCouponIsAuditedWithItsTerms()]
removed call to org/springframework/context/ApplicationEventPublisher::publishEvent → KILLED

90

1.1
Location : create
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/CouponService::create → KILLED

95

1.1
Location : lambda$update$1
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:anEditFollowsTheSameRulesAsCreate()]
replaced return value with null for com/rbctcsworld/ecommerce/coupon/CouponService::lambda$update$1 → 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 call to com/rbctcsworld/ecommerce/coupon/CouponService::checkTerms → KILLED

97

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 comparison check with false → KILLED

2.2
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

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

101

1.1
Location : update
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:anEditChangesTheTermsKeepsTheCodeAndAuditsOnlyWhatChanged()]
removed call to com/rbctcsworld/ecommerce/coupon/Coupon::update → KILLED

102

1.1
Location : update
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:anEditChangesTheTermsKeepsTheCodeAndAuditsOnlyWhatChanged()]
removed call to org/springframework/context/ApplicationEventPublisher::publishEvent → KILLED

104

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

109

1.1
Location : lambda$setActive$2
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:switchingOffAndOnIsAuditedOnceAndRepeatingChangesNothing()]
replaced return value with null for com/rbctcsworld/ecommerce/coupon/CouponService::lambda$setActive$2 → KILLED

110

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

111

1.1
Location : setActive
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:switchingOffAndOnIsAuditedOnceAndRepeatingChangesNothing()]
removed call to com/rbctcsworld/ecommerce/coupon/Coupon::setActive → KILLED

112

1.1
Location : setActive
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:switchingOffAndOnIsAuditedOnceAndRepeatingChangesNothing()]
removed call to org/springframework/context/ApplicationEventPublisher::publishEvent → KILLED

113

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

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

116

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

125

1.1
Location : search
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

126

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

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

127

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

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

130

1.1
Location : search
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:searchFiltersByPartOfTheCodeAndByState()]
replaced return value with Collections.emptyList for com/rbctcsworld/ecommerce/coupon/CouponService::search → KILLED

131

1.1
Location : lambda$search$3
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:searchFiltersByPartOfTheCodeAndByState()]
replaced boolean return with true for com/rbctcsworld/ecommerce/coupon/CouponService::lambda$search$3 → KILLED

2.2
Location : lambda$search$3
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:searchFiltersByPartOfTheCodeAndByState()]
replaced boolean return with false for com/rbctcsworld/ecommerce/coupon/CouponService::lambda$search$3 → KILLED

132

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

2.2
Location : lambda$search$4
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:searchFiltersByPartOfTheCodeAndByState()]
replaced boolean return with true for com/rbctcsworld/ecommerce/coupon/CouponService::lambda$search$4 → KILLED

3.3
Location : lambda$search$4
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:searchFiltersByPartOfTheCodeAndByState()]
removed conditional - replaced equality check with false → KILLED

141

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

2.2
Location : state
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

142

1.1
Location : state
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

2.2
Location : state
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:theStateIsWhatACustomerWouldExperienceNow()]
replaced return value with "" for com/rbctcsworld/ecommerce/coupon/CouponService::state → KILLED

3.3
Location : state
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

143

1.1
Location : state
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

2.2
Location : state
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:theStateIsWhatACustomerWouldExperienceNow()]
replaced return value with "" for com/rbctcsworld/ecommerce/coupon/CouponService::state → KILLED

144

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

2.2
Location : state
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

3.3
Location : state
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

145

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

149

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

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

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

152

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

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

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

158

1.1
Location : audited
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:aNewCouponIsAuditedWithItsTerms()]
replaced return value with Collections.emptyMap for com/rbctcsworld/ecommerce/coupon/CouponService::audited → KILLED

165

1.1
Location : all
Killed by : com.rbctcsworld.ecommerce.coupon.CouponServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.coupon.CouponServiceTest]/[method:listAndNormaliseHelpers()]
replaced return value with Collections.emptyList for com/rbctcsworld/ecommerce/coupon/CouponService::all → KILLED

169

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

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

Active mutators

Tests examined


Report generated by PIT 1.30.0 support