ProductService.java

1
package com.rbctcsworld.ecommerce.product;
2
3
import jakarta.persistence.criteria.Predicate;
4
import org.springframework.data.jpa.domain.Specification;
5
import java.util.ArrayList;
6
import java.util.Locale;
7
8
import com.rbctcsworld.ecommerce.common.exception.BusinessRuleException;
9
import com.rbctcsworld.ecommerce.common.exception.ConflictException;
10
import com.rbctcsworld.ecommerce.common.exception.NotFoundException;
11
import com.rbctcsworld.ecommerce.audit.AuditChange;
12
import com.rbctcsworld.ecommerce.audit.AuditEvent;
13
import com.rbctcsworld.ecommerce.inventory.InventoryService;
14
import org.springframework.context.ApplicationEventPublisher;
15
import org.springframework.data.domain.Page;
16
import org.springframework.data.domain.PageRequest;
17
import org.springframework.data.domain.Sort;
18
import org.springframework.stereotype.Service;
19
import org.springframework.transaction.annotation.Transactional;
20
21
import java.util.List;
22
import java.util.Map;
23
24
@Service
25
@Transactional
26
public class ProductService {
27
28
    private final ProductRepository repo;
29
    private final ApplicationEventPublisher events;
30
    private final InventoryService inventory;
31
32
    public ProductService(ProductRepository repo, ApplicationEventPublisher events, InventoryService inventory) {
33
        this.repo = repo;
34
        this.events = events;
35
        this.inventory = inventory;
36
    }
37
38
    /** The product fields the audit trail follows (ratings change with every review and are not audited). */
39
    static Map<String, Object> audited(Product p) {
40 1 1. audited : replaced return value with Collections.emptyMap for com/rbctcsworld/ecommerce/product/ProductService::audited → KILLED
        return AuditChange.fields("name", p.getName(), "sku", p.getSku(), "category", p.getCategory(),
41
                "price", p.getPrice(), "stock", p.getStock(), "imageUrl", p.getImageUrl(), "active", p.isActive(),
42
                "variantGroup", p.getVariantGroup(), "size", p.getSize(), "color", p.getColor(),
43
                "dealPrice", p.getDealPrice(), "dealStartsAt", p.getDealStartsAt(), "dealEndsAt", p.getDealEndsAt());
44
    }
45
46
    private void audit(Product p, String action, Map<String, Object> before) {
47 1 1. audit : removed call to org/springframework/context/ApplicationEventPublisher::publishEvent → KILLED
        events.publishEvent(AuditEvent.of(AuditChange.diff(AuditChange.PRODUCT, p.getId(), action, before, audited(p))));
48
    }
49
50
    public static final int DEFAULT_PAGE_SIZE = 20;
51
    public static final int MAX_PAGE_SIZE = 100;
52
    public static final List<String> SORTS = List.of("id", "name", "price_asc", "price_desc");
53
54
    /**
55
     * DEF-007: one page of the active catalog instead of every product. Page 0-based, size 1..100.
56
     * Every sort ends with the id, so pages are stable (no product appears twice or goes missing).
57
     */
58
    @Transactional(readOnly = true)
59
    public Page<Product> page(String q, int page, int size, String sort) {
60 1 1. page : replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::page → KILLED
        return page(q, page, size, sort, ProductFilter.NONE);
61
    }
62
63
    /**
64
     * Like {@link #page(String, int, int, String)} with the extra filters of {@link ProductFilter}.
65
     * minPrice/maxPrice may not be negative and maxPrice may not be below minPrice (400).
66
     */
67
    @Transactional(readOnly = true)
68
    public Page<Product> page(String q, int page, int size, String sort, ProductFilter filter) {
69 2 1. page : changed conditional boundary → KILLED
2. page : removed conditional - replaced comparison check with false → KILLED
        if (page < 0) throw new BusinessRuleException("page must be 0 or greater");
70 4 1. page : removed conditional - replaced comparison check with false → KILLED
2. page : changed conditional boundary → KILLED
3. page : removed conditional - replaced comparison check with false → KILLED
4. page : changed conditional boundary → KILLED
        if (size < 1 || size > MAX_PAGE_SIZE) throw new BusinessRuleException("size must be between 1 and " + MAX_PAGE_SIZE);
71 2 1. page : removed conditional - replaced equality check with false → KILLED
2. page : removed conditional - replaced equality check with false → KILLED
        String s = sort == null || sort.isBlank() ? "id" : sort.trim().toLowerCase();
72 1 1. page : removed conditional - replaced equality check with false → KILLED
        if (!SORTS.contains(s)) throw new BusinessRuleException("sort must be one of " + SORTS);
73
        PageRequest request = PageRequest.of(page, size, sortOf(s));
74 1 1. page : removed conditional - replaced equality check with false → KILLED
        ProductFilter f = checked(filter == null ? ProductFilter.NONE : filter);
75 2 1. page : removed conditional - replaced equality check with false → KILLED
2. page : replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::page → KILLED
        if (!f.isEmpty()) return repo.findAll(spec(q, f), request);
76 3 1. page : removed conditional - replaced equality check with false → KILLED
2. page : replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::page → KILLED
3. page : removed conditional - replaced equality check with false → KILLED
        return (q == null || q.isBlank())
77
                ? repo.findByActiveTrue(request)
78
                : repo.findByNameContainingIgnoreCaseAndActiveTrue(q.trim(), request);
79
    }
80
81
    /**
82
     * active AND name contains q AND every filter of {@link ProductFilter} (each when given). grouped: one row per
83
     * item - a single product, or the first variant (lowest id) of its group that passes the same filters.
84
     */
85
    static Specification<Product> spec(String q, ProductFilter f) {
86 1 1. spec : replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::spec → KILLED
        return (root, query, cb) -> {
87
            List<Predicate> where = new ArrayList<>();
88
            where.add(cb.isTrue(root.<Boolean>get("active")));
89 2 1. lambda$spec$44fe5d0b$1 : removed conditional - replaced equality check with false → NO_COVERAGE
2. lambda$spec$44fe5d0b$1 : removed conditional - replaced equality check with false → NO_COVERAGE
            if (q != null && !q.isBlank()) {
90
                where.add(cb.like(cb.lower(root.<String>get("name")), "%" + q.trim().toLowerCase(Locale.ROOT) + "%"));
91
            }
92
            where.addAll(variantFilters(cb, root, f));
93 1 1. lambda$spec$44fe5d0b$1 : removed conditional - replaced equality check with false → NO_COVERAGE
            if (Boolean.TRUE.equals(f.grouped())) {
94
                var first = query.subquery(Long.class);
95
                var v = first.from(Product.class);
96
                List<Predicate> same = new ArrayList<>(variantFilters(cb, v, f));
97
                same.add(cb.equal(v.get("variantGroup"), root.get("variantGroup")));
98
                same.add(cb.isTrue(v.<Boolean>get("active")));
99
                first.select(cb.min(v.<Long>get("id"))).where(same.toArray(new Predicate[0]));
100
                where.add(cb.or(cb.isNull(root.get("variantGroup")), cb.equal(root.get("id"), first)));
101
            }
102 1 1. lambda$spec$44fe5d0b$1 : replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::lambda$spec$44fe5d0b$1 → NO_COVERAGE
            return cb.and(where.toArray(new Predicate[0]));
103
        };
104
    }
105
106
    /** The filters that look at one product row (the in-memory twin is ProductFilter.matches). */
107
    private static List<Predicate> variantFilters(jakarta.persistence.criteria.CriteriaBuilder cb,
108
                                                  jakarta.persistence.criteria.Path<Product> p, ProductFilter f) {
109
        List<Predicate> where = new ArrayList<>();
110 1 1. variantFilters : removed conditional - replaced equality check with false → NO_COVERAGE
        if (!f.categories().isEmpty()) where.add(cb.lower(p.<String>get("category")).in(f.categories()));
111 1 1. variantFilters : removed conditional - replaced equality check with false → NO_COVERAGE
        if (f.minPrice() != null) where.add(cb.greaterThanOrEqualTo(p.<java.math.BigDecimal>get("price"), f.minPrice()));
112 1 1. variantFilters : removed conditional - replaced equality check with false → NO_COVERAGE
        if (f.maxPrice() != null) where.add(cb.lessThanOrEqualTo(p.<java.math.BigDecimal>get("price"), f.maxPrice()));
113 1 1. variantFilters : removed conditional - replaced equality check with false → NO_COVERAGE
        if (Boolean.TRUE.equals(f.inStock())) where.add(cb.greaterThan(p.<Integer>get("stock"), 0));
114 1 1. variantFilters : removed conditional - replaced equality check with false → NO_COVERAGE
        if (f.minRating() != null) where.add(cb.greaterThanOrEqualTo(p.<java.math.BigDecimal>get("ratingAverage"), f.minRating()));
115 1 1. variantFilters : removed conditional - replaced equality check with false → NO_COVERAGE
        if (!f.colorList().isEmpty()) where.add(cb.lower(p.<String>get("color")).in(f.colorList()));
116 1 1. variantFilters : removed conditional - replaced equality check with false → NO_COVERAGE
        if (!f.sizeList().isEmpty()) where.add(cb.lower(p.<String>get("size")).in(f.sizeList()));
117 1 1. variantFilters : replaced return value with Collections.emptyList for com/rbctcsworld/ecommerce/product/ProductService::variantFilters → NO_COVERAGE
        return where;
118
    }
119
120
    public static final int MAX_FACET_PRODUCTS = 5000;
121
    public static final int MAX_FILTER_VALUES = 20;
122
123
    /**
124
     * Counts for the catalog's filter panel, for the products matching q and the other filters ("disjunctive"
125
     * facets: ticking "books" does not hide the count of "home"). Counts are ITEMS (cards), not variants.
126
     * Computed in memory over at most 5000 matching products: enough for this shop; a big one would use the
127
     * aggregations of a search engine (OpenSearch, Elasticsearch) instead.
128
     */
129
    @Transactional(readOnly = true)
130
    public Facets facets(String q, ProductFilter filter) {
131 1 1. facets : removed conditional - replaced equality check with false → KILLED
        ProductFilter f = checked(filter == null ? ProductFilter.NONE : filter);
132
        List<Product> candidates = repo.findAll(spec(q, ProductFilter.NONE), PageRequest.of(0, MAX_FACET_PRODUCTS, Sort.by("id"))).getContent();
133 1 1. facets : replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::facets → KILLED
        return Facets.count(candidates, f);
134
    }
135
136
    /** The checks every filtered query shares (400 for each). */
137
    static ProductFilter checked(ProductFilter f) {
138 3 1. checked : changed conditional boundary → KILLED
2. checked : removed conditional - replaced equality check with false → KILLED
3. checked : removed conditional - replaced comparison check with false → KILLED
        if (f.minPrice() != null && f.minPrice().signum() < 0) throw new BusinessRuleException("minPrice cannot be negative");
139 3 1. checked : changed conditional boundary → KILLED
2. checked : removed conditional - replaced comparison check with false → KILLED
3. checked : removed conditional - replaced equality check with false → KILLED
        if (f.maxPrice() != null && f.maxPrice().signum() < 0) throw new BusinessRuleException("maxPrice cannot be negative");
140 4 1. checked : removed conditional - replaced equality check with false → KILLED
2. checked : changed conditional boundary → KILLED
3. checked : removed conditional - replaced comparison check with false → KILLED
4. checked : removed conditional - replaced equality check with false → KILLED
        if (f.minPrice() != null && f.maxPrice() != null && f.maxPrice().compareTo(f.minPrice()) < 0) {
141
            throw new BusinessRuleException("maxPrice must not be below minPrice");
142
        }
143 5 1. checked : removed conditional - replaced equality check with false → KILLED
2. checked : changed conditional boundary → KILLED
3. checked : changed conditional boundary → KILLED
4. checked : removed conditional - replaced comparison check with false → KILLED
5. checked : removed conditional - replaced comparison check with false → KILLED
        if (f.minRating() != null && (f.minRating().signum() < 0 || f.minRating().compareTo(java.math.BigDecimal.valueOf(5)) > 0)) {
144
            throw new BusinessRuleException("minRating must be between 0 and 5");
145
        }
146 6 1. checked : changed conditional boundary → SURVIVED
2. checked : changed conditional boundary → SURVIVED
3. checked : removed conditional - replaced comparison check with false → KILLED
4. checked : removed conditional - replaced comparison check with false → KILLED
5. checked : changed conditional boundary → KILLED
6. checked : removed conditional - replaced comparison check with false → KILLED
        if (f.categories().size() > MAX_FILTER_VALUES || f.colorList().size() > MAX_FILTER_VALUES || f.sizeList().size() > MAX_FILTER_VALUES) {
147
            throw new BusinessRuleException("at most " + MAX_FILTER_VALUES + " values per filter");
148
        }
149 1 1. checked : replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::checked → KILLED
        return f;
150
    }
151
152
    public static final int MAX_SIMILAR = 12;
153
154
    /**
155
     * Up to {@code limit} (1..12, default 4) products like this one: same category, in stock first,
156
     * closest price first. 404 when the product itself is not on sale.
157
     */
158
    @Transactional(readOnly = true)
159
    public List<Product> similar(long id, Integer limit) {
160 1 1. similar : removed conditional - replaced equality check with false → KILLED
        int n = limit == null ? 4 : limit;
161 4 1. similar : removed conditional - replaced comparison check with false → KILLED
2. similar : changed conditional boundary → KILLED
3. similar : changed conditional boundary → KILLED
4. similar : removed conditional - replaced comparison check with false → KILLED
        if (n < 1 || n > MAX_SIMILAR) throw new BusinessRuleException("limit must be between 1 and " + MAX_SIMILAR);
162
        Product p = get(id);
163
        // other sizes and colours of the same item are not "similar products" (the product page offers them)
164 1 1. similar : removed conditional - replaced equality check with false → SURVIVED
        int siblings = p.getVariantGroup() == null ? 0 : repo.variantsOf(p.getVariantGroup()).size();
165 1 1. similar : Replaced integer addition with subtraction → KILLED
        PageRequest first = PageRequest.of(0, n + siblings);
166 2 1. similar : removed conditional - replaced equality check with false → KILLED
2. similar : removed conditional - replaced equality check with false → KILLED
        List<Product> found = p.getCategory() == null || p.getCategory().isBlank()
167
                ? repo.similarByPrice(p.getId(), p.getPrice(), first)
168
                : repo.similarInCategory(p.getId(), p.getCategory(), p.getPrice(), first);
169 1 1. similar : replaced return value with Collections.emptyList for com/rbctcsworld/ecommerce/product/ProductService::similar → KILLED
        return found.stream()
170 3 1. lambda$similar$0 : removed conditional - replaced equality check with false → KILLED
2. lambda$similar$0 : replaced boolean return with true for com/rbctcsworld/ecommerce/product/ProductService::lambda$similar$0 → KILLED
3. lambda$similar$0 : removed conditional - replaced equality check with false → KILLED
                .filter(o -> p.getVariantGroup() == null || !p.getVariantGroup().equals(o.getVariantGroup()))
171
                .limit(n).toList();
172
    }
173
174
    /**
175
     * "Customers who bought this also bought": the products that most often share an order with this item (all of
176
     * its sizes and colours count as the item). Only products on sale and in stock, one per item (variant group),
177
     * most frequent first; fewer than {@code limit} when there is little history; empty when nobody bought it yet.
178
     */
179
    @Transactional(readOnly = true)
180
    public List<Product> boughtTogether(long id, Integer limit) {
181 1 1. boughtTogether : removed conditional - replaced equality check with false → KILLED
        int n = limit == null ? 4 : limit;
182 4 1. boughtTogether : changed conditional boundary → SURVIVED
2. boughtTogether : changed conditional boundary → SURVIVED
3. boughtTogether : removed conditional - replaced comparison check with false → KILLED
4. boughtTogether : removed conditional - replaced comparison check with false → KILLED
        if (n < 1 || n > MAX_SIMILAR) throw new BusinessRuleException("limit must be between 1 and " + MAX_SIMILAR);
183
        Product p = get(id);
184 1 1. boughtTogether : removed conditional - replaced equality check with false → SURVIVED
        List<Long> sources = p.getVariantGroup() == null ? List.of(p.getId())
185
                : repo.variantsOf(p.getVariantGroup()).stream().map(Product::getId).toList();
186
        // ask for more than n: sold-out and repeated variants of one item are dropped below
187 2 1. boughtTogether : Replaced integer addition with subtraction → KILLED
2. boughtTogether : Replaced integer multiplication with division → KILLED
        List<Object[]> ranked = repo.boughtWith(sources, PageRequest.of(0, n * 6 + 12));
188 1 1. boughtTogether : removed conditional - replaced equality check with false → SURVIVED
        if (ranked.isEmpty()) return List.of();
189
        Map<Long, Product> byId = new java.util.HashMap<>();
190 2 1. lambda$boughtTogether$1 : replaced Long return value with 0L for com/rbctcsworld/ecommerce/product/ProductService::lambda$boughtTogether$1 → SURVIVED
2. boughtTogether : removed call to java/util/List::forEach → KILLED
        repo.findAllById(ranked.stream().map(r -> ((Number) r[0]).longValue()).toList()).forEach(x -> byId.put(x.getId(), x));
191
        List<Product> out = new ArrayList<>();
192
        java.util.Set<String> seen = new java.util.HashSet<>();
193
        for (Object[] row : ranked) {
194
            Product c = byId.get(((Number) row[0]).longValue());
195 4 1. boughtTogether : removed conditional - replaced comparison check with false → KILLED
2. boughtTogether : removed conditional - replaced equality check with false → KILLED
3. boughtTogether : changed conditional boundary → KILLED
4. boughtTogether : removed conditional - replaced equality check with false → KILLED
            if (c == null || !c.isActive() || c.getStock() < 1) continue;
196 2 1. boughtTogether : removed conditional - replaced equality check with false → KILLED
2. boughtTogether : removed conditional - replaced equality check with false → KILLED
            if (!seen.add(c.getVariantGroup() == null ? "P" + c.getId() : "G" + c.getVariantGroup())) continue;
197
            out.add(c);
198 1 1. boughtTogether : removed conditional - replaced equality check with false → KILLED
            if (out.size() == n) break;
199
        }
200 1 1. boughtTogether : replaced return value with Collections.emptyList for com/rbctcsworld/ecommerce/product/ProductService::boughtTogether → KILLED
        return out;
201
    }
202
203
    /** Every size and colour of this product's item (itself included); a product without variants: just itself. */
204
    @Transactional(readOnly = true)
205
    public List<Product> variants(long id) {
206
        Product p = get(id);
207 2 1. variants : replaced return value with Collections.emptyList for com/rbctcsworld/ecommerce/product/ProductService::variants → KILLED
2. variants : removed conditional - replaced equality check with false → KILLED
        return p.getVariantGroup() == null ? List.of(p) : repo.variantsOf(p.getVariantGroup());
208
    }
209
210
    public static final int MAX_GROUPS = 100;
211
212
    /** For catalog cards: per variant group, how many options, which colours and sizes, price range, units. */
213
    @Transactional(readOnly = true)
214
    public List<VariantSummary> variantSummaries(List<String> groups) {
215 1 1. variantSummaries : removed conditional - replaced equality check with false → KILLED
        List<String> wanted = groups == null ? List.of() : groups.stream()
216 4 1. lambda$variantSummaries$3 : replaced boolean return with true for com/rbctcsworld/ecommerce/product/ProductService::lambda$variantSummaries$3 → KILLED
2. lambda$variantSummaries$3 : removed conditional - replaced equality check with false → KILLED
3. lambda$variantSummaries$4 : replaced return value with "" for com/rbctcsworld/ecommerce/product/ProductService::lambda$variantSummaries$4 → KILLED
4. lambda$variantSummaries$3 : removed conditional - replaced equality check with false → KILLED
                .filter(g -> g != null && !g.isBlank()).map(g -> g.trim().toUpperCase(Locale.ROOT)).distinct().toList();
217 2 1. variantSummaries : removed conditional - replaced comparison check with false → KILLED
2. variantSummaries : changed conditional boundary → KILLED
        if (wanted.size() > MAX_GROUPS) throw new BusinessRuleException("at most " + MAX_GROUPS + " groups at a time");
218 1 1. variantSummaries : removed conditional - replaced equality check with false → KILLED
        if (wanted.isEmpty()) return List.of();
219
        Map<String, List<Product>> byGroup = new java.util.LinkedHashMap<>();
220 1 1. variantSummaries : removed call to java/util/List::forEach → KILLED
        wanted.forEach(g -> byGroup.put(g, new ArrayList<>()));
221 1 1. variantSummaries : removed call to java/util/List::forEach → KILLED
        repo.variantsOfAll(wanted).forEach(p -> byGroup.get(p.getVariantGroup()).add(p));
222 3 1. variantSummaries : replaced return value with Collections.emptyList for com/rbctcsworld/ecommerce/product/ProductService::variantSummaries → KILLED
2. lambda$variantSummaries$7 : replaced boolean return with true for com/rbctcsworld/ecommerce/product/ProductService::lambda$variantSummaries$7 → KILLED
3. lambda$variantSummaries$7 : removed conditional - replaced equality check with false → KILLED
        return byGroup.entrySet().stream().filter(e -> !e.getValue().isEmpty())
223 1 1. lambda$variantSummaries$8 : replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::lambda$variantSummaries$8 → KILLED
                .map(e -> VariantSummary.of(e.getKey(), e.getValue())).toList();
224
    }
225
226
    /**
227
     * Normalises and checks the variant fields: group in upper case, blanks are null; size or colour need a group,
228
     * a group needs a size or a colour (400); no two products on sale of one group with the same size and colour
229
     * (409, ignoring case).
230
     */
231
    VariantKey variantOf(ProductRequest r, Long selfId) {
232
        String group = blankToNull(r.variantGroup());
233
        String size = blankToNull(r.size());
234
        String color = blankToNull(r.color());
235 1 1. variantOf : removed conditional - replaced equality check with false → KILLED
        if (group == null) {
236 2 1. variantOf : removed conditional - replaced equality check with false → KILLED
2. variantOf : removed conditional - replaced equality check with false → KILLED
            if (size != null || color != null) throw new BusinessRuleException("A size or colour needs a variant group");
237 1 1. variantOf : replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::variantOf → KILLED
            return new VariantKey(null, null, null);
238
        }
239
        group = group.toUpperCase(Locale.ROOT);
240 2 1. variantOf : removed conditional - replaced equality check with false → KILLED
2. variantOf : removed conditional - replaced equality check with false → KILLED
        if (size == null && color == null) throw new BusinessRuleException("A variant needs a size, a colour or both");
241
        for (Product other : repo.variantsOf(group)) {
242 3 1. variantOf : removed conditional - replaced equality check with false → KILLED
2. variantOf : removed conditional - replaced equality check with false → KILLED
3. variantOf : removed conditional - replaced equality check with false → KILLED
            if (!other.getId().equals(selfId) && equalsIgnoreCase(other.getSize(), size) && equalsIgnoreCase(other.getColor(), color)) {
243
                throw new ConflictException("Variant group " + group + " already has " + label(color, size) + " (SKU " + other.getSku() + ")");
244
            }
245
        }
246 1 1. variantOf : replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::variantOf → KILLED
        return new VariantKey(group, size, color);
247
    }
248
249
    record VariantKey(String group, String size, String color) {}
250
251
    private static String blankToNull(String v) {
252 3 1. blankToNull : removed conditional - replaced equality check with false → KILLED
2. blankToNull : replaced return value with "" for com/rbctcsworld/ecommerce/product/ProductService::blankToNull → KILLED
3. blankToNull : removed conditional - replaced equality check with false → KILLED
        return v == null || v.isBlank() ? null : v.trim().replaceAll("\\s+", " ");
253
    }
254
255
    private static boolean equalsIgnoreCase(String a, String b) {
256 4 1. equalsIgnoreCase : removed conditional - replaced equality check with false → KILLED
2. equalsIgnoreCase : replaced boolean return with true for com/rbctcsworld/ecommerce/product/ProductService::equalsIgnoreCase → KILLED
3. equalsIgnoreCase : removed conditional - replaced equality check with false → KILLED
4. equalsIgnoreCase : replaced boolean return with false for com/rbctcsworld/ecommerce/product/ProductService::equalsIgnoreCase → KILLED
        return a == null ? b == null : a.equalsIgnoreCase(b);
257
    }
258
259
    private static String label(String color, String size) {
260 1 1. label : replaced return value with "" for com/rbctcsworld/ecommerce/product/ProductService::label → KILLED
        return java.util.stream.Stream.of(color, size).filter(java.util.Objects::nonNull).collect(java.util.stream.Collectors.joining(" / "));
261
    }
262
263
    @Transactional(readOnly = true)
264
    public List<String> categories() {
265 1 1. categories : replaced return value with Collections.emptyList for com/rbctcsworld/ecommerce/product/ProductService::categories → KILLED
        return repo.activeCategories();
266
    }
267
268
    static Sort sortOf(String sort) {
269
        Sort byId = Sort.by(Sort.Order.asc("id"));
270 1 1. sortOf : replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::sortOf → KILLED
        return switch (sort) {
271
            case "name" -> Sort.by(Sort.Order.asc("name").ignoreCase()).and(byId);
272
            case "price_asc" -> Sort.by(Sort.Order.asc("price")).and(byId);
273
            case "price_desc" -> Sort.by(Sort.Order.desc("price")).and(byId);
274
            default -> byId;
275
        };
276
    }
277
278
    /** Deleted (inactive) products are invisible: 404, same as never existed. */
279
    @Transactional(readOnly = true)
280
    public Product get(long id) {
281 1 1. get : replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::get → KILLED
        return repo.findByIdAndActiveTrue(id)
282 1 1. lambda$get$9 : replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::lambda$get$9 → KILLED
                .orElseThrow(() -> new NotFoundException("Product not found: " + id));
283
    }
284
285
    public Product create(ProductRequest r) {
286
        String sku = r.sku().trim();
287 1 1. create : removed conditional - replaced equality check with false → KILLED
        if (repo.existsBySku(sku)) {
288
            throw new ConflictException("SKU already exists: " + sku);
289
        }
290
        VariantKey variant = variantOf(r, null);
291
        Product p = new Product(r.name().trim(), sku, r.category(), r.price(), r.stock());
292 1 1. create : removed call to com/rbctcsworld/ecommerce/product/Product::changeImage → KILLED
        p.changeImage(r.imageUrl());
293 1 1. create : removed call to com/rbctcsworld/ecommerce/product/Product::changeVariant → KILLED
        p.changeVariant(variant.group(), variant.size(), variant.color());
294 1 1. create : removed call to com/rbctcsworld/ecommerce/product/ProductService::checkDeal → SURVIVED
        checkDeal(r, null);
295 1 1. create : removed call to com/rbctcsworld/ecommerce/product/Product::changeDeal → SURVIVED
        p.changeDeal(r.dealPrice(), r.dealStartsAt(), r.dealEndsAt());
296
        Product saved = repo.save(p);
297 1 1. create : removed call to com/rbctcsworld/ecommerce/inventory/InventoryService::stockNewProduct → KILLED
        inventory.stockNewProduct(saved.getId(), saved.getStock());       // the first units go to the default warehouse
298 1 1. create : removed call to com/rbctcsworld/ecommerce/product/ProductService::audit → KILLED
        audit(saved, "PRODUCT_CREATED", null);
299 1 1. create : replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::create → KILLED
        return saved;
300
    }
301
302
    public Product update(long id, ProductRequest r) {
303
        Product p = get(id);
304
        String sku = r.sku().trim();
305
        repo.findBySku(sku)
306 2 1. lambda$update$10 : removed conditional - replaced equality check with false → KILLED
2. lambda$update$10 : replaced boolean return with true for com/rbctcsworld/ecommerce/product/ProductService::lambda$update$10 → KILLED
                .filter(other -> !other.getId().equals(p.getId()))
307 1 1. update : removed call to java/util/Optional::ifPresent → KILLED
                .ifPresent(other -> { throw new ConflictException("SKU already exists: " + sku); });
308
        VariantKey variant = variantOf(r, p.getId());
309 1 1. update : removed call to com/rbctcsworld/ecommerce/product/ProductService::checkDeal → SURVIVED
        checkDeal(r, p);
310
        Map<String, Object> before = audited(p);
311 1 1. update : removed call to com/rbctcsworld/ecommerce/inventory/InventoryService::changeTotalFromProductForm → KILLED
        inventory.changeTotalFromProductForm(p.getId(), r.stock());        // atomic; the entity never writes stock
312 1 1. update : removed call to com/rbctcsworld/ecommerce/product/Product::update → KILLED
        p.update(r.name().trim(), sku, r.category(), r.price(), r.stock());
313 1 1. update : removed call to com/rbctcsworld/ecommerce/product/Product::changeImage → KILLED
        p.changeImage(r.imageUrl());                                  // PUT replaces: no imageUrl = no picture
314 1 1. update : removed call to com/rbctcsworld/ecommerce/product/Product::changeVariant → KILLED
        p.changeVariant(variant.group(), variant.size(), variant.color());  // ... and no variant fields = no variant
315 1 1. update : removed call to com/rbctcsworld/ecommerce/product/Product::changeDeal → SURVIVED
        p.changeDeal(r.dealPrice(), r.dealStartsAt(), r.dealEndsAt());      // ... and no deal fields = no deal
316
        Product saved = repo.save(p);
317 1 1. update : removed call to com/rbctcsworld/ecommerce/product/ProductService::audit → KILLED
        audit(saved, "PRODUCT_UPDATED", before);
318 1 1. update : replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::update → KILLED
        return saved;
319
    }
320
321
    public static final int MAX_DEAL_DAYS = 30;
322
    public static final int MAX_DEALS_SHOWN = 12;
323
324
    /**
325
     * A deal is a price below the normal price between two UTC times: all three fields or none (400), the end after
326
     * the start, at most 30 days long, and not already over. An unchanged deal that has ended is kept as it is, so
327
     * the form of a product whose deal is over can still be saved.
328
     */
329
    void checkDeal(ProductRequest r, Product existing) {
330 3 1. checkDeal : removed conditional - replaced equality check with false → SURVIVED
2. checkDeal : removed conditional - replaced equality check with false → KILLED
3. checkDeal : removed conditional - replaced equality check with false → KILLED
        boolean any = r.dealPrice() != null || r.dealStartsAt() != null || r.dealEndsAt() != null;
331 1 1. checkDeal : removed conditional - replaced equality check with false → KILLED
        if (!any) return;
332 1 1. checkDeal : removed conditional - replaced equality check with false → KILLED
        if (r.dealPrice() == null) throw new BusinessRuleException("A deal needs a deal price");
333 2 1. checkDeal : removed conditional - replaced equality check with false → KILLED
2. checkDeal : removed conditional - replaced equality check with false → KILLED
        if (r.dealStartsAt() == null || r.dealEndsAt() == null) throw new BusinessRuleException("A deal needs a start and an end");
334 2 1. checkDeal : removed conditional - replaced comparison check with false → KILLED
2. checkDeal : changed conditional boundary → KILLED
        if (r.dealPrice().compareTo(r.price()) >= 0) throw new BusinessRuleException("The deal price must be lower than the price");
335 1 1. checkDeal : removed conditional - replaced equality check with false → KILLED
        if (!r.dealEndsAt().isAfter(r.dealStartsAt())) throw new BusinessRuleException("The deal must end after it starts");
336 2 1. checkDeal : changed conditional boundary → KILLED
2. checkDeal : removed conditional - replaced comparison check with false → KILLED
        if (java.time.Duration.between(r.dealStartsAt(), r.dealEndsAt()).compareTo(java.time.Duration.ofDays(MAX_DEAL_DAYS)) > 0) {
337
            throw new BusinessRuleException("A deal can last " + MAX_DEAL_DAYS + " days at most");
338
        }
339 3 1. checkDeal : removed conditional - replaced equality check with false → SURVIVED
2. checkDeal : removed conditional - replaced equality check with false → KILLED
3. checkDeal : removed conditional - replaced equality check with false → KILLED
        boolean unchanged = existing != null && r.dealPrice().compareTo(existing.getDealPrice() == null ? java.math.BigDecimal.valueOf(-1) : existing.getDealPrice()) == 0
340 2 1. checkDeal : removed conditional - replaced equality check with false → KILLED
2. checkDeal : removed conditional - replaced equality check with false → KILLED
                && r.dealStartsAt().equals(existing.getDealStartsAt()) && r.dealEndsAt().equals(existing.getDealEndsAt());
341 2 1. checkDeal : removed conditional - replaced equality check with false → KILLED
2. checkDeal : removed conditional - replaced equality check with false → KILLED
        if (!unchanged && !r.dealEndsAt().isAfter(java.time.LocalDateTime.now(java.time.ZoneOffset.UTC))) {
342
            throw new BusinessRuleException("The deal has already ended");
343
        }
344
    }
345
346
    /** The deals running right now (UTC), the one ending first on top; only products in stock. */
347
    @Transactional(readOnly = true)
348
    public List<Product> liveDeals() {
349 1 1. liveDeals : replaced return value with Collections.emptyList for com/rbctcsworld/ecommerce/product/ProductService::liveDeals → NO_COVERAGE
        return repo.liveDeals(java.time.LocalDateTime.now(java.time.ZoneOffset.UTC), PageRequest.of(0, MAX_DEALS_SHOWN));
350
    }
351
352
    /** Soft delete: keeps history for orders/audit, hides the product from customers. */
353
    public void delete(long id) {
354
        Product p = get(id);
355
        Map<String, Object> before = audited(p);
356 1 1. delete : removed call to com/rbctcsworld/ecommerce/product/Product::setActive → KILLED
        p.setActive(false);
357
        repo.save(p);
358 1 1. delete : removed call to com/rbctcsworld/ecommerce/product/ProductService::audit → KILLED
        audit(p, "PRODUCT_DELETED", before);
359
    }
360
}

Mutations

40

1.1
Location : audited
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:aDeletedProductIsAuditedAsNoLongerActive()]
replaced return value with Collections.emptyMap for com/rbctcsworld/ecommerce/product/ProductService::audited → KILLED

47

1.1
Location : audit
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:aDeletedProductIsAuditedAsNoLongerActive()]
removed call to org/springframework/context/ApplicationEventPublisher::publishEvent → KILLED

60

1.1
Location : page
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:smallestPageSizeAndBlankSortAreAcceptedAndThePageIsReturned()]
replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::page → KILLED

69

1.1
Location : page
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:withoutExtraFiltersTheCatalogQueryStaysTheSame()]
changed conditional boundary → KILLED

2.2
Location : page
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[test-template:invalidPageSizeOrSortIs400(int, int, java.lang.String)]/[test-template-invocation:#1]
removed conditional - replaced comparison check with false → KILLED

70

1.1
Location : page
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[test-template:invalidPageSizeOrSortIs400(int, int, java.lang.String)]/[test-template-invocation:#3]
removed conditional - replaced comparison check with false → KILLED

2.2
Location : page
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:smallestPageSizeAndBlankSortAreAcceptedAndThePageIsReturned()]
changed conditional boundary → KILLED

3.3
Location : page
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:withoutExtraFiltersTheCatalogQueryStaysTheSame()]
removed conditional - replaced comparison check with false → KILLED

4.4
Location : page
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:requestedPageAndStableSortReachTheDatabase()]
changed conditional boundary → KILLED

71

1.1
Location : page
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[test-template:invalidPageSizeOrSortIs400(int, int, java.lang.String)]/[test-template-invocation:#4]
removed conditional - replaced equality check with false → KILLED

2.2
Location : page
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:smallestPageSizeAndBlankSortAreAcceptedAndThePageIsReturned()]
removed conditional - replaced equality check with false → KILLED

72

1.1
Location : page
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[test-template:invalidPageSizeOrSortIs400(int, int, java.lang.String)]/[test-template-invocation:#4]
removed conditional - replaced equality check with false → KILLED

74

1.1
Location : page
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:withoutExtraFiltersTheCatalogQueryStaysTheSame()]
removed conditional - replaced equality check with false → KILLED

75

1.1
Location : page
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:thePriceRangeMustMakeSense()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : page
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:thePriceRangeMustMakeSense()]
replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::page → KILLED

76

1.1
Location : page
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:requestedPageAndStableSortReachTheDatabase()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : page
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:smallestPageSizeAndBlankSortAreAcceptedAndThePageIsReturned()]
replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::page → KILLED

3.3
Location : page
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:searchUsesTheNameQueryAndDefaultsToIdOrder()]
removed conditional - replaced equality check with false → KILLED

86

1.1
Location : spec
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:thePriceRangeMustMakeSense()]
replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::spec → KILLED

89

1.1
Location : lambda$spec$44fe5d0b$1
Killed by : none
removed conditional - replaced equality check with false → NO_COVERAGE

2.2
Location : lambda$spec$44fe5d0b$1
Killed by : none
removed conditional - replaced equality check with false → NO_COVERAGE

93

1.1
Location : lambda$spec$44fe5d0b$1
Killed by : none
removed conditional - replaced equality check with false → NO_COVERAGE

102

1.1
Location : lambda$spec$44fe5d0b$1
Killed by : none
replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::lambda$spec$44fe5d0b$1 → NO_COVERAGE

110

1.1
Location : variantFilters
Killed by : none
removed conditional - replaced equality check with false → NO_COVERAGE

111

1.1
Location : variantFilters
Killed by : none
removed conditional - replaced equality check with false → NO_COVERAGE

112

1.1
Location : variantFilters
Killed by : none
removed conditional - replaced equality check with false → NO_COVERAGE

113

1.1
Location : variantFilters
Killed by : none
removed conditional - replaced equality check with false → NO_COVERAGE

114

1.1
Location : variantFilters
Killed by : none
removed conditional - replaced equality check with false → NO_COVERAGE

115

1.1
Location : variantFilters
Killed by : none
removed conditional - replaced equality check with false → NO_COVERAGE

116

1.1
Location : variantFilters
Killed by : none
removed conditional - replaced equality check with false → NO_COVERAGE

117

1.1
Location : variantFilters
Killed by : none
replaced return value with Collections.emptyList for com/rbctcsworld/ecommerce/product/ProductService::variantFilters → NO_COVERAGE

131

1.1
Location : facets
Killed by : com.rbctcsworld.ecommerce.product.FacetSearchTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FacetSearchTest]/[method:theFacetsComeFromTheProductsMatchingTheSearch()]
removed conditional - replaced equality check with false → KILLED

133

1.1
Location : facets
Killed by : com.rbctcsworld.ecommerce.product.FacetSearchTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FacetSearchTest]/[method:badFiltersAre400()]
replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::facets → KILLED

138

1.1
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:thePriceRangeMustMakeSense()]
changed conditional boundary → KILLED

2.2
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:thePriceRangeMustMakeSense()]
removed conditional - replaced equality check with false → KILLED

3.3
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:thePriceRangeMustMakeSense()]
removed conditional - replaced comparison check with false → KILLED

139

1.1
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:thePriceRangeMustMakeSense()]
changed conditional boundary → KILLED

2.2
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:thePriceRangeMustMakeSense()]
removed conditional - replaced comparison check with false → KILLED

3.3
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:thePriceRangeMustMakeSense()]
removed conditional - replaced equality check with false → KILLED

140

1.1
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:thePriceRangeMustMakeSense()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:thePriceRangeMustMakeSense()]
changed conditional boundary → KILLED

3.3
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:thePriceRangeMustMakeSense()]
removed conditional - replaced comparison check with false → KILLED

4.4
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:thePriceRangeMustMakeSense()]
removed conditional - replaced equality check with false → KILLED

143

1.1
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.FacetSearchTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FacetSearchTest]/[method:badFiltersAre400()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.FacetSearchTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FacetSearchTest]/[method:badFiltersAre400()]
changed conditional boundary → KILLED

3.3
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.FacetSearchTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FacetSearchTest]/[method:badFiltersAre400()]
changed conditional boundary → KILLED

4.4
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.FacetSearchTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FacetSearchTest]/[method:badFiltersAre400()]
removed conditional - replaced comparison check with false → KILLED

5.5
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.FacetSearchTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FacetSearchTest]/[method:badFiltersAre400()]
removed conditional - replaced comparison check with false → KILLED

146

1.1
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:withoutExtraFiltersTheCatalogQueryStaysTheSame()]
removed conditional - replaced comparison check with false → KILLED

2.2
Location : checked
Killed by : none
changed conditional boundary → SURVIVED
Covering tests

3.3
Location : checked
Killed by : none
changed conditional boundary → SURVIVED Covering tests

4.4
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.FacetSearchTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FacetSearchTest]/[method:badFiltersAre400()]
removed conditional - replaced comparison check with false → KILLED

5.5
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.FacetSearchTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FacetSearchTest]/[method:badFiltersAre400()]
changed conditional boundary → KILLED

6.6
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:withoutExtraFiltersTheCatalogQueryStaysTheSame()]
removed conditional - replaced comparison check with false → KILLED

149

1.1
Location : checked
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:withoutExtraFiltersTheCatalogQueryStaysTheSame()]
replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::checked → KILLED

160

1.1
Location : similar
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:similarProductsComeFromTheSameCategoryNearestPriceFirst()]
removed conditional - replaced equality check with false → KILLED

161

1.1
Location : similar
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:theNumberOfSimilarProductsIsLimitedAndTheProductMustBeOnSale()]
removed conditional - replaced comparison check with false → KILLED

2.2
Location : similar
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:theNumberOfSimilarProductsIsLimitedAndTheProductMustBeOnSale()]
changed conditional boundary → KILLED

3.3
Location : similar
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:withoutACategorySimilarMeansTheClosestPrice()]
changed conditional boundary → KILLED

4.4
Location : similar
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:theNumberOfSimilarProductsIsLimitedAndTheProductMustBeOnSale()]
removed conditional - replaced comparison check with false → KILLED

164

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

165

1.1
Location : similar
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:otherSizesAndColoursOfTheSameItemAreNotSimilarProducts()]
Replaced integer addition with subtraction → KILLED

166

1.1
Location : similar
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:withoutACategorySimilarMeansTheClosestPrice()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : similar
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:similarProductsComeFromTheSameCategoryNearestPriceFirst()]
removed conditional - replaced equality check with false → KILLED

169

1.1
Location : similar
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:similarProductsComeFromTheSameCategoryNearestPriceFirst()]
replaced return value with Collections.emptyList for com/rbctcsworld/ecommerce/product/ProductService::similar → KILLED

170

1.1
Location : lambda$similar$0
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:otherSizesAndColoursOfTheSameItemAreNotSimilarProducts()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : lambda$similar$0
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:otherSizesAndColoursOfTheSameItemAreNotSimilarProducts()]
replaced boolean return with true for com/rbctcsworld/ecommerce/product/ProductService::lambda$similar$0 → KILLED

3.3
Location : lambda$similar$0
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:otherSizesAndColoursOfTheSameItemAreNotSimilarProducts()]
removed conditional - replaced equality check with false → KILLED

181

1.1
Location : boughtTogether
Killed by : com.rbctcsworld.ecommerce.product.BoughtTogetherTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.BoughtTogetherTest]/[method:noHistoryMeansNoRecommendations()]
removed conditional - replaced equality check with false → KILLED

182

1.1
Location : boughtTogether
Killed by : com.rbctcsworld.ecommerce.product.BoughtTogetherTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.BoughtTogetherTest]/[method:anUnknownOrInactiveProductIs404()]
removed conditional - replaced comparison check with false → KILLED

2.2
Location : boughtTogether
Killed by : com.rbctcsworld.ecommerce.product.BoughtTogetherTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.BoughtTogetherTest]/[method:theDefaultIsFourAndTheLimitIsChecked()]
removed conditional - replaced comparison check with false → KILLED

3.3
Location : boughtTogether
Killed by : none
changed conditional boundary → SURVIVED
Covering tests

4.4
Location : boughtTogether
Killed by : none
changed conditional boundary → SURVIVED Covering tests

184

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

187

1.1
Location : boughtTogether
Killed by : com.rbctcsworld.ecommerce.product.BoughtTogetherTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.BoughtTogetherTest]/[method:mostFrequentFirstAndOnlyWhatCanBeBought()]
Replaced integer addition with subtraction → KILLED

2.2
Location : boughtTogether
Killed by : com.rbctcsworld.ecommerce.product.BoughtTogetherTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.BoughtTogetherTest]/[method:theDefaultIsFourAndTheLimitIsChecked()]
Replaced integer multiplication with division → KILLED

188

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

190

1.1
Location : boughtTogether
Killed by : com.rbctcsworld.ecommerce.product.BoughtTogetherTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.BoughtTogetherTest]/[method:mostFrequentFirstAndOnlyWhatCanBeBought()]
removed call to java/util/List::forEach → KILLED

2.2
Location : lambda$boughtTogether$1
Killed by : none
replaced Long return value with 0L for com/rbctcsworld/ecommerce/product/ProductService::lambda$boughtTogether$1 → SURVIVED
Covering tests

195

1.1
Location : boughtTogether
Killed by : com.rbctcsworld.ecommerce.product.BoughtTogetherTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.BoughtTogetherTest]/[method:mostFrequentFirstAndOnlyWhatCanBeBought()]
removed conditional - replaced comparison check with false → KILLED

2.2
Location : boughtTogether
Killed by : com.rbctcsworld.ecommerce.product.BoughtTogetherTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.BoughtTogetherTest]/[method:mostFrequentFirstAndOnlyWhatCanBeBought()]
removed conditional - replaced equality check with false → KILLED

3.3
Location : boughtTogether
Killed by : com.rbctcsworld.ecommerce.product.BoughtTogetherTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.BoughtTogetherTest]/[method:mostFrequentFirstAndOnlyWhatCanBeBought()]
changed conditional boundary → KILLED

4.4
Location : boughtTogether
Killed by : com.rbctcsworld.ecommerce.product.BoughtTogetherTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.BoughtTogetherTest]/[method:mostFrequentFirstAndOnlyWhatCanBeBought()]
removed conditional - replaced equality check with false → KILLED

196

1.1
Location : boughtTogether
Killed by : com.rbctcsworld.ecommerce.product.BoughtTogetherTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.BoughtTogetherTest]/[method:allSizesOfTheItemCountAsTheItemAndEachRecommendedItemAppearsOnce()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : boughtTogether
Killed by : com.rbctcsworld.ecommerce.product.BoughtTogetherTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.BoughtTogetherTest]/[method:mostFrequentFirstAndOnlyWhatCanBeBought()]
removed conditional - replaced equality check with false → KILLED

198

1.1
Location : boughtTogether
Killed by : com.rbctcsworld.ecommerce.product.BoughtTogetherTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.BoughtTogetherTest]/[method:mostFrequentFirstAndOnlyWhatCanBeBought()]
removed conditional - replaced equality check with false → KILLED

200

1.1
Location : boughtTogether
Killed by : com.rbctcsworld.ecommerce.product.BoughtTogetherTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.BoughtTogetherTest]/[method:mostFrequentFirstAndOnlyWhatCanBeBought()]
replaced return value with Collections.emptyList for com/rbctcsworld/ecommerce/product/ProductService::boughtTogether → KILLED

207

1.1
Location : variants
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:theVariantsOfAProductAreItsWholeGroupOrJustItself()]
replaced return value with Collections.emptyList for com/rbctcsworld/ecommerce/product/ProductService::variants → KILLED

2.2
Location : variants
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:theVariantsOfAProductAreItsWholeGroupOrJustItself()]
removed conditional - replaced equality check with false → KILLED

215

1.1
Location : variantSummaries
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:noGroupsAskedMeansNoQueryAndAtMostAHundredAtATime()]
removed conditional - replaced equality check with false → KILLED

216

1.1
Location : lambda$variantSummaries$3
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:noGroupsAskedMeansNoQueryAndAtMostAHundredAtATime()]
replaced boolean return with true for com/rbctcsworld/ecommerce/product/ProductService::lambda$variantSummaries$3 → KILLED

2.2
Location : lambda$variantSummaries$3
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:noGroupsAskedMeansNoQueryAndAtMostAHundredAtATime()]
removed conditional - replaced equality check with false → KILLED

3.3
Location : lambda$variantSummaries$4
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:noGroupsAskedMeansNoQueryAndAtMostAHundredAtATime()]
replaced return value with "" for com/rbctcsworld/ecommerce/product/ProductService::lambda$variantSummaries$4 → KILLED

4.4
Location : lambda$variantSummaries$3
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:noGroupsAskedMeansNoQueryAndAtMostAHundredAtATime()]
removed conditional - replaced equality check with false → KILLED

217

1.1
Location : variantSummaries
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:noGroupsAskedMeansNoQueryAndAtMostAHundredAtATime()]
removed conditional - replaced comparison check with false → KILLED

2.2
Location : variantSummaries
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:noGroupsAskedMeansNoQueryAndAtMostAHundredAtATime()]
changed conditional boundary → KILLED

218

1.1
Location : variantSummaries
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:noGroupsAskedMeansNoQueryAndAtMostAHundredAtATime()]
removed conditional - replaced equality check with false → KILLED

220

1.1
Location : variantSummaries
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:summariesListOptionsColoursSizesInClothingOrderPriceRangeAndUnits()]
removed call to java/util/List::forEach → KILLED

221

1.1
Location : variantSummaries
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:summariesListOptionsColoursSizesInClothingOrderPriceRangeAndUnits()]
removed call to java/util/List::forEach → KILLED

222

1.1
Location : variantSummaries
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:summariesListOptionsColoursSizesInClothingOrderPriceRangeAndUnits()]
replaced return value with Collections.emptyList for com/rbctcsworld/ecommerce/product/ProductService::variantSummaries → KILLED

2.2
Location : lambda$variantSummaries$7
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:noGroupsAskedMeansNoQueryAndAtMostAHundredAtATime()]
replaced boolean return with true for com/rbctcsworld/ecommerce/product/ProductService::lambda$variantSummaries$7 → KILLED

3.3
Location : lambda$variantSummaries$7
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:summariesListOptionsColoursSizesInClothingOrderPriceRangeAndUnits()]
removed conditional - replaced equality check with false → KILLED

223

1.1
Location : lambda$variantSummaries$8
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:summariesListOptionsColoursSizesInClothingOrderPriceRangeAndUnits()]
replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::lambda$variantSummaries$8 → KILLED

235

1.1
Location : variantOf
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:aNewProductsStockIsPlacedInTheDefaultWarehouse()]
removed conditional - replaced equality check with false → KILLED

236

1.1
Location : variantOf
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:aSizeOrColourNeedsAGroupAndAGroupNeedsASizeOrColour()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : variantOf
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:aNewProductsStockIsPlacedInTheDefaultWarehouse()]
removed conditional - replaced equality check with false → KILLED

237

1.1
Location : variantOf
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:aNewProductsStockIsPlacedInTheDefaultWarehouse()]
replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::variantOf → KILLED

240

1.1
Location : variantOf
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:aSizeOrColourNeedsAGroupAndAGroupNeedsASizeOrColour()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : variantOf
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:aSizeOrColourNeedsAGroupAndAGroupNeedsASizeOrColour()]
removed conditional - replaced equality check with false → KILLED

242

1.1
Location : variantOf
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:twoProductsOfOneGroupCannotHaveTheSameSizeAndColourIgnoringCase()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : variantOf
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:twoProductsOfOneGroupCannotHaveTheSameSizeAndColourIgnoringCase()]
removed conditional - replaced equality check with false → KILLED

3.3
Location : variantOf
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:twoProductsOfOneGroupCannotHaveTheSameSizeAndColourIgnoringCase()]
removed conditional - replaced equality check with false → KILLED

246

1.1
Location : variantOf
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:onlyASizeOrOnlyAColourIsEnough()]
replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::variantOf → KILLED

252

1.1
Location : blankToNull
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:aSizeOrColourNeedsAGroupAndAGroupNeedsASizeOrColour()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : blankToNull
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:anUpdateThatChangesNothingHasNothingToAudit()]
replaced return value with "" for com/rbctcsworld/ecommerce/product/ProductService::blankToNull → KILLED

3.3
Location : blankToNull
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:aSizeOrColourNeedsAGroupAndAGroupNeedsASizeOrColour()]
removed conditional - replaced equality check with false → KILLED

256

1.1
Location : equalsIgnoreCase
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:aDifferentSizeOrColourInTheSameGroupIsFine()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : equalsIgnoreCase
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:aNewVariantIsSavedWithItsGroupInUpperCaseAndTidySizeAndColour()]
replaced boolean return with true for com/rbctcsworld/ecommerce/product/ProductService::equalsIgnoreCase → KILLED

3.3
Location : equalsIgnoreCase
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:aDifferentSizeOrColourInTheSameGroupIsFine()]
removed conditional - replaced equality check with false → KILLED

4.4
Location : equalsIgnoreCase
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:twoProductsOfOneGroupCannotHaveTheSameSizeAndColourIgnoringCase()]
replaced boolean return with false for com/rbctcsworld/ecommerce/product/ProductService::equalsIgnoreCase → KILLED

260

1.1
Location : label
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:twoProductsOfOneGroupCannotHaveTheSameSizeAndColourIgnoringCase()]
replaced return value with "" for com/rbctcsworld/ecommerce/product/ProductService::label → KILLED

265

1.1
Location : categories
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:categoriesComeFromTheProductsOnSale()]
replaced return value with Collections.emptyList for com/rbctcsworld/ecommerce/product/ProductService::categories → KILLED

270

1.1
Location : sortOf
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:nameSortIgnoresCaseAndEndsWithIdSoPagesAreStable()]
replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::sortOf → KILLED

281

1.1
Location : get
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:withoutACategorySimilarMeansTheClosestPrice()]
replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::get → KILLED

282

1.1
Location : lambda$get$9
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:getInactiveOrMissingProductIsNotFound()]
replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::lambda$get$9 → KILLED

287

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

292

1.1
Location : create
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:createKeepsThePicture()]
removed call to com/rbctcsworld/ecommerce/product/Product::changeImage → KILLED

293

1.1
Location : create
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:onlyASizeOrOnlyAColourIsEnough()]
removed call to com/rbctcsworld/ecommerce/product/Product::changeVariant → KILLED

294

1.1
Location : create
Killed by : none
removed call to com/rbctcsworld/ecommerce/product/ProductService::checkDeal → SURVIVED
Covering tests

295

1.1
Location : create
Killed by : none
removed call to com/rbctcsworld/ecommerce/product/Product::changeDeal → SURVIVED
Covering tests

297

1.1
Location : create
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:aNewProductsStockIsPlacedInTheDefaultWarehouse()]
removed call to com/rbctcsworld/ecommerce/inventory/InventoryService::stockNewProduct → KILLED

298

1.1
Location : create
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:aNewProductIsAuditedWithEveryValue()]
removed call to com/rbctcsworld/ecommerce/product/ProductService::audit → KILLED

299

1.1
Location : create
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:createKeepsThePicture()]
replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::create → KILLED

306

1.1
Location : lambda$update$10
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:updateRejectsSkuUsedByAnotherProduct()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : lambda$update$10
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:anUpdateThatChangesNothingHasNothingToAudit()]
replaced boolean return with true for com/rbctcsworld/ecommerce/product/ProductService::lambda$update$10 → KILLED

307

1.1
Location : update
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:updateRejectsSkuUsedByAnotherProduct()]
removed call to java/util/Optional::ifPresent → KILLED

309

1.1
Location : update
Killed by : none
removed call to com/rbctcsworld/ecommerce/product/ProductService::checkDeal → SURVIVED
Covering tests

311

1.1
Location : update
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:theProductFormsStockGoesThroughTheInventoryBeforeTheOtherFields()]
removed call to com/rbctcsworld/ecommerce/inventory/InventoryService::changeTotalFromProductForm → KILLED

312

1.1
Location : update
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:theProductFormsStockGoesThroughTheInventoryBeforeTheOtherFields()]
removed call to com/rbctcsworld/ecommerce/product/Product::update → KILLED

313

1.1
Location : update
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:updateReplacesOrRemovesThePicture()]
removed call to com/rbctcsworld/ecommerce/product/Product::changeImage → KILLED

314

1.1
Location : update
Killed by : com.rbctcsworld.ecommerce.product.ProductVariantTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductVariantTest]/[method:anUpdateMayKeepItsOwnSizeAndColourAndAPutWithoutThemEndsTheVariant()]
removed call to com/rbctcsworld/ecommerce/product/Product::changeVariant → KILLED

315

1.1
Location : update
Killed by : none
removed call to com/rbctcsworld/ecommerce/product/Product::changeDeal → SURVIVED
Covering tests

317

1.1
Location : update
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:anUpdateThatChangesNothingHasNothingToAudit()]
removed call to com/rbctcsworld/ecommerce/product/ProductService::audit → KILLED

318

1.1
Location : update
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:theProductFormsStockGoesThroughTheInventoryBeforeTheOtherFields()]
replaced return value with null for com/rbctcsworld/ecommerce/product/ProductService::update → KILLED

330

1.1
Location : checkDeal
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:aNewProductsStockIsPlacedInTheDefaultWarehouse()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : checkDeal
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:aNewProductsStockIsPlacedInTheDefaultWarehouse()]
removed conditional - replaced equality check with false → KILLED

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

331

1.1
Location : checkDeal
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:aNewProductsStockIsPlacedInTheDefaultWarehouse()]
removed conditional - replaced equality check with false → KILLED

332

1.1
Location : checkDeal
Killed by : com.rbctcsworld.ecommerce.product.FlashDealTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FlashDealTest]/[method:halfADealIsRefused()]
removed conditional - replaced equality check with false → KILLED

333

1.1
Location : checkDeal
Killed by : com.rbctcsworld.ecommerce.product.FlashDealTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FlashDealTest]/[method:theDealPriceMustBeLowerThanThePrice()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : checkDeal
Killed by : com.rbctcsworld.ecommerce.product.FlashDealTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FlashDealTest]/[method:halfADealIsRefused()]
removed conditional - replaced equality check with false → KILLED

334

1.1
Location : checkDeal
Killed by : com.rbctcsworld.ecommerce.product.FlashDealTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FlashDealTest]/[method:theDealPriceMustBeLowerThanThePrice()]
removed conditional - replaced comparison check with false → KILLED

2.2
Location : checkDeal
Killed by : com.rbctcsworld.ecommerce.product.FlashDealTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FlashDealTest]/[method:theDealPriceMustBeLowerThanThePrice()]
changed conditional boundary → KILLED

335

1.1
Location : checkDeal
Killed by : com.rbctcsworld.ecommerce.product.FlashDealTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FlashDealTest]/[method:theDealMustEndAfterItStartsAndLastAtMostThirtyDays()]
removed conditional - replaced equality check with false → KILLED

336

1.1
Location : checkDeal
Killed by : com.rbctcsworld.ecommerce.product.FlashDealTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FlashDealTest]/[method:theDealMustEndAfterItStartsAndLastAtMostThirtyDays()]
changed conditional boundary → KILLED

2.2
Location : checkDeal
Killed by : com.rbctcsworld.ecommerce.product.FlashDealTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FlashDealTest]/[method:theDealMustEndAfterItStartsAndLastAtMostThirtyDays()]
removed conditional - replaced comparison check with false → KILLED

339

1.1
Location : checkDeal
Killed by : com.rbctcsworld.ecommerce.product.FlashDealTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FlashDealTest]/[method:aNewDealThatIsAlreadyOverIsRefusedButAnUnchangedOldOneIsKept()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : checkDeal
Killed by : com.rbctcsworld.ecommerce.product.FlashDealTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FlashDealTest]/[method:aNewDealThatIsAlreadyOverIsRefusedButAnUnchangedOldOneIsKept()]
removed conditional - replaced equality check with false → KILLED

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

340

1.1
Location : checkDeal
Killed by : com.rbctcsworld.ecommerce.product.FlashDealTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FlashDealTest]/[method:aNewDealThatIsAlreadyOverIsRefusedButAnUnchangedOldOneIsKept()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : checkDeal
Killed by : com.rbctcsworld.ecommerce.product.FlashDealTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FlashDealTest]/[method:aNewDealThatIsAlreadyOverIsRefusedButAnUnchangedOldOneIsKept()]
removed conditional - replaced equality check with false → KILLED

341

1.1
Location : checkDeal
Killed by : com.rbctcsworld.ecommerce.product.FlashDealTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FlashDealTest]/[method:aNewDealThatIsAlreadyOverIsRefusedButAnUnchangedOldOneIsKept()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : checkDeal
Killed by : com.rbctcsworld.ecommerce.product.FlashDealTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.FlashDealTest]/[method:aNewDealThatIsAlreadyOverIsRefusedButAnUnchangedOldOneIsKept()]
removed conditional - replaced equality check with false → KILLED

349

1.1
Location : liveDeals
Killed by : none
replaced return value with Collections.emptyList for com/rbctcsworld/ecommerce/product/ProductService::liveDeals → NO_COVERAGE

356

1.1
Location : delete
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:aDeletedProductIsAuditedAsNoLongerActive()]
removed call to com/rbctcsworld/ecommerce/product/Product::setActive → KILLED

358

1.1
Location : delete
Killed by : com.rbctcsworld.ecommerce.product.ProductServiceTest.[engine:junit-jupiter]/[class:com.rbctcsworld.ecommerce.product.ProductServiceTest]/[method:aDeletedProductIsAuditedAsNoLongerActive()]
removed call to com/rbctcsworld/ecommerce/product/ProductService::audit → KILLED

Active mutators

Tests examined


Report generated by PIT 1.30.0 support