feat: ExchangeController & tests

This commit is contained in:
Piotr Dec 2024-05-25 00:33:33 +02:00
parent 720937bd6c
commit 95ed5f6ae7
Signed by: stawros
GPG key ID: F89F27AD8F881A91
8 changed files with 85 additions and 21 deletions

View file

@ -0,0 +1,11 @@
package eu.ztsh.wymiana.exception;
import eu.ztsh.wymiana.web.model.CurrencyExchangeRequest;
public class UserNotFoundException extends RuntimeException {
public UserNotFoundException(CurrencyExchangeRequest entity) {
super("User with PESEL %s not found".formatted(entity.pesel()));
}
}

View file

@ -2,6 +2,7 @@ package eu.ztsh.wymiana.service;
import eu.ztsh.wymiana.exception.ExchangeFailedException;
import eu.ztsh.wymiana.exception.InsufficientFundsException;
import eu.ztsh.wymiana.exception.UserNotFoundException;
import eu.ztsh.wymiana.model.Currency;
import eu.ztsh.wymiana.model.User;
import eu.ztsh.wymiana.validation.InstanceValidator;
@ -49,7 +50,7 @@ public class CurrencyService {
user.currencies().putAll(exchanged);
return userService.update(user);
})
.orElseThrow(ExchangeFailedException::new);
.orElseThrow(() -> new UserNotFoundException(request));
}
private Currency create(String symbol) {

View file

@ -9,9 +9,11 @@ import eu.ztsh.wymiana.web.model.UserCreateRequest;
import lombok.RequiredArgsConstructor;
import org.hibernate.validator.constraints.pl.PESEL;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.util.Optional;
@Validated
@RequiredArgsConstructor
@Service
public class UserService {

View file

@ -0,0 +1,42 @@
package eu.ztsh.wymiana.web.controller;
import eu.ztsh.wymiana.exception.InsufficientFundsException;
import eu.ztsh.wymiana.exception.UserAlreadyExistsException;
import eu.ztsh.wymiana.exception.UserNotFoundException;
import eu.ztsh.wymiana.service.CurrencyService;
import eu.ztsh.wymiana.validation.ValidationFailedException;
import eu.ztsh.wymiana.web.model.CurrencyExchangeRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequiredArgsConstructor
@Validated
@RestController
@RequestMapping(path = "/api/exchange", produces = "application/json")
public class ExchangeController {
private final CurrencyService currencyService;
@PostMapping
public ResponseEntity<Object> exchange(@Valid @RequestBody CurrencyExchangeRequest request) {
try {
return ResponseEntity.status(200).body(currencyService.exchange(request));
} catch (Exception e) {
var status = switch (e) {
case InsufficientFundsException ignored -> HttpStatus.BAD_REQUEST;
case UserNotFoundException ignored -> HttpStatus.NOT_FOUND;
default -> HttpStatus.INTERNAL_SERVER_ERROR;
};
return ResponseEntity.status(status).body(e.getMessage());
}
}
}

View file

@ -6,6 +6,7 @@ import eu.ztsh.wymiana.service.UserService;
import eu.ztsh.wymiana.validation.ValidationFailedException;
import eu.ztsh.wymiana.web.model.UserCreateRequest;
import jakarta.validation.Valid;
import jakarta.validation.ValidationException;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@ -27,7 +28,13 @@ public class UserController {
@GetMapping("{pesel}")
public ResponseEntity<User> get(@PathVariable("pesel") String pesel) {
return ResponseEntity.of(userService.get(pesel));
try {
return userService.get(pesel)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
} catch (ValidationException e) {
return ResponseEntity.badRequest().build();
}
}
@PostMapping