From b947f953052a32fc814a75e04d4d25f1b9fc3be3 Mon Sep 17 00:00:00 2001 From: Piotr Dec Date: Wed, 22 May 2024 19:12:42 +0200 Subject: [PATCH 1/7] test: fixes UserEntity builder --- src/test/java/eu/ztsh/wymiana/EntityCreator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/eu/ztsh/wymiana/EntityCreator.java b/src/test/java/eu/ztsh/wymiana/EntityCreator.java index 9caa4c8..61d5533 100644 --- a/src/test/java/eu/ztsh/wymiana/EntityCreator.java +++ b/src/test/java/eu/ztsh/wymiana/EntityCreator.java @@ -56,7 +56,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 +68,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 ); } From 3121caf8f74d62f4e5223ed7b7d7c0a9dbfb7fd8 Mon Sep 17 00:00:00 2001 From: Piotr Dec Date: Wed, 22 May 2024 19:13:43 +0200 Subject: [PATCH 2/7] feat: POJO mappers --- .../eu/ztsh/wymiana/util/CurrencyMapper.java | 24 ++++++++++++++++ .../java/eu/ztsh/wymiana/util/UserMapper.java | 16 +++++++++++ .../eu/ztsh/wymiana/util/UserMapperTest.java | 28 +++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 src/main/java/eu/ztsh/wymiana/util/CurrencyMapper.java create mode 100644 src/main/java/eu/ztsh/wymiana/util/UserMapper.java create mode 100644 src/test/java/eu/ztsh/wymiana/util/UserMapperTest.java 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..ea744f4 --- /dev/null +++ b/src/main/java/eu/ztsh/wymiana/util/UserMapper.java @@ -0,0 +1,16 @@ +package eu.ztsh.wymiana.util; + +import eu.ztsh.wymiana.data.entity.UserEntity; +import eu.ztsh.wymiana.model.User; + +public class UserMapper { + + public static User entityToPojo(UserEntity entity) { + return new User(entity.getName(), entity.getSurname(), entity.getPesel(), + CurrencyMapper.entitiesToPojoMap(entity.getCurrencies())); + } + + private UserMapper() { + } + +} 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..7b97107 --- /dev/null +++ b/src/test/java/eu/ztsh/wymiana/util/UserMapperTest.java @@ -0,0 +1,28 @@ +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); + } + +} From 7207e9b2561f56322b06788a440714be904c0bfd Mon Sep 17 00:00:00 2001 From: Piotr Dec Date: Wed, 22 May 2024 19:14:08 +0200 Subject: [PATCH 3/7] feat: UserService TDD --- .../eu/ztsh/wymiana/service/UserService.java | 21 +++++++ .../ztsh/wymiana/service/UserServiceTest.java | 63 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 src/main/java/eu/ztsh/wymiana/service/UserService.java create mode 100644 src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java 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..7b1e652 --- /dev/null +++ b/src/main/java/eu/ztsh/wymiana/service/UserService.java @@ -0,0 +1,21 @@ +package eu.ztsh.wymiana.service; + +import eu.ztsh.wymiana.model.User; +import eu.ztsh.wymiana.web.model.UserCreateRequest; +import jakarta.validation.Valid; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +public class UserService { + + public User create(@Valid UserCreateRequest request) { + throw new IllegalStateException("Not impplemented yet"); + } + + public Optional get(String pesel) { + throw new IllegalStateException("Not impplemented yet"); + } + +} 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..7edb478 --- /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.util.UserMapper; +import eu.ztsh.wymiana.web.model.UserCreateRequest; +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 = new UserService(); + + @Autowired + public UserServiceTest(UserRepository userRepository) { + super(userRepository); + } + + @Test + void createNewUserTest() { + userService.create(createRequest()); + var entity = EntityCreator.user().build(); + expect(entity); + } + + @Test + void createDuplicatedUser() { + userService.create(createRequest()); + assertThatThrownBy(() -> userService.create(createRequest())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Duplicated PESEL: %s".formatted(EntityCreator.Constants.PESEL)); + + } + + @Test + 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(); + } + + private UserCreateRequest createRequest() { + return new UserCreateRequest(EntityCreator.Constants.NAME, EntityCreator.Constants.SURNAME, + EntityCreator.Constants.PESEL, 20.10); + } + +} From 52ae2789fc3a51ffd4042e9598e136898c49446c Mon Sep 17 00:00:00 2001 From: Piotr Dec Date: Wed, 22 May 2024 19:16:07 +0200 Subject: [PATCH 4/7] fix: SonarLint fixes --- src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java b/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java index 7edb478..0ef2abc 100644 --- a/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java +++ b/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java @@ -29,11 +29,12 @@ class UserServiceTest extends RepositoryBasedTest { @Test void createDuplicatedUser() { - userService.create(createRequest()); - assertThatThrownBy(() -> userService.create(createRequest())) + var first = createRequest(); + var second = createRequest(); + userService.create(first); + assertThatThrownBy(() -> userService.create(second)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Duplicated PESEL: %s".formatted(EntityCreator.Constants.PESEL)); - } @Test From c7ef32e28d2e101877eabf643ae3d3e91c22f569 Mon Sep 17 00:00:00 2001 From: Piotr Dec Date: Wed, 22 May 2024 19:21:26 +0200 Subject: [PATCH 5/7] feat: Dedicated exception on user creation --- .../wymiana/exception/UserAlreadyExistsException.java | 11 +++++++++++ .../java/eu/ztsh/wymiana/service/UserService.java | 6 ++++++ .../java/eu/ztsh/wymiana/service/UserServiceTest.java | 8 +++++--- 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 src/main/java/eu/ztsh/wymiana/exception/UserAlreadyExistsException.java 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 index 7b1e652..341112c 100644 --- a/src/main/java/eu/ztsh/wymiana/service/UserService.java +++ b/src/main/java/eu/ztsh/wymiana/service/UserService.java @@ -1,15 +1,21 @@ package eu.ztsh.wymiana.service; +import eu.ztsh.wymiana.data.repository.UserRepository; import eu.ztsh.wymiana.model.User; 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) { throw new IllegalStateException("Not impplemented yet"); } diff --git a/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java b/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java index 0ef2abc..4dd6908 100644 --- a/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java +++ b/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java @@ -3,6 +3,7 @@ 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 eu.ztsh.wymiana.web.model.UserCreateRequest; import org.junit.jupiter.api.Test; @@ -13,11 +14,12 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; class UserServiceTest extends RepositoryBasedTest { - private final UserService userService = new UserService(); + private final UserService userService; @Autowired public UserServiceTest(UserRepository userRepository) { super(userRepository); + userService = new UserService(userRepository); } @Test @@ -33,8 +35,8 @@ class UserServiceTest extends RepositoryBasedTest { var second = createRequest(); userService.create(first); assertThatThrownBy(() -> userService.create(second)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Duplicated PESEL: %s".formatted(EntityCreator.Constants.PESEL)); + .isInstanceOf(UserAlreadyExistsException.class) + .hasMessage("User with PESEL %s already exists".formatted(EntityCreator.Constants.PESEL)); } @Test From 9d6ba747a8613a6fe4b9cc9e54e84e6cdfef305a Mon Sep 17 00:00:00 2001 From: Piotr Dec Date: Wed, 22 May 2024 19:37:19 +0200 Subject: [PATCH 6/7] feat: UserService implementation --- .../java/eu/ztsh/wymiana/service/UserService.java | 10 +++++++--- src/main/java/eu/ztsh/wymiana/util/UserMapper.java | 9 +++++++++ src/test/java/eu/ztsh/wymiana/EntityCreator.java | 5 +++++ .../eu/ztsh/wymiana/service/UserServiceTest.java | 14 ++++++-------- .../java/eu/ztsh/wymiana/util/UserMapperTest.java | 9 +++++++++ 5 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/main/java/eu/ztsh/wymiana/service/UserService.java b/src/main/java/eu/ztsh/wymiana/service/UserService.java index 341112c..01cba7c 100644 --- a/src/main/java/eu/ztsh/wymiana/service/UserService.java +++ b/src/main/java/eu/ztsh/wymiana/service/UserService.java @@ -1,7 +1,9 @@ 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; @@ -15,13 +17,15 @@ public class UserService { private final UserRepository userRepository; - public User create(@Valid UserCreateRequest request) { - throw new IllegalStateException("Not impplemented yet"); + if (userRepository.findById(request.pesel()).isPresent()) { + throw new UserAlreadyExistsException(request); + } + return UserMapper.entityToPojo(userRepository.save(UserMapper.requestToEntity(request))); } public Optional get(String pesel) { - throw new IllegalStateException("Not impplemented yet"); + return userRepository.findById(pesel).map(UserMapper::entityToPojo); } } diff --git a/src/main/java/eu/ztsh/wymiana/util/UserMapper.java b/src/main/java/eu/ztsh/wymiana/util/UserMapper.java index ea744f4..b4aff44 100644 --- a/src/main/java/eu/ztsh/wymiana/util/UserMapper.java +++ b/src/main/java/eu/ztsh/wymiana/util/UserMapper.java @@ -1,7 +1,11 @@ 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 { @@ -10,6 +14,11 @@ public class UserMapper { 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 61d5533..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; diff --git a/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java b/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java index 4dd6908..5d9656e 100644 --- a/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java +++ b/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java @@ -6,6 +6,7 @@ import eu.ztsh.wymiana.data.repository.UserRepository; import eu.ztsh.wymiana.exception.UserAlreadyExistsException; import eu.ztsh.wymiana.util.UserMapper; import eu.ztsh.wymiana.web.model.UserCreateRequest; +import jakarta.transaction.Transactional; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -23,16 +24,17 @@ class UserServiceTest extends RepositoryBasedTest { } @Test + @Transactional void createNewUserTest() { - userService.create(createRequest()); + userService.create(EntityCreator.userRequest()); var entity = EntityCreator.user().build(); expect(entity); } @Test void createDuplicatedUser() { - var first = createRequest(); - var second = createRequest(); + var first = EntityCreator.userRequest(); + var second = EntityCreator.userRequest(); userService.create(first); assertThatThrownBy(() -> userService.create(second)) .isInstanceOf(UserAlreadyExistsException.class) @@ -40,6 +42,7 @@ class UserServiceTest extends RepositoryBasedTest { } @Test + @Transactional void getExistingUserTest() { var entity = EntityCreator.user().build(); userRepository.save(entity); @@ -58,9 +61,4 @@ class UserServiceTest extends RepositoryBasedTest { assertThat(userOptional).isEmpty(); } - private UserCreateRequest createRequest() { - return new UserCreateRequest(EntityCreator.Constants.NAME, EntityCreator.Constants.SURNAME, - EntityCreator.Constants.PESEL, 20.10); - } - } diff --git a/src/test/java/eu/ztsh/wymiana/util/UserMapperTest.java b/src/test/java/eu/ztsh/wymiana/util/UserMapperTest.java index 7b97107..f3fc91d 100644 --- a/src/test/java/eu/ztsh/wymiana/util/UserMapperTest.java +++ b/src/test/java/eu/ztsh/wymiana/util/UserMapperTest.java @@ -25,4 +25,13 @@ class UserMapperTest { .isEqualTo(expected); } + @Test + void requestToEntityTest() { + var request = EntityCreator.userRequest(); + var expected = EntityCreator.user().build(); + assertThat(UserMapper.requestToEntity(request)) + .usingRecursiveComparison() + .isEqualTo(expected); + } + } From 753b0976d6fd0955e2d6903ecf4440f207b9cfe1 Mon Sep 17 00:00:00 2001 From: Piotr Dec Date: Wed, 22 May 2024 19:43:21 +0200 Subject: [PATCH 7/7] fix: Formatting fixes --- src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java b/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java index 5d9656e..4a9b94b 100644 --- a/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java +++ b/src/test/java/eu/ztsh/wymiana/service/UserServiceTest.java @@ -5,7 +5,6 @@ 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 eu.ztsh.wymiana.web.model.UserCreateRequest; import jakarta.transaction.Transactional; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired;