Skip to content
Open
Show file tree
Hide file tree
Changes from 12 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package kitchenpos.products.tobe.domain;

import kitchenpos.products.tobe.domain.entity.Product;

import java.util.*;

public class InMemoryProductRepository {
private final Map<UUID, Product> products = new HashMap<>();

public Product save(final Product product) {
products.put(product.getId(), product);
return product;
}

public Optional<Product> findById(final UUID id) {
return Optional.ofNullable(products.get(id));
}

public List<Product> findAll() {
return new ArrayList<>(products.values());
}

public List<Product> findAllByIdIn(final List<UUID> ids) {
return products.values()
.stream()
.filter(product -> ids.contains(product.getId()))
.toList();
}

public void update(final Product newProduct) {
Optional<Product> pd = this.findById(newProduct.getId());
List<Product> pds = this.findAll();
if(pd.isEmpty()){
throw new NoSuchElementException("Product not found with id: " + newProduct.getId());
}

this.save(newProduct);
}
}
44 changes: 44 additions & 0 deletions src/main/java/kitchenpos/products/tobe/domain/ProductService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package kitchenpos.products.tobe.domain;

import kitchenpos.products.tobe.domain.entity.Product;
import kitchenpos.products.tobe.domain.strategy.Profanity;
import kitchenpos.products.tobe.domain.vo.DisplayedName;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

public class ProductService {
private final InMemoryProductRepository productRepository;

public ProductService(InMemoryProductRepository repository) {
this.productRepository = repository;
}

public void register(Product product) {
product.validateProperty();
this.productRepository.save(product);
}

public void changeName(UUID productId, String name) throws Exception {
Optional<Product> optionalProduct = this.productRepository.findById(productId);
if (optionalProduct.isEmpty()) {
// Handle the case when the product is not found
throw new Exception("Product not found with id: " + productId);
}

Product product = optionalProduct.get();
Product changedProduct = new Product(productId, new DisplayedName(name), product.getPrice(), new Profanity());
changedProduct.checkValidName();

this.productRepository.update(changedProduct);
}

public List<Product> getList() {
return this.productRepository.findAll();
}

public Optional<Product> findById(UUID id) {
return this.productRepository.findById(id);
}
}
54 changes: 54 additions & 0 deletions src/main/java/kitchenpos/products/tobe/domain/entity/Product.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package kitchenpos.products.tobe.domain.entity;

import kitchenpos.products.tobe.domain.strategy.Profanity;
import kitchenpos.products.tobe.domain.vo.DisplayedName;
import kitchenpos.products.tobe.domain.vo.Price;

import java.util.UUID;


public class Product {
private final UUID id;
private final DisplayedName displayedName;
private final Price price;
private final Profanity profanity;

public Product(UUID id, DisplayedName displayedName, Price price, Profanity profanity) {
this.id = (id != null) ? id : UUID.randomUUID();
this.displayedName = displayedName;
this.price = price;
this.profanity = profanity;
}

// Constructor that generates a random UUID
public Product(DisplayedName displayedName, Price price) {
this(UUID.randomUUID(), displayedName, price, new Profanity());
}

public UUID getId() {
return this.id;
}

public Price getPrice() {
return this.price;
}

public DisplayedName getName() {
return this.displayedName;
}

public void validateProperty() {
this.checkValidPrice();
this.checkValidName();
}

public void checkValidName() {
this.profanity.validate(this.displayedName.value());
}

private void checkValidPrice() {
if (this.price.getValue() <= 0) {
throw new IllegalArgumentException("Price should be over zero, not negative");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package kitchenpos.products.tobe.domain.strategy;

import java.util.ArrayList;
import java.util.List;

public class Profanity {

public void validate(String word) {
List<String> wrongWords = new ArrayList<>();
wrongWords.add("wrong-name");

if (wrongWords.contains(word)) {
throw new IllegalArgumentException("The word '" + word + "' is not allowed.");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package kitchenpos.products.tobe.domain.vo;

public class DisplayedName {
private final String value;
public DisplayedName(String value){
this.value = value;
}

public String value(){
return this.value;
}
}
13 changes: 13 additions & 0 deletions src/main/java/kitchenpos/products/tobe/domain/vo/Price.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package kitchenpos.products.tobe.domain.vo;

public class Price {
final int value;

public Price(int value) {
this.value = value;
}

public int getValue(){
return this.value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
public class InMemoryProductRepository implements ProductRepository {
private final Map<UUID, Product> products = new HashMap<>();


@Override
public Product save(final Product product) {
products.put(product.getId(), product);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package kitchenpos.products.application.tobe;

import kitchenpos.products.tobe.domain.InMemoryProductRepository;
import kitchenpos.products.tobe.domain.entity.Product;
import kitchenpos.products.tobe.domain.ProductService;
import kitchenpos.products.tobe.domain.vo.DisplayedName;
import kitchenpos.products.tobe.domain.vo.Price;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;

public class ProductServiceTest {
@DisplayName("상품의 이름에는 비속어가 포함될 수 없다")
@Test
void changeWrongNameTest() throws Exception {
Price price = new Price(10);
DisplayedName displayedName = new DisplayedName("wrong-name");
Product pd = new Product(displayedName, price);

ProductService service = new ProductService(new InMemoryProductRepository());
assertThatThrownBy(() -> service.register(pd))
.isInstanceOf(IllegalArgumentException.class);
}


@DisplayName("상품의 이름을 변경할 수 있다")
@Test
void changeGetNameTest() throws Exception {
Price price = new Price(10);
DisplayedName displayedName = new DisplayedName("name");
Product pd = new Product(displayedName, price);

ProductService service = new ProductService(new InMemoryProductRepository());
service.register(pd);

service.changeName(pd.getId(), "new-name");

Optional<Product> updatedPd = service.findById(pd.getId());
Product upd = updatedPd.get();
assertThat(upd.getName().value()).isEqualTo("new-name");
}

@DisplayName("상품을 등록할 수 있다")
@Test
void registerTest() {
Price price = new Price(10);
DisplayedName displayedName = new DisplayedName("name");
Product pd = new Product(displayedName, price);

ProductService service = new ProductService(new InMemoryProductRepository());
service.register(pd);

List<Product> pdList = service.getList();
assertThat(pdList).hasSize(1);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package kitchenpos.products.application.tobe;


import kitchenpos.products.tobe.domain.entity.Product;
import kitchenpos.products.tobe.domain.vo.DisplayedName;
import kitchenpos.products.tobe.domain.vo.Price;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThatThrownBy;

public class ProductTest {

@DisplayName("상품의 이름은 비속어이면 안된다")
@Disabled("not implemented")
@Test
void ProductGetNameTest() {
Price price = new Price(10);
DisplayedName displayedName = new DisplayedName("아이씨");
assertThatThrownBy(()->new Product(displayedName, price)).isInstanceOf(IllegalArgumentException.class);
}

@DisplayName("상품의 가격은 0원 이상이어야 한다.")
@Test
void ProductPriceTest() {
Price price = new Price(0);
DisplayedName displayedName = new DisplayedName("my-product");
assertThatThrownBy(()->new Product(displayedName, price).validateProperty()).isInstanceOf(IllegalArgumentException.class);
}

@DisplayName("상품에는 가격과 이름이 필요로 하다")
@Test
void EntityPropertyTest() {
Price price = new Price(100);
DisplayedName displayedName = new DisplayedName("my-product");
Product pd = new Product(displayedName, price);
Assertions.assertNotNull(pd);
}
}