Skip to content

Commit ee58ea1

Browse files
committed
Kill mutants
1 parent 35e9026 commit ee58ea1

File tree

4 files changed

+192
-6
lines changed

4 files changed

+192
-6
lines changed

ecommerce/pricing/lib/pricing/discounts.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@ def exists?
6363

6464
class ThreePlusOneGratis
6565
def apply(product_quantities, product_id, base_price)
66-
product = product_quantities.find { |product_quantity| product_quantity[:product_id] == product_id }
67-
return [false, price: base_price] if product.nil?
68-
quantity = product[:quantity] + 1
69-
return [false, base_price] if quantity < 4
70-
return [true, 0] if quantity % 4 == 0
66+
product = product_quantities.find { |product_quantity| product_quantity.fetch(:product_id) == product_id }
67+
return [false, base_price] if product.nil?
68+
quantity = product.fetch(:quantity) + 1
69+
return [false, base_price] if !quantity.%(4).eql?(0)
70+
[true, 0]
7171
end
7272
end
7373
end

ecommerce/pricing/lib/pricing/services.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def initialize(event_store)
120120

121121
def call(command)
122122
@repository.with_aggregate(Offer, command.aggregate_id) do |order|
123-
promotion = command.promotion ? Discounts::ThreePlusOneGratis.new : nil
123+
promotion = Discounts::ThreePlusOneGratis.new if command.promotion
124124
order.add_item(command.product_id, command.price, promotion)
125125
end
126126
end

ecommerce/pricing/test/discounts_test.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,55 @@ def test_doesnt_change_total
6464
assert_equal(100, NoPercentageDiscount.new.apply(100))
6565
end
6666
end
67+
68+
class ThreePlusOneGratisTest < Test
69+
cover "Pricing::Discounts*"
70+
def setup
71+
@three_plus_one_gratis = ThreePlusOneGratis.new
72+
@product_id = SecureRandom.uuid
73+
end
74+
75+
def test_returns_full_price_when_product_not_found
76+
result = @three_plus_one_gratis.apply([], @product_id, 20)
77+
assert_equal [false, 20], result
78+
end
79+
80+
def test_returns_full_price_when_quantity_plus_one_is_less_than_4
81+
quantities = [{ product_id: @product_id, quantity: 2 }]
82+
result = @three_plus_one_gratis.apply(quantities, @product_id, 20)
83+
assert_equal [false, 20], result
84+
end
85+
86+
def test_returns_free_when_quantity_plus_one_is_4
87+
quantities = [{ product_id: @product_id, quantity: 3 }]
88+
result = @three_plus_one_gratis.apply(quantities, @product_id, 20)
89+
assert_equal [true, 0], result
90+
end
91+
92+
def test_returns_full_price_when_quantity_plus_one_is_5
93+
quantities = [{ product_id: @product_id, quantity: 4 }]
94+
result = @three_plus_one_gratis.apply(quantities, @product_id, 20)
95+
assert_equal [false, 20], result
96+
end
97+
98+
def test_returns_free_when_quantity_plus_one_is_8
99+
quantities = [{ product_id: @product_id, quantity: 7 }]
100+
result = @three_plus_one_gratis.apply(quantities, @product_id, 20)
101+
assert_equal [true, 0], result
102+
end
103+
104+
def test_returns_full_price_when_quantity_plus_one_is_9
105+
quantities = [{ product_id: @product_id, quantity: 8 }]
106+
result = @three_plus_one_gratis.apply(quantities, @product_id, 20)
107+
assert_equal [false, 20], result
108+
end
109+
110+
def test_does_not_confuse_other_product_ids
111+
other_product_id = SecureRandom.uuid
112+
quantities = [{ product_id: other_product_id, quantity: 3 }]
113+
result = @three_plus_one_gratis.apply(quantities, @product_id, 20)
114+
assert_equal [false, 20], result
115+
end
116+
end
67117
end
68118
end

ecommerce/pricing/test/three_plus_one_test.rb

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,5 +434,141 @@ def test_given_three_plus_one_is_applied_when_item_is_removed_then_the_discount_
434434
)
435435
) { remove_item(order_id, product_id) }
436436
end
437+
438+
def test_given_three_items_added_to_basket_and_no_three_plus_one_promotion_when_fourth_is_added_then_price_is_not_discounted
439+
product_id = SecureRandom.uuid
440+
set_price(product_id, 20)
441+
order_id = SecureRandom.uuid
442+
stream = "Pricing::Offer$#{order_id}"
443+
444+
3.times { add_item(order_id, product_id) }
445+
446+
assert_events(
447+
stream,
448+
PriceItemAdded.new(
449+
data: {
450+
order_id: order_id,
451+
product_id: product_id,
452+
base_price: 20,
453+
price: 20,
454+
base_total_value: 80,
455+
total_value: 80
456+
}
457+
),
458+
OrderTotalValueCalculated.new(
459+
data: {
460+
order_id: order_id,
461+
total_amount: 80,
462+
discounted_amount: 80
463+
}
464+
),
465+
PriceItemValueCalculated.new(
466+
data: {
467+
order_id: order_id,
468+
product_id: product_id,
469+
quantity: 4,
470+
amount: 80,
471+
discounted_amount: 80,
472+
}),
473+
) { add_item(order_id, product_id) }
474+
end
475+
476+
def test_given_three_items_in_basket_when_different_one_is_added_then_price_is_not_discounted
477+
product_id = SecureRandom.uuid
478+
different_product_id = SecureRandom.uuid
479+
set_price(product_id, 20)
480+
set_price(different_product_id, 50)
481+
order_id = SecureRandom.uuid
482+
stream = "Pricing::Offer$#{order_id}"
483+
484+
3.times { add_item(order_id, product_id) }
485+
486+
assert_events(
487+
stream,
488+
PriceItemAdded.new(
489+
data: {
490+
order_id: order_id,
491+
product_id: different_product_id,
492+
base_price: 50,
493+
price: 50,
494+
base_total_value: 110,
495+
total_value: 110
496+
}
497+
),
498+
OrderTotalValueCalculated.new(
499+
data: {
500+
order_id: order_id,
501+
total_amount: 110,
502+
discounted_amount: 110
503+
}
504+
),
505+
PriceItemValueCalculated.new(
506+
data: {
507+
order_id: order_id,
508+
product_id: product_id,
509+
quantity: 3,
510+
amount: 60,
511+
discounted_amount: 60,
512+
}),
513+
PriceItemValueCalculated.new(
514+
data: {
515+
order_id: order_id,
516+
product_id: different_product_id,
517+
quantity: 1,
518+
amount: 50,
519+
discounted_amount: 50,
520+
})
521+
) { add_item(order_id, different_product_id) }
522+
end
523+
524+
def test_given_two_sets_of_three_items_in_basket_when_added_forth_item_then_price_is_discounted_for_that_item
525+
product_id = SecureRandom.uuid
526+
different_product_id = SecureRandom.uuid
527+
set_price(product_id, 20)
528+
set_price(different_product_id, 50)
529+
order_id = SecureRandom.uuid
530+
stream = "Pricing::Offer$#{order_id}"
531+
532+
3.times { add_item(order_id, product_id, promotion: true) }
533+
3.times { add_item(order_id, different_product_id, promotion: true) }
534+
535+
assert_events(
536+
stream,
537+
PriceItemAdded.new(
538+
data: {
539+
order_id: order_id,
540+
product_id: different_product_id,
541+
base_price: 50,
542+
price: 0,
543+
base_total_value: 260,
544+
total_value: 210,
545+
applied_promotion: Pricing::Discounts::ThreePlusOneGratis.to_s
546+
}
547+
),
548+
OrderTotalValueCalculated.new(
549+
data: {
550+
order_id: order_id,
551+
total_amount: 260,
552+
discounted_amount: 210
553+
}
554+
),
555+
PriceItemValueCalculated.new(
556+
data: {
557+
order_id: order_id,
558+
product_id: product_id,
559+
quantity: 3,
560+
amount: 60,
561+
discounted_amount: 60,
562+
}),
563+
PriceItemValueCalculated.new(
564+
data: {
565+
order_id: order_id,
566+
product_id: different_product_id,
567+
quantity: 4,
568+
amount: 200,
569+
discounted_amount: 150,
570+
})
571+
) { add_item(order_id, different_product_id, promotion: true) }
572+
end
437573
end
438574
end

0 commit comments

Comments
 (0)