Skip to content
This repository was archived by the owner on Apr 26, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions src/main/java/group/rohlik/application/CartDiscountAdder.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

@AllArgsConstructor
@Service
Expand All @@ -20,15 +19,8 @@ public class CartDiscountAdder {
public void add(long cartId, String code) {
Cart cart = cartRepository.findById(cartId).orElseThrow();
Discount discount = discountRepository.findByCode(code).orElseThrow();
applyDiscount(cart, discount);
cart.applyDiscount(discount);

cartRepository.save(cart);
}

public void applyDiscount(Cart cart, Discount discount) {
//@todo suspicious code - should we move this logic to cart entity?
Assert.isTrue(!cart.getDiscounts().contains(discount), "Discount already applied");

cart.getDiscounts().add(discount);
}
}
23 changes: 19 additions & 4 deletions src/main/java/group/rohlik/entity/Cart.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,13 @@ private double totalDiscountsPrice() {
}

public double totalPrice() {
return BigDecimal
.valueOf(totalLinesPrice() - totalDiscountsPrice())
.setScale(2, RoundingMode.CEILING)
.doubleValue();
return Math.max(
0,
BigDecimal
.valueOf(totalLinesPrice() - totalDiscountsPrice())
.setScale(2, RoundingMode.CEILING)
.doubleValue()
);
}

public Integer quantityOfProduct(String sku) {
Expand All @@ -96,4 +99,16 @@ public Integer quantityOfProduct(String sku) {
.map(CartLine::getQuantity)
.orElse(0);
}

public boolean hasDiscount(String name) {
return discounts
.stream()
.anyMatch(line -> line.getName().equals(name));
}

public void applyDiscount(Discount discount) {
Assert.isTrue(!discounts.contains(discount), "Discount already applied");

discounts.add(discount);
}
}
34 changes: 29 additions & 5 deletions src/test/java/group/rohlik/acceptance/steps/CartSteps.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package group.rohlik.acceptance.steps;

import group.rohlik.entity.Cart;
import group.rohlik.entity.CartLine;
import group.rohlik.entity.CartRepository;
import group.rohlik.entity.Discount;
import io.cucumber.gherkin.internal.com.eclipsesource.json.JsonObject;
import io.cucumber.java.Before;
import io.cucumber.java.en.Given;
Expand All @@ -17,9 +15,6 @@
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;

import java.math.BigDecimal;
import java.math.RoundingMode;


@RequiredArgsConstructor
public class CartSteps {
Expand Down Expand Up @@ -83,6 +78,35 @@ public void thereShouldNotBeProductInCart(String sku) {
Assertions.assertTrue(cart.quantityOfProduct(sku) == 0, String.format("Product %s should not be present", sku));
}

@Then("there should be discount {string} in my cart")
public void thereShouldBeDiscountInCart(String name) {
Cart cart = currentCart();

Assertions.assertTrue(cart.hasDiscount(name), String.format("Discount %s should be present", name));
}

@Then("there shouldn't be discounts in my cart")
public void thereShouldNotBeDiscountsInCart() {
Cart cart = currentCart();

Assertions.assertEquals(0, cart.getDiscounts().size());
}

@When("I apply {string} discount to my cart")
public void iApplyDiscountToMyCart(String code) {
JsonObject body = new JsonObject();
body.add("code", code);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

template.exchange(
String.format("/carts/%d/discounts", currentCartId),
HttpMethod.POST,
new HttpEntity<>(body.toString(), headers),
String.class
);
}

private Cart currentCart() {
return cartRepository.findById(currentCartId).orElseThrow();
}
Expand Down
39 changes: 39 additions & 0 deletions src/test/resources/features/add_discount_to_cart.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
Feature: Add discount to cart
As a Rohlik customer
I want to apply discounts to my cart
so that I can save some money

Background:
Given the following products exist:
| sku | name | price |
| 001 | potatoes | 2.5 |
| 002 | water | 0.95 |
And there is a cart discount "free shipping" for 1 euros with code "FREE-SHIPPING"
And there is a cart discount "special offer" for 10 euros with code "SPECIAL-OFFER"
And I have a cart

Scenario: No discounts
When I add 2 units of product "001" to my cart
Then the cart's total cost should be 5.0 euros
But there shouldn't be discounts in my cart

Scenario: Add discount
Given I add 2 units of product "001" to my cart
When I apply "FREE-SHIPPING" discount to my cart
Then the cart's total cost should be 4.0 euros
And there should be discount "free shipping" in my cart

Scenario: Add discount only apply once
Given I add 2 units of product "001" to my cart
And I apply "FREE-SHIPPING" discount to my cart
When I apply "FREE-SHIPPING" discount to my cart
Then the cart's total cost should be 4.0 euros
And there should be discount "free shipping" in my cart

Scenario: Cart total should be always positive
Given I add 2 units of product "001" to my cart
And I apply "FREE-SHIPPING" discount to my cart
When I apply "SPECIAL-OFFER" discount to my cart
Then the cart's total cost should be 0.0 euros
And there should be discount "free shipping" in my cart
And there should be discount "special offer" in my cart