Merge pull request 'user-service' from user-service into master

This commit is contained in:
Piotr Dec 2024-05-22 19:46:14 +02:00
commit 1eee6b1b48
7 changed files with 198 additions and 2 deletions

View file

@ -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()));
}
}

View file

@ -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<User> get(String pesel) {
return userRepository.findById(pesel).map(UserMapper::entityToPojo);
}
}

View file

@ -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<String, Currency> entitiesToPojoMap(List<CurrencyEntity> values) {
return values.stream().map(CurrencyMapper::entityToPojo)
.collect(Collectors.toMap(Currency::symbol, pojo -> pojo));
}
private CurrencyMapper() {
}
}

View file

@ -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() {
}
}

View file

@ -2,6 +2,7 @@ package eu.ztsh.wymiana;
import eu.ztsh.wymiana.data.entity.CurrencyEntity; import eu.ztsh.wymiana.data.entity.CurrencyEntity;
import eu.ztsh.wymiana.data.entity.UserEntity; import eu.ztsh.wymiana.data.entity.UserEntity;
import eu.ztsh.wymiana.web.model.UserCreateRequest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -22,6 +23,10 @@ public class EntityCreator {
return new UserEntityBuilder(); return new UserEntityBuilder();
} }
public static UserCreateRequest userRequest() {
return new UserCreateRequest(Constants.NAME, Constants.SURNAME, Constants.PESEL, Constants.PLN);
}
public static class UserEntityBuilder { public static class UserEntityBuilder {
String name; String name;
@ -56,7 +61,7 @@ public class EntityCreator {
} }
public UserEntity build() { public UserEntity build() {
var nonnulPesel = Optional.ofNullable(pesel).orElse(Constants.NAME); var nonnulPesel = Optional.ofNullable(pesel).orElse(Constants.PESEL);
List<CurrencyEntity> currencies = new ArrayList<>(); List<CurrencyEntity> currencies = new ArrayList<>();
if (pln > 0) { if (pln > 0) {
currencies.add(new CurrencyEntity(nonnulPesel, "PLN", pln)); currencies.add(new CurrencyEntity(nonnulPesel, "PLN", pln));
@ -68,9 +73,9 @@ public class EntityCreator {
currencies.add(new CurrencyEntity(nonnulPesel, "PLN", Constants.PLN)); currencies.add(new CurrencyEntity(nonnulPesel, "PLN", Constants.PLN));
} }
return new UserEntity( return new UserEntity(
nonnulPesel,
Optional.ofNullable(name).orElse(Constants.NAME), Optional.ofNullable(name).orElse(Constants.NAME),
Optional.ofNullable(surname).orElse(Constants.SURNAME), Optional.ofNullable(surname).orElse(Constants.SURNAME),
nonnulPesel,
currencies currencies
); );
} }

View file

@ -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();
}
}

View file

@ -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);
}
}