diff --git a/src/main/java/eu/ztsh/wymiana/exception/UserAlreadyExistsException.java b/src/main/java/eu/ztsh/wymiana/exception/UserAlreadyExistsException.java new file mode 100644 index 0000000..659b495 --- /dev/null +++ b/src/main/java/eu/ztsh/wymiana/exception/UserAlreadyExistsException.java @@ -0,0 +1,11 @@ +package eu.ztsh.wymiana.exception; + +import eu.ztsh.wymiana.web.model.UserCreateRequest; + +public class UserAlreadyExistsException extends RuntimeException { + + public UserAlreadyExistsException(UserCreateRequest entity) { + super("User with PESEL %s already exists".formatted(entity.pesel())); + } + +} diff --git a/src/main/java/eu/ztsh/wymiana/service/UserService.java b/src/main/java/eu/ztsh/wymiana/service/UserService.java new file mode 100644 index 0000000..01cba7c --- /dev/null +++ b/src/main/java/eu/ztsh/wymiana/service/UserService.java @@ -0,0 +1,31 @@ +package eu.ztsh.wymiana.service; + +import eu.ztsh.wymiana.data.repository.UserRepository; +import eu.ztsh.wymiana.exception.UserAlreadyExistsException; +import eu.ztsh.wymiana.model.User; +import eu.ztsh.wymiana.util.UserMapper; +import eu.ztsh.wymiana.web.model.UserCreateRequest; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@RequiredArgsConstructor +@Service +public class UserService { + + private final UserRepository userRepository; + + public User create(@Valid UserCreateRequest request) { + if (userRepository.findById(request.pesel()).isPresent()) { + throw new UserAlreadyExistsException(request); + } + return UserMapper.entityToPojo(userRepository.save(UserMapper.requestToEntity(request))); + } + + public Optional get(String pesel) { + return userRepository.findById(pesel).map(UserMapper::entityToPojo); + } + +} diff --git a/src/main/java/eu/ztsh/wymiana/util/CurrencyMapper.java b/src/main/java/eu/ztsh/wymiana/util/CurrencyMapper.java new file mode 100644 index 0000000..7542187 --- /dev/null +++ b/src/main/java/eu/ztsh/wymiana/util/CurrencyMapper.java @@ -0,0 +1,24 @@ +package eu.ztsh.wymiana.util; + +import eu.ztsh.wymiana.data.entity.CurrencyEntity; +import eu.ztsh.wymiana.model.Currency; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class CurrencyMapper { + + public static Currency entityToPojo(CurrencyEntity entity) { + return new Currency(entity.getSymbol(), entity.getAmount()); + } + + public static Map entitiesToPojoMap(List values) { + return values.stream().map(CurrencyMapper::entityToPojo) + .collect(Collectors.toMap(Currency::symbol, pojo -> pojo)); + } + + private CurrencyMapper() { + } + +} diff --git a/src/main/java/eu/ztsh/wymiana/util/UserMapper.java b/src/main/java/eu/ztsh/wymiana/util/UserMapper.java new file mode 100644 index 0000000..b4aff44 --- /dev/null +++ b/src/main/java/eu/ztsh/wymiana/util/UserMapper.java @@ -0,0 +1,25 @@ +package eu.ztsh.wymiana.util; + +import eu.ztsh.wymiana.data.entity.CurrencyEntity; +import eu.ztsh.wymiana.data.entity.UserEntity; +import eu.ztsh.wymiana.model.User; +import eu.ztsh.wymiana.web.model.UserCreateRequest; + +import java.util.List; + +public class UserMapper { + + public static User entityToPojo(UserEntity entity) { + return new User(entity.getName(), entity.getSurname(), entity.getPesel(), + CurrencyMapper.entitiesToPojoMap(entity.getCurrencies())); + } + + public static UserEntity requestToEntity(UserCreateRequest request) { + return new UserEntity(request.pesel(), request.name(), request.surname(), + List.of(new CurrencyEntity(request.pesel(), "PLN", request.pln()))); + } + + private UserMapper() { + } + +} diff --git a/src/test/java/eu/ztsh/wymiana/EntityCreator.java b/src/test/java/eu/ztsh/wymiana/EntityCreator.java index 9caa4c8..77ae953 100644 --- a/src/test/java/eu/ztsh/wymiana/EntityCreator.java +++ b/src/test/java/eu/ztsh/wymiana/EntityCreator.java @@ -2,6 +2,7 @@ package eu.ztsh.wymiana; import eu.ztsh.wymiana.data.entity.CurrencyEntity; import eu.ztsh.wymiana.data.entity.UserEntity; +import eu.ztsh.wymiana.web.model.UserCreateRequest; import java.util.ArrayList; import java.util.List; @@ -22,6 +23,10 @@ public class EntityCreator { return new UserEntityBuilder(); } + public static UserCreateRequest userRequest() { + return new UserCreateRequest(Constants.NAME, Constants.SURNAME, Constants.PESEL, Constants.PLN); + } + public static class UserEntityBuilder { String name; @@ -56,7 +61,7 @@ public class EntityCreator { } public UserEntity build() { - var nonnulPesel = Optional.ofNullable(pesel).orElse(Constants.NAME); + var nonnulPesel = Optional.ofNullable(pesel).orElse(Constants.PESEL); List currencies = new ArrayList<>(); if (pln > 0) { currencies.add(new CurrencyEntity(nonnulPesel, "PLN", pln)); @@ -68,9 +73,9 @@ public class EntityCreator { currencies.add(new CurrencyEntity(nonnulPesel, "PLN", Constants.PLN)); } return new UserEntity( + nonnulPesel, Optional.ofNullable(name).orElse(Constants.NAME), Optional.ofNullable(surname).orElse(Constants.SURNAME), - nonnulPesel, currencies ); } diff --git a/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java b/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java new file mode 100644 index 0000000..4a9b94b --- /dev/null +++ b/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java @@ -0,0 +1,63 @@ +package eu.ztsh.wymiana.service; + +import eu.ztsh.wymiana.EntityCreator; +import eu.ztsh.wymiana.RepositoryBasedTest; +import eu.ztsh.wymiana.data.repository.UserRepository; +import eu.ztsh.wymiana.exception.UserAlreadyExistsException; +import eu.ztsh.wymiana.util.UserMapper; +import jakarta.transaction.Transactional; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class UserServiceTest extends RepositoryBasedTest { + + private final UserService userService; + + @Autowired + public UserServiceTest(UserRepository userRepository) { + super(userRepository); + userService = new UserService(userRepository); + } + + @Test + @Transactional + void createNewUserTest() { + userService.create(EntityCreator.userRequest()); + var entity = EntityCreator.user().build(); + expect(entity); + } + + @Test + void createDuplicatedUser() { + var first = EntityCreator.userRequest(); + var second = EntityCreator.userRequest(); + userService.create(first); + assertThatThrownBy(() -> userService.create(second)) + .isInstanceOf(UserAlreadyExistsException.class) + .hasMessage("User with PESEL %s already exists".formatted(EntityCreator.Constants.PESEL)); + } + + @Test + @Transactional + void getExistingUserTest() { + var entity = EntityCreator.user().build(); + userRepository.save(entity); + var userOptional = userService.get(EntityCreator.Constants.PESEL); + var expected = UserMapper.entityToPojo(entity); + assertThat(userOptional) + .isNotEmpty() + .get() + .usingRecursiveComparison() + .isEqualTo(expected); + } + + @Test + void getNonExistingUserTest() { + var userOptional = userService.get(EntityCreator.Constants.PESEL); + assertThat(userOptional).isEmpty(); + } + +} diff --git a/src/test/java/eu/ztsh/wymiana/util/UserMapperTest.java b/src/test/java/eu/ztsh/wymiana/util/UserMapperTest.java new file mode 100644 index 0000000..f3fc91d --- /dev/null +++ b/src/test/java/eu/ztsh/wymiana/util/UserMapperTest.java @@ -0,0 +1,37 @@ +package eu.ztsh.wymiana.util; + +import eu.ztsh.wymiana.EntityCreator; +import eu.ztsh.wymiana.model.Currency; +import eu.ztsh.wymiana.model.User; +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +class UserMapperTest { + + @Test + void entityToPojoTest() { + var entity = EntityCreator.user().build(); + var expected = new User( + EntityCreator.Constants.NAME, + EntityCreator.Constants.SURNAME, + EntityCreator.Constants.PESEL, + Map.of("PLN", new Currency("PLN", EntityCreator.Constants.PLN)) + ); + assertThat(UserMapper.entityToPojo(entity)) + .usingRecursiveComparison() + .isEqualTo(expected); + } + + @Test + void requestToEntityTest() { + var request = EntityCreator.userRequest(); + var expected = EntityCreator.user().build(); + assertThat(UserMapper.requestToEntity(request)) + .usingRecursiveComparison() + .isEqualTo(expected); + } + +}