From f88e4f78b6a773467bb69a664869f705b1d58ea1 Mon Sep 17 00:00:00 2001 From: Tizian Date: Thu, 24 Feb 2022 14:33:56 +0100 Subject: [PATCH] Code cleanup (#46) * Changed Put and Post mapping * Added Tests * Added Tests * Cleanup * PR fixes * Added login integration test * Removed Log * Fixed Test * Added constants * ID to Id * Added constants * Cleanup * Remove payment series when category is being deleted * Cleanup * Changed hover color Co-authored-by: Tizian --- backend/pom.xml | 8 +- .../controller/CategoryController.java | 28 ++++--- .../backend/controller/LoginController.java | 4 +- .../backend/controller/PaymentController.java | 28 +++---- .../CategoryAlreadyExistException.java | 4 + .../SeriesAlreadyExistException.java | 2 +- .../SeriesDoesNotExistException.java | 11 +++ .../redstylzz/backend/model/Category.java | 4 +- .../redstylzz/backend/model/Payment.java | 24 +++--- .../backend/model/dto/CategoryDTO.java | 4 +- ...{CategoryIDDTO.java => CategoryIdDTO.java} | 4 +- .../model/dto/CategoryPaymentInputDTO.java | 4 +- .../backend/model/dto/PaymentDTO.java | 4 +- .../backend/model/dto/RequestPaymentDTO.java | 2 +- .../repository/ICategoryRepository.java | 10 +-- .../repository/IMongoUserRepository.java | 2 - .../repository/IPaymentRepository.java | 15 ++-- .../repository/IPaymentSeriesRepository.java | 2 + .../backend/service/CategoryService.java | 43 +++++----- .../backend/service/DepositService.java | 6 +- .../backend/service/LoginService.java | 2 +- .../backend/service/MongoUserService.java | 10 ++- .../backend/service/PaymentSeriesService.java | 15 +++- .../backend/service/PaymentService.java | 57 +++++++------- .../backend/service/UserService.java | 10 ++- .../controller/LoginControllerTest.java | 77 ++++++++++++++++++ .../backend/model/TestDataProvider.java | 26 +++---- .../backend/service/CategoryServiceTest.java | 45 ++++------- .../backend/service/JWTServiceTest.java | 2 +- .../backend/service/PaymentServiceTest.java | 78 +++++++++---------- frontend/src/App.tsx | 4 +- frontend/src/components/PieChart.tsx | 2 +- .../components/categories/CategoryItem.tsx | 12 +-- .../categories/HomeCategoryItem.tsx | 2 +- .../src/components/payments/PaymentItem.tsx | 12 +-- frontend/src/components/payments/Payments.tsx | 16 ++-- .../src/controllers/CategoryController.ts | 4 +- frontend/src/controllers/PaymentController.ts | 8 +- frontend/src/models/Category.ts | 6 +- frontend/src/models/Payment.ts | 12 +-- frontend/src/pages/CategoryPage.tsx | 6 +- frontend/src/pages/ChangePaymentPage.tsx | 14 ++-- frontend/src/pages/RenameCategoryPage.tsx | 6 +- frontend/src/pages/SchedulePage.tsx | 8 +- frontend/src/services/CategoryService.ts | 4 +- frontend/src/services/PaymentService.ts | 12 +-- 46 files changed, 380 insertions(+), 279 deletions(-) create mode 100644 backend/src/main/java/com/github/redstylzz/backend/exception/SeriesDoesNotExistException.java rename backend/src/main/java/com/github/redstylzz/backend/model/dto/{CategoryIDDTO.java => CategoryIdDTO.java} (77%) create mode 100644 backend/src/test/java/com/github/redstylzz/backend/controller/LoginControllerTest.java diff --git a/backend/pom.xml b/backend/pom.xml index 473ab4e..74250d3 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -17,6 +17,10 @@ 17 + + org.springframework.boot + spring-boot-starter-webflux + org.springframework.boot spring-boot-starter-data-mongodb @@ -69,12 +73,12 @@ org.springdoc springdoc-openapi-ui - 1.6.4 + 1.6.6 org.mockito mockito-inline - 4.2.0 + 4.3.1 test diff --git a/backend/src/main/java/com/github/redstylzz/backend/controller/CategoryController.java b/backend/src/main/java/com/github/redstylzz/backend/controller/CategoryController.java index afe992f..446a0b3 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/controller/CategoryController.java +++ b/backend/src/main/java/com/github/redstylzz/backend/controller/CategoryController.java @@ -21,6 +21,8 @@ @RequiredArgsConstructor public class CategoryController { private static final Log LOG = LogFactory.getLog(CategoryController.class); + private static final String ID_NOT_GIVEN = "Id is not given"; + private static final String NAME_NOT_GIVEN = "Name is not given"; private final CategoryService service; private final MongoUserService userService; @@ -43,8 +45,8 @@ public List getCategories(UsernamePasswordAuthenticationToken princ public List addCategory(UsernamePasswordAuthenticationToken principal, @RequestBody CategoryNameDTO dto) throws ResponseStatusException { String name = dto.getCategoryName(); if (name == null || name.isBlank()) { - LOG.warn("Name is null or blank"); - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "No name given"); + LOG.warn(NAME_NOT_GIVEN); + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, NAME_NOT_GIVEN); } MongoUser user = getUser(principal); @@ -57,25 +59,29 @@ public List addCategory(UsernamePasswordAuthenticationToken princip @PatchMapping public List renameCategory(UsernamePasswordAuthenticationToken principal, @RequestBody CategoryDTO dto) throws ResponseStatusException { - String id = dto.getCategoryID(); + String id = dto.getCategoryId(); String name = dto.getCategoryName(); - if ((id == null || id.isBlank()) || (name == null || name.isBlank())) { - LOG.warn("ID or name is null or blank"); - throw new ResponseStatusException(HttpStatus.BAD_REQUEST); + if (id == null || id.isBlank()) { + LOG.warn(ID_NOT_GIVEN); + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, ID_NOT_GIVEN); + } + if (name == null || name.isBlank()) { + LOG.warn(NAME_NOT_GIVEN); + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, NAME_NOT_GIVEN); } MongoUser user = userService.getUserByPrincipal(principal); return service.renameCategory(user, id, name); } @DeleteMapping - public List deleteCategory(UsernamePasswordAuthenticationToken principal, @RequestParam String categoryID) throws ResponseStatusException { - if (categoryID == null || categoryID.isBlank()) { - LOG.warn("ID is null or blank"); - throw new ResponseStatusException(HttpStatus.BAD_REQUEST); + public List deleteCategory(UsernamePasswordAuthenticationToken principal, @RequestParam String categoryId) throws ResponseStatusException { + if (categoryId == null || categoryId.isBlank()) { + LOG.warn(ID_NOT_GIVEN); + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, ID_NOT_GIVEN); } MongoUser user = userService.getUserByPrincipal(principal); - return service.deleteCategory(user, categoryID); + return service.deleteCategory(user, categoryId); } diff --git a/backend/src/main/java/com/github/redstylzz/backend/controller/LoginController.java b/backend/src/main/java/com/github/redstylzz/backend/controller/LoginController.java index 389f84d..745dc49 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/controller/LoginController.java +++ b/backend/src/main/java/com/github/redstylzz/backend/controller/LoginController.java @@ -6,10 +6,12 @@ import lombok.RequiredArgsConstructor; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; +import org.springframework.http.HttpStatus; 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; +import org.springframework.web.server.ResponseStatusException; @RestController @RequestMapping("auth/login") @@ -26,8 +28,8 @@ public String login(@RequestBody LoginDTO dto) { return service.login(mongoUser); } catch (Exception e) { LOG.error("Failed to login user", e); + throw new ResponseStatusException(HttpStatus.FORBIDDEN, "Wrong Credentials"); } - return null; } diff --git a/backend/src/main/java/com/github/redstylzz/backend/controller/PaymentController.java b/backend/src/main/java/com/github/redstylzz/backend/controller/PaymentController.java index 3163903..724fde1 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/controller/PaymentController.java +++ b/backend/src/main/java/com/github/redstylzz/backend/controller/PaymentController.java @@ -38,17 +38,17 @@ private List getPaymentsAsDTO(List payments) { @GetMapping("/") public PaymentDTO getPayment(UsernamePasswordAuthenticationToken principal, - @RequestParam String categoryID, - @RequestParam String paymentID) { + @RequestParam String categoryId, + @RequestParam String paymentId) { MongoUser user = getUser(principal); - return Payment.convertPaymentToDTO(service.getPayment(user.getId(), categoryID, paymentID)); + return Payment.convertPaymentToDTO(service.getPayment(user.getId(), categoryId, paymentId)); } - @GetMapping("{categoryID}") + @GetMapping("{categoryId}") public List getPayments(UsernamePasswordAuthenticationToken principal, - @PathVariable String categoryID) { + @PathVariable String categoryId) { MongoUser user = getUser(principal); - return getPaymentsAsDTO(service.getPayments(user.getId(), categoryID)); + return getPaymentsAsDTO(service.getPayments(user.getId(), categoryId)); } @GetMapping @@ -60,25 +60,25 @@ public List getLastPayments(UsernamePasswordAuthenticationToken prin @PostMapping public List addPayment(UsernamePasswordAuthenticationToken principal, @RequestBody RequestPaymentDTO dto) { - String userID = getUser(principal).getId(); + String userId = getUser(principal).getId(); Payment payment = Payment.convertDTOtoPayment(dto); - return getPaymentsAsDTO(service.addPayment(userID, payment)); + return getPaymentsAsDTO(service.addPayment(userId, payment)); } @DeleteMapping public List deletePayment(UsernamePasswordAuthenticationToken principal, - @RequestParam String categoryID, - @RequestParam String paymentID) { - String userID = getUser(principal).getId(); - return getPaymentsAsDTO(service.deletePayment(userID, categoryID, paymentID)); + @RequestParam String categoryId, + @RequestParam String paymentId) { + String userId = getUser(principal).getId(); + return getPaymentsAsDTO(service.deletePayment(userId, categoryId, paymentId)); } @PutMapping public List changePayment(UsernamePasswordAuthenticationToken principal, @RequestBody PaymentDTO dto) { - String userID = getUser(principal).getId(); + String userId = getUser(principal).getId(); Payment payment = Payment.convertDTOtoPayment(dto); - return getPaymentsAsDTO(service.changePayment(userID, payment)); + return getPaymentsAsDTO(service.changePayment(userId, payment)); } } diff --git a/backend/src/main/java/com/github/redstylzz/backend/exception/CategoryAlreadyExistException.java b/backend/src/main/java/com/github/redstylzz/backend/exception/CategoryAlreadyExistException.java index 1489aaf..cdc6107 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/exception/CategoryAlreadyExistException.java +++ b/backend/src/main/java/com/github/redstylzz/backend/exception/CategoryAlreadyExistException.java @@ -4,4 +4,8 @@ public class CategoryAlreadyExistException extends RuntimeException { public CategoryAlreadyExistException(String message) { super(message); } + + public CategoryAlreadyExistException() { + super("A category with this name already exists"); + } } diff --git a/backend/src/main/java/com/github/redstylzz/backend/exception/SeriesAlreadyExistException.java b/backend/src/main/java/com/github/redstylzz/backend/exception/SeriesAlreadyExistException.java index 6ee77aa..f955cd4 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/exception/SeriesAlreadyExistException.java +++ b/backend/src/main/java/com/github/redstylzz/backend/exception/SeriesAlreadyExistException.java @@ -6,6 +6,6 @@ public SeriesAlreadyExistException(String message) { } public SeriesAlreadyExistException() { - super(); + super("Series already existent"); } } diff --git a/backend/src/main/java/com/github/redstylzz/backend/exception/SeriesDoesNotExistException.java b/backend/src/main/java/com/github/redstylzz/backend/exception/SeriesDoesNotExistException.java new file mode 100644 index 0000000..e2e97e0 --- /dev/null +++ b/backend/src/main/java/com/github/redstylzz/backend/exception/SeriesDoesNotExistException.java @@ -0,0 +1,11 @@ +package com.github.redstylzz.backend.exception; + +public class SeriesDoesNotExistException extends RuntimeException { + public SeriesDoesNotExistException(String message) { + super(message); + } + + public SeriesDoesNotExistException() { + super("Series does not exist"); + } +} diff --git a/backend/src/main/java/com/github/redstylzz/backend/model/Category.java b/backend/src/main/java/com/github/redstylzz/backend/model/Category.java index 866700d..28b2d7c 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/model/Category.java +++ b/backend/src/main/java/com/github/redstylzz/backend/model/Category.java @@ -17,9 +17,9 @@ public class Category { @Id - String categoryID; + String categoryId; - String userID; + String userId; String categoryName; LocalDateTime saveDate; } diff --git a/backend/src/main/java/com/github/redstylzz/backend/model/Payment.java b/backend/src/main/java/com/github/redstylzz/backend/model/Payment.java index 6c58ff8..82132fd 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/model/Payment.java +++ b/backend/src/main/java/com/github/redstylzz/backend/model/Payment.java @@ -23,10 +23,10 @@ public class Payment { @Id - String paymentID; + String paymentId; - String userID; - String categoryID; + String userId; + String categoryId; String description; BigDecimal amount; Instant saveDate; @@ -34,8 +34,8 @@ public class Payment { public static Payment convertDTOtoPayment(PaymentDTO dto) { return Payment.builder() - .paymentID(dto.getPaymentID()) - .categoryID(dto.getCategoryID()) + .paymentId(dto.getPaymentId()) + .categoryId(dto.getCategoryId()) .description(dto.getDescription()) .amount(dto.getAmount()) .payDate(dto.getPayDate().toInstant(ZoneOffset.UTC)) @@ -44,7 +44,7 @@ public static Payment convertDTOtoPayment(PaymentDTO dto) { public static Payment convertDTOtoPayment(RequestPaymentDTO dto) { return Payment.builder() - .categoryID(dto.getCategoryID()) + .categoryId(dto.getCategoryId()) .description(dto.getDescription()) .amount(dto.getAmount()) .payDate(dto.getPayDate().toInstant(ZoneOffset.UTC)) @@ -53,8 +53,8 @@ public static Payment convertDTOtoPayment(RequestPaymentDTO dto) { public static Payment convertDTOtoPayment(PaymentDTO dto, String userId) { return Payment.builder() - .userID(userId) - .categoryID(dto.getCategoryID()) + .userId(userId) + .categoryId(dto.getCategoryId()) .description(dto.getDescription()) .amount(dto.getAmount()) .payDate(dto.getPayDate().toInstant(ZoneOffset.UTC)) @@ -63,8 +63,8 @@ public static Payment convertDTOtoPayment(PaymentDTO dto, String userId) { public static Payment convertDTOtoPayment(PaymentDTO dto, String userId, Instant payDate) { return Payment.builder() - .userID(userId) - .categoryID(dto.getCategoryID()) + .userId(userId) + .categoryId(dto.getCategoryId()) .description(dto.getDescription()) .amount(dto.getAmount()) .payDate(payDate) @@ -73,8 +73,8 @@ public static Payment convertDTOtoPayment(PaymentDTO dto, String userId, Instant public static PaymentDTO convertPaymentToDTO(Payment payment) { return PaymentDTO.builder() - .paymentID(payment.paymentID) - .categoryID(payment.categoryID) + .paymentId(payment.paymentId) + .categoryId(payment.categoryId) .description(payment.description) .amount(payment.amount) .payDate(LocalDateTime.from(payment.payDate.atZone(ZoneId.of("GMT+1")))) diff --git a/backend/src/main/java/com/github/redstylzz/backend/model/dto/CategoryDTO.java b/backend/src/main/java/com/github/redstylzz/backend/model/dto/CategoryDTO.java index 348a26b..897570e 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/model/dto/CategoryDTO.java +++ b/backend/src/main/java/com/github/redstylzz/backend/model/dto/CategoryDTO.java @@ -15,13 +15,13 @@ @Builder public class CategoryDTO { String categoryName; - String categoryID; + String categoryId; BigDecimal paymentSum; @Transient public static CategoryDTO mapCategoryToDTO(Category category) { return CategoryDTO.builder() - .categoryID(category.getCategoryID()) + .categoryId(category.getCategoryId()) .categoryName(category.getCategoryName()) .build(); } diff --git a/backend/src/main/java/com/github/redstylzz/backend/model/dto/CategoryIDDTO.java b/backend/src/main/java/com/github/redstylzz/backend/model/dto/CategoryIdDTO.java similarity index 77% rename from backend/src/main/java/com/github/redstylzz/backend/model/dto/CategoryIDDTO.java rename to backend/src/main/java/com/github/redstylzz/backend/model/dto/CategoryIdDTO.java index 562b20a..80bd091 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/model/dto/CategoryIDDTO.java +++ b/backend/src/main/java/com/github/redstylzz/backend/model/dto/CategoryIdDTO.java @@ -7,6 +7,6 @@ @Data @NoArgsConstructor @AllArgsConstructor -public class CategoryIDDTO { - String categoryID; +public class CategoryIdDTO { + String categoryId; } diff --git a/backend/src/main/java/com/github/redstylzz/backend/model/dto/CategoryPaymentInputDTO.java b/backend/src/main/java/com/github/redstylzz/backend/model/dto/CategoryPaymentInputDTO.java index f50e3d4..4ed897b 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/model/dto/CategoryPaymentInputDTO.java +++ b/backend/src/main/java/com/github/redstylzz/backend/model/dto/CategoryPaymentInputDTO.java @@ -8,6 +8,6 @@ @NoArgsConstructor @AllArgsConstructor public class CategoryPaymentInputDTO { - String categoryID; - String paymentID; + String categoryId; + String paymentId; } diff --git a/backend/src/main/java/com/github/redstylzz/backend/model/dto/PaymentDTO.java b/backend/src/main/java/com/github/redstylzz/backend/model/dto/PaymentDTO.java index 38df66f..fc799b3 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/model/dto/PaymentDTO.java +++ b/backend/src/main/java/com/github/redstylzz/backend/model/dto/PaymentDTO.java @@ -14,8 +14,8 @@ @Builder public class PaymentDTO { - String paymentID; - String categoryID; + String paymentId; + String categoryId; String description; BigDecimal amount; LocalDateTime payDate; diff --git a/backend/src/main/java/com/github/redstylzz/backend/model/dto/RequestPaymentDTO.java b/backend/src/main/java/com/github/redstylzz/backend/model/dto/RequestPaymentDTO.java index 2395681..d8c2fa9 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/model/dto/RequestPaymentDTO.java +++ b/backend/src/main/java/com/github/redstylzz/backend/model/dto/RequestPaymentDTO.java @@ -11,7 +11,7 @@ @Builder public class RequestPaymentDTO { - @NonNull String categoryID; + @NonNull String categoryId; @NonNull String description; @NonNull BigDecimal amount; @NonNull LocalDateTime payDate; diff --git a/backend/src/main/java/com/github/redstylzz/backend/repository/ICategoryRepository.java b/backend/src/main/java/com/github/redstylzz/backend/repository/ICategoryRepository.java index 83fd591..c6acc68 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/repository/ICategoryRepository.java +++ b/backend/src/main/java/com/github/redstylzz/backend/repository/ICategoryRepository.java @@ -9,14 +9,14 @@ @Repository public interface ICategoryRepository extends MongoRepository { - List findAllByUserID(String userID); + List findAllByUserId(String userId); - Category findByUserIDAndCategoryID(String userID, String categoryID); + Category findByUserIdAndCategoryId(String userId, String categoryId); - void deleteByCategoryID(String categoryID); + void deleteByCategoryId(String categoryId); - boolean existsByUserIDAndCategoryName(String userID, String categoryName); + boolean existsByUserIdAndCategoryName(String userId, String categoryName); - boolean existsByUserIDAndCategoryID(String userID, String categoryID); + boolean existsByUserIdAndCategoryId(String userId, String categoryId); } diff --git a/backend/src/main/java/com/github/redstylzz/backend/repository/IMongoUserRepository.java b/backend/src/main/java/com/github/redstylzz/backend/repository/IMongoUserRepository.java index 802fe6a..9f2d173 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/repository/IMongoUserRepository.java +++ b/backend/src/main/java/com/github/redstylzz/backend/repository/IMongoUserRepository.java @@ -8,6 +8,4 @@ @Repository public interface IMongoUserRepository extends MongoRepository { MongoUser findMongoUserByUsername(String username) throws UsernameNotFoundException; - - MongoUser findMongoUserById(String id); } diff --git a/backend/src/main/java/com/github/redstylzz/backend/repository/IPaymentRepository.java b/backend/src/main/java/com/github/redstylzz/backend/repository/IPaymentRepository.java index d379562..94bc5dc 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/repository/IPaymentRepository.java +++ b/backend/src/main/java/com/github/redstylzz/backend/repository/IPaymentRepository.java @@ -4,23 +4,22 @@ import org.springframework.data.mongodb.repository.MongoRepository; import java.time.Instant; -import java.time.LocalDateTime; import java.util.List; public interface IPaymentRepository extends MongoRepository { - List getAllByUserIDAndCategoryIDOrderByPayDateDesc(String userID, String categoryID); + List getAllByUserIdAndCategoryIdOrderByPayDateDesc(String userId, String categoryId); - List getAllByUserIDAndPayDateAfterOrderByPayDateDesc(String userID, Instant date); + List getAllByUserIdAndPayDateAfterOrderByPayDateDesc(String userId, Instant date); - List getAllByUserIDAndCategoryIDAndPayDateAfterOrderByPayDateDesc(String userID, String categoryID, LocalDateTime date); + List getAllByUserIdAndCategoryIdAndPayDateAfterOrderByPayDateDesc(String userId, String categoryId, Instant date); - Payment getByUserIDAndCategoryIDAndPaymentID(String userID, String categoryID, String paymentID); + Payment getByUserIdAndCategoryIdAndPaymentId(String userId, String categoryId, String paymentId); - boolean existsByPaymentID(String paymentID); + boolean existsByPaymentId(String paymentId); - void deleteByPaymentID(String paymentID); + void deleteByPaymentId(String paymentId); - void deleteAllByUserIDAndCategoryID(String userID, String categoryID); + void deleteAllByUserIdAndCategoryId(String userId, String categoryId); } diff --git a/backend/src/main/java/com/github/redstylzz/backend/repository/IPaymentSeriesRepository.java b/backend/src/main/java/com/github/redstylzz/backend/repository/IPaymentSeriesRepository.java index ba09bea..3313df9 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/repository/IPaymentSeriesRepository.java +++ b/backend/src/main/java/com/github/redstylzz/backend/repository/IPaymentSeriesRepository.java @@ -17,6 +17,8 @@ public interface IPaymentSeriesRepository extends MongoRepository getAllCategoriesAsDTO(String userID) { - List dto = categoryRepository.findAllByUserID(userID) + private List getAllCategoriesAsDTO(String userId) { + List dto = categoryRepository.findAllByUserId(userId) .stream() .map(CategoryDTO::mapCategoryToDTO) .toList(); - dto.forEach(categoryDTO -> categoryDTO.setPaymentSum(paymentService.calculatePaymentSum(userID, categoryDTO.getCategoryID()))); + dto.forEach(categoryDTO -> categoryDTO.setPaymentSum(paymentService.calculatePaymentSum(userId, categoryDTO.getCategoryId()))); return dto; } @@ -41,48 +44,48 @@ public List getCategories(MongoUser user) { public List addCategory(MongoUser user, String categoryName) throws CategoryAlreadyExistException { LOG.info("Adding category"); - if (!categoryRepository.existsByUserIDAndCategoryName(user.getId(), categoryName)) { + if (!categoryRepository.existsByUserIdAndCategoryName(user.getId(), categoryName)) { Category category = Category.builder() - .userID(user.getId()) + .userId(user.getId()) .categoryName(categoryName) .saveDate(LocalDateTime.now()) .build(); categoryRepository.save(category); LOG.info("Added category"); } else { - LOG.warn("Category already existent"); - throw new CategoryAlreadyExistException("A category with this name already exists"); + LOG.warn(CATEGORY_ALREADY_EXISTS); + throw new CategoryAlreadyExistException(); } return getAllCategoriesAsDTO(user.getId()); } - public List renameCategory(MongoUser user, String categoryID, String name) throws CategoryAlreadyExistException, CategoryDoesNotExistException { + public List renameCategory(MongoUser user, String categoryId, String name) throws CategoryAlreadyExistException, CategoryDoesNotExistException { LOG.info("Renaming category"); - Category category = categoryRepository.findByUserIDAndCategoryID(user.getId(), categoryID); + Category category = categoryRepository.findByUserIdAndCategoryId(user.getId(), categoryId); if (category != null) { - if (!categoryRepository.existsByUserIDAndCategoryName(user.getId(), name)) { + if (!categoryRepository.existsByUserIdAndCategoryName(user.getId(), name)) { category.setCategoryName(name); category.setSaveDate(LocalDateTime.now()); categoryRepository.save(category); - LOG.info("Renamed category with ID"); + LOG.info("Successfully Renamed category"); } else { - LOG.warn("A category with this name already exists"); - throw new CategoryAlreadyExistException("A category with this name already exists"); + LOG.warn(CATEGORY_ALREADY_EXISTS); + throw new CategoryAlreadyExistException(); } } else { - LOG.warn("Category does not exist"); - throw new CategoryDoesNotExistException("No category with this ID"); + LOG.warn(CATEGORY_DOES_NOT_EXISTS); + throw new CategoryDoesNotExistException(CATEGORY_DOES_NOT_EXISTS); } return getAllCategoriesAsDTO(user.getId()); } - public List deleteCategory(MongoUser user, String categoryID) { + public List deleteCategory(MongoUser user, String categoryId) { LOG.debug("Deleting category"); - categoryRepository.deleteByCategoryID(categoryID); - paymentRepo.deleteAllByUserIDAndCategoryID(user.getId(), categoryID); + categoryRepository.deleteByCategoryId(categoryId); + paymentRepo.deleteAllByUserIdAndCategoryId(user.getId(), categoryId); + paymentSeriesRepository.deleteAllByUserIdAndPayment_CategoryId(user.getId(), categoryId); return getAllCategoriesAsDTO(user.getId()); } - } diff --git a/backend/src/main/java/com/github/redstylzz/backend/service/DepositService.java b/backend/src/main/java/com/github/redstylzz/backend/service/DepositService.java index 96bfcec..b3f2a88 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/service/DepositService.java +++ b/backend/src/main/java/com/github/redstylzz/backend/service/DepositService.java @@ -19,7 +19,7 @@ @RequiredArgsConstructor public class DepositService { private static final Log LOG = LogFactory.getLog(DepositService.class); - + private static final String INVALID_DEPOSIT = "Description, Amount or DepositDate is not given"; private final IDepositRepository repository; private boolean isValidDeposit(Deposit deposit) { @@ -50,7 +50,7 @@ public List addDeposit(String userId, Deposit deposit) { deposit.setSaveDate(Instant.now()); repository.save(deposit); } else { - throw new NullPointerException("Some data is null"); + throw new NullPointerException(INVALID_DEPOSIT); } } else { throw new DepositAlreadyExistException("ID already existent"); @@ -68,7 +68,7 @@ public List changeDeposit(String userId, Deposit deposit) { repository.save(deposit); return getDepositsFrom(userId); } else { - throw new NullPointerException("Description, Amount or DepositDate is null"); + throw new NullPointerException(INVALID_DEPOSIT); } } else { throw new DepositDoesNotExistException("Deposit does not exist"); diff --git a/backend/src/main/java/com/github/redstylzz/backend/service/LoginService.java b/backend/src/main/java/com/github/redstylzz/backend/service/LoginService.java index 2e265b8..c1b479e 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/service/LoginService.java +++ b/backend/src/main/java/com/github/redstylzz/backend/service/LoginService.java @@ -27,7 +27,7 @@ public String login(MongoUser user) { LOG.info("Successfully logged in user"); return jwtService.createToken(user); } catch (AuthenticationException e) { - LOG.warn("Login invalid credentials: " + e.getMessage()); + LOG.warn("Invalid login credentials: " + e.getMessage()); throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid credentials"); } } diff --git a/backend/src/main/java/com/github/redstylzz/backend/service/MongoUserService.java b/backend/src/main/java/com/github/redstylzz/backend/service/MongoUserService.java index df02e96..f1e6d71 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/service/MongoUserService.java +++ b/backend/src/main/java/com/github/redstylzz/backend/service/MongoUserService.java @@ -13,6 +13,8 @@ @Service public class MongoUserService implements UserDetailsService { public static final String ROLE_ADMIN = "ADMIN"; + public static final String USER_NOT_FOUND = "User not found"; + public static final String PRINCIPAL_IS_NULL = "Principal is null"; private static final Log LOG = LogFactory.getLog(MongoUserService.class); private final IMongoUserRepository repository; @@ -25,8 +27,8 @@ public MongoUserService(IMongoUserRepository repository) { public MongoUser loadUserByUsername(String username) throws UsernameNotFoundException { MongoUser user = repository.findMongoUserByUsername(username); if (user == null) { - LOG.warn("Could not find user"); - throw new UsernameNotFoundException("User not found"); + LOG.warn(USER_NOT_FOUND); + throw new UsernameNotFoundException(USER_NOT_FOUND); } return user; } @@ -35,7 +37,7 @@ public MongoUser getUserByPrincipal(Principal principal) throws UsernameNotFound if (principal != null) { return loadUserByUsername(principal.getName()); } - LOG.warn("Principal is null"); - throw new UsernameNotFoundException("Principal is null"); + LOG.warn(PRINCIPAL_IS_NULL); + throw new UsernameNotFoundException(PRINCIPAL_IS_NULL); } } diff --git a/backend/src/main/java/com/github/redstylzz/backend/service/PaymentSeriesService.java b/backend/src/main/java/com/github/redstylzz/backend/service/PaymentSeriesService.java index 9c5886a..af4cb4a 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/service/PaymentSeriesService.java +++ b/backend/src/main/java/com/github/redstylzz/backend/service/PaymentSeriesService.java @@ -1,6 +1,7 @@ package com.github.redstylzz.backend.service; import com.github.redstylzz.backend.exception.SeriesAlreadyExistException; +import com.github.redstylzz.backend.exception.SeriesDoesNotExistException; import com.github.redstylzz.backend.model.PaymentSeries; import com.github.redstylzz.backend.model.dto.PaymentSeriesDTO; import com.github.redstylzz.backend.repository.IPaymentSeriesRepository; @@ -15,7 +16,8 @@ @RequiredArgsConstructor public class PaymentSeriesService { private static final Log LOG = LogFactory.getLog(PaymentSeriesService.class); - + private static final String SERIES_DOES_NOT_EXIST = "Series does not exist"; + private static final String SERIES_ALREADY_EXIST = "Series already exist"; private final IPaymentSeriesRepository repository; public List getSeries(String userId) { @@ -29,10 +31,10 @@ public List addSeries(String userId, PaymentSeriesDTO dto) { if (series.getSeriesId() == null || !repository.existsBySeriesId(series.getSeriesId())) { repository.save(series); } else { - LOG.warn("Series already existent"); - throw new SeriesAlreadyExistException("Series already exists"); + LOG.warn(SERIES_ALREADY_EXIST); + throw new SeriesAlreadyExistException(); } - + LOG.info("Successfully added series"); return getSeries(userId); } @@ -43,10 +45,15 @@ public List deleteSeries(String userId, String seriesId) { } public List changeSeries(String userId, PaymentSeriesDTO dto) { + LOG.info("Changing series"); if (repository.existsByUserIdAndSeriesId(userId, dto.getSeriesId())) { PaymentSeries series = PaymentSeries.mapDTOtoSeries(dto, userId); repository.save(series); + } else { + LOG.warn(SERIES_DOES_NOT_EXIST); + throw new SeriesDoesNotExistException(); } + LOG.info("Successfully changed series"); return getSeries(userId); } diff --git a/backend/src/main/java/com/github/redstylzz/backend/service/PaymentService.java b/backend/src/main/java/com/github/redstylzz/backend/service/PaymentService.java index fda99b1..68c2298 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/service/PaymentService.java +++ b/backend/src/main/java/com/github/redstylzz/backend/service/PaymentService.java @@ -14,6 +14,7 @@ import java.time.Duration; import java.time.Instant; import java.time.LocalDateTime; +import java.time.ZoneOffset; import java.util.List; @Service @@ -24,73 +25,73 @@ public class PaymentService { private final IPaymentRepository paymentRepository; private final ICategoryRepository categoryRepository; - private boolean categoryExistent(String userID, String categoryID) { - return categoryRepository.existsByUserIDAndCategoryID(userID, categoryID); + private boolean categoryExistent(String userId, String categoryId) { + return categoryRepository.existsByUserIdAndCategoryId(userId, categoryId); } - private boolean paymentExists(String paymentID) { - return paymentRepository.existsByPaymentID(paymentID); + private boolean paymentExists(String paymentId) { + return paymentRepository.existsByPaymentId(paymentId); } - public BigDecimal calculatePaymentSum(String userID, String categoryID) { + public BigDecimal calculatePaymentSum(String userId, String categoryId) { List payments = paymentRepository - .getAllByUserIDAndCategoryIDAndPayDateAfterOrderByPayDateDesc(userID, categoryID, LocalDateTime.now().withDayOfMonth(1).minus(Duration.ofDays(1))); + .getAllByUserIdAndCategoryIdAndPayDateAfterOrderByPayDateDesc(userId, categoryId, LocalDateTime.now().withDayOfMonth(1).minus(Duration.ofDays(1)).toInstant(ZoneOffset.UTC)); return payments.stream() .map(Payment::getAmount) .reduce(BigDecimal.ZERO, BigDecimal::add); } - public Payment getPayment(String userID, String categoryID, String paymentID) { + public Payment getPayment(String userId, String categoryId, String paymentId) { return paymentRepository - .getByUserIDAndCategoryIDAndPaymentID(userID, categoryID, paymentID); + .getByUserIdAndCategoryIdAndPaymentId(userId, categoryId, paymentId); } - public List getPayments(String userID, String categoryID) { + public List getPayments(String userId, String categoryId) { return paymentRepository - .getAllByUserIDAndCategoryIDOrderByPayDateDesc(userID, categoryID); + .getAllByUserIdAndCategoryIdOrderByPayDateDesc(userId, categoryId); } - public List getLastPayments(String userID) { + public List getLastPayments(String userId) { return paymentRepository - .getAllByUserIDAndPayDateAfterOrderByPayDateDesc(userID, Instant.now().minus(Duration.ofDays(7))); + .getAllByUserIdAndPayDateAfterOrderByPayDateDesc(userId, Instant.now().minus(Duration.ofDays(7))); } - public List addPayment(String userID, Payment payment) throws CategoryDoesNotExistException { - if (categoryExistent(userID, payment.getCategoryID())) { + public List addPayment(String userId, Payment payment) throws CategoryDoesNotExistException { + if (categoryExistent(userId, payment.getCategoryId())) { LOG.debug(payment.getPayDate()); - payment.setUserID(userID); + payment.setUserId(userId); payment.setSaveDate(Instant.now()); paymentRepository.save(payment); - calculatePaymentSum(userID, payment.getCategoryID()); + calculatePaymentSum(userId, payment.getCategoryId()); } else { throw new CategoryDoesNotExistException(); } - return getPayments(userID, payment.getCategoryID()); + return getPayments(userId, payment.getCategoryId()); } - public List deletePayment(String userID, String categoryID, String paymentID) throws PaymentDoesNotExistException, CategoryDoesNotExistException { - if (categoryExistent(userID, categoryID)) { - paymentRepository.deleteByPaymentID(paymentID); - calculatePaymentSum(userID, categoryID); + public List deletePayment(String userId, String categoryId, String paymentId) throws PaymentDoesNotExistException, CategoryDoesNotExistException { + if (categoryExistent(userId, categoryId)) { + paymentRepository.deleteByPaymentId(paymentId); + calculatePaymentSum(userId, categoryId); } else { throw new CategoryDoesNotExistException(); } - return getPayments(userID, categoryID); + return getPayments(userId, categoryId); } - public List changePayment(String userID, Payment payment) throws PaymentDoesNotExistException, CategoryDoesNotExistException { - if (categoryExistent(userID, payment.getCategoryID())) { - if (paymentExists(payment.getPaymentID())) { - payment.setUserID(userID); + public List changePayment(String userId, Payment payment) throws PaymentDoesNotExistException, CategoryDoesNotExistException { + if (categoryExistent(userId, payment.getCategoryId())) { + if (paymentExists(payment.getPaymentId())) { + payment.setUserId(userId); payment.setSaveDate(Instant.now()); paymentRepository.save(payment); - calculatePaymentSum(userID, payment.getCategoryID()); + calculatePaymentSum(userId, payment.getCategoryId()); } else { throw new PaymentDoesNotExistException(); } } else { throw new CategoryDoesNotExistException(); } - return getPayments(userID, payment.getCategoryID()); + return getPayments(userId, payment.getCategoryId()); } } diff --git a/backend/src/main/java/com/github/redstylzz/backend/service/UserService.java b/backend/src/main/java/com/github/redstylzz/backend/service/UserService.java index 1c6eff6..b664160 100644 --- a/backend/src/main/java/com/github/redstylzz/backend/service/UserService.java +++ b/backend/src/main/java/com/github/redstylzz/backend/service/UserService.java @@ -18,6 +18,8 @@ @RequiredArgsConstructor public class UserService { private static final Log LOG = LogFactory.getLog(UserService.class); + private static final String USER_ALREADY_EXISTS = "User already exists"; + private static final String NOT_ADMIN = "User is not Admin"; private final IMongoUserRepository repository; private final JWTService jwtService; @@ -42,10 +44,10 @@ public String addUser(MongoUser admin, MongoUserDTO user) throws ResponseStatusE LOG.info("Added new User"); return jwtService.createToken(newUser); } - LOG.warn("User already exists"); - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "User with this name already exists"); + LOG.warn(USER_ALREADY_EXISTS); + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, USER_ALREADY_EXISTS); } - LOG.warn("User does not have admin role"); - throw new ResponseStatusException(HttpStatus.FORBIDDEN, "Not admin"); + LOG.warn(NOT_ADMIN); + throw new ResponseStatusException(HttpStatus.FORBIDDEN, NOT_ADMIN); } } diff --git a/backend/src/test/java/com/github/redstylzz/backend/controller/LoginControllerTest.java b/backend/src/test/java/com/github/redstylzz/backend/controller/LoginControllerTest.java new file mode 100644 index 0000000..9424a89 --- /dev/null +++ b/backend/src/test/java/com/github/redstylzz/backend/controller/LoginControllerTest.java @@ -0,0 +1,77 @@ +package com.github.redstylzz.backend.controller; + +import com.github.redstylzz.backend.model.MongoUser; +import com.github.redstylzz.backend.model.dto.LoginDTO; +import com.github.redstylzz.backend.repository.IMongoUserRepository; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; + +import static com.github.redstylzz.backend.model.TestDataProvider.testUser; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +class LoginControllerTest { + + @LocalServerPort + private int port; + + @MockBean + private IMongoUserRepository mongoUserRepository; + + @Autowired + private PasswordEncoder passwordEncoder; + + private final WebClient webClient = WebClient.create(); + + @Test + void shouldReturnTokenOnSuccessfulLogin() { + MongoUser user = testUser(); + LoginDTO loginData = new LoginDTO(user.getUsername(), user.getPassword()); + user.setPassword(passwordEncoder.encode(user.getPassword())); + when(mongoUserRepository.findMongoUserByUsername("Test")).thenReturn(user); + + ResponseEntity login = webClient.post() + .uri("http://localhost:"+port+"/auth/login") + .contentType(MediaType.APPLICATION_JSON) + .bodyValue(loginData) + .retrieve() + .toEntity(String.class) + .block(); + + //THEN + assert login != null; + assertEquals(HttpStatus.OK, login.getStatusCode()); + } + + @Test + void shouldReturnBadRequestWithWrongCredentials() { + LoginDTO loginData = new LoginDTO("Test", "TestPassword"); + + ResponseEntity login = webClient.post() + .uri("http://localhost:"+port+"/auth/login") + .contentType(MediaType.APPLICATION_JSON) + .bodyValue(loginData) + .retrieve() + .onStatus(httpStatus -> httpStatus.equals(HttpStatus.FORBIDDEN), + clientResponse -> Mono.empty()) + .toEntity(String.class) + .block(); + + assert login != null; + assertEquals(HttpStatus.FORBIDDEN, login.getStatusCode()); + } + + +} \ No newline at end of file diff --git a/backend/src/test/java/com/github/redstylzz/backend/model/TestDataProvider.java b/backend/src/test/java/com/github/redstylzz/backend/model/TestDataProvider.java index d659fa1..92499ab 100644 --- a/backend/src/test/java/com/github/redstylzz/backend/model/TestDataProvider.java +++ b/backend/src/test/java/com/github/redstylzz/backend/model/TestDataProvider.java @@ -30,8 +30,8 @@ public static MongoUser testUser(String id, public static MongoUser testUser() { return testUser("24", - "Tizian", - "Turtle", + "Test", + "TestPassword", List.of(), true, true, @@ -48,36 +48,36 @@ public static MongoUserDTO testUserDTO(String username, String password, List uuidMock; private final ICategoryRepository repository = mock(ICategoryRepository.class); private final IPaymentRepository paymentRepo = mock(IPaymentRepository.class); + private final IPaymentSeriesRepository paymentSeriesRepository = mock(IPaymentSeriesRepository.class); private final PaymentService paymentService = mock(PaymentService.class); - private final CategoryService underTest = new CategoryService(repository, paymentRepo, paymentService); - - @BeforeAll - static void init() { - uuidMock = mockStatic(UUID.class); - uuidMock.when(UUID::randomUUID).thenReturn(uuid); - } - - @AfterAll - static void end() { - uuidMock.close(); - } + private final CategoryService underTest = new CategoryService(repository, paymentRepo, paymentSeriesRepository, paymentService); @Test void shouldFetchCategories() { underTest.getCategories(TestDataProvider.testUser()); - verify(repository).findAllByUserID(anyString()); + verify(repository).findAllByUserId(anyString()); } @Test @@ -54,7 +38,7 @@ void shouldThrowExceptionIfCategoryExists() { MongoUser user = TestDataProvider.testUser(); Category category = TestDataProvider.testCategory(); String categoryName = category.getCategoryName(); - when(repository.existsByUserIDAndCategoryName(anyString(), anyString())).thenReturn(true); + when(repository.existsByUserIdAndCategoryName(anyString(), anyString())).thenReturn(true); assertThrows(CategoryAlreadyExistException.class, () -> underTest.addCategory(user, categoryName)); @@ -64,10 +48,9 @@ void shouldThrowExceptionIfCategoryExists() { void shouldAddCategoryIfNotExistentAndReturnCategories() { MongoUser user = TestDataProvider.testUser(); Category category = TestDataProvider.testCategory(); - category.setCategoryID(UUID_STRING); String categoryName = category.getCategoryName(); when(repository.save(any(Category.class))).thenReturn(null); - when(repository.findAllByUserID(anyString())).thenReturn(List.of(category)); + when(repository.findAllByUserId(anyString())).thenReturn(List.of(category)); List wantedList = underTest.addCategory(user, categoryName); verify(repository).save(any(Category.class)); @@ -85,8 +68,8 @@ void shouldThrowExceptionIfCategoryNotExistsWithExplicitIdOnRename() { @Test void shouldThrowExceptionIfCategoryExistsWithNameOnRename() { MongoUser user = TestDataProvider.testUser(); - when(repository.findByUserIDAndCategoryID(anyString(), anyString())).thenReturn(TestDataProvider.testCategory()); - when(repository.existsByUserIDAndCategoryName(anyString(), anyString())).thenReturn(true); + when(repository.findByUserIdAndCategoryId(anyString(), anyString())).thenReturn(TestDataProvider.testCategory()); + when(repository.existsByUserIdAndCategoryName(anyString(), anyString())).thenReturn(true); assertThrows(CategoryAlreadyExistException.class, () -> underTest.renameCategory(user, "", "")); @@ -95,13 +78,13 @@ void shouldThrowExceptionIfCategoryExistsWithNameOnRename() { @Test void shouldReturnListOnSuccessfulRename() { MongoUser user = TestDataProvider.testUser(); - when(repository.findByUserIDAndCategoryID(anyString(), anyString())).thenReturn(TestDataProvider.testCategory()); - when(repository.existsByUserIDAndCategoryName(anyString(), anyString())).thenReturn(false); + when(repository.findByUserIdAndCategoryId(anyString(), anyString())).thenReturn(TestDataProvider.testCategory()); + when(repository.existsByUserIdAndCategoryName(anyString(), anyString())).thenReturn(false); List wantedList = underTest.renameCategory(user, "", ""); verify(repository).save(any(Category.class)); - verify(repository).findAllByUserID(anyString()); + verify(repository).findAllByUserId(anyString()); assertEquals(List.of(), wantedList); } @@ -111,9 +94,9 @@ void shouldReturnListOnSuccessfulDelete() { List wantedList = underTest.deleteCategory(user, ""); - verify(repository).deleteByCategoryID(anyString()); - verify(paymentRepo).deleteAllByUserIDAndCategoryID(anyString(), anyString()); - verify(repository).findAllByUserID(anyString()); + verify(repository).deleteByCategoryId(anyString()); + verify(paymentRepo).deleteAllByUserIdAndCategoryId(anyString(), anyString()); + verify(repository).findAllByUserId(anyString()); assertEquals(List.of(), wantedList); } } diff --git a/backend/src/test/java/com/github/redstylzz/backend/service/JWTServiceTest.java b/backend/src/test/java/com/github/redstylzz/backend/service/JWTServiceTest.java index cfe49b1..59a6ca6 100644 --- a/backend/src/test/java/com/github/redstylzz/backend/service/JWTServiceTest.java +++ b/backend/src/test/java/com/github/redstylzz/backend/service/JWTServiceTest.java @@ -21,7 +21,7 @@ class JWTServiceTest { private static final MockedStatic staticDate = mockStatic(Date.class); - private final String actualToken = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJUaXppYW4iLCJleHAiOjAsImlhdCI6MH0.9z7Q2p6ZlLAuABX-2fE_ouij1YjhsIAWnewZ4D2blks"; + private final String actualToken = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJUZXN0IiwiZXhwIjowLCJpYXQiOjB9.9o_lZ1UCyd3l-kwbjtQLFRunqZouMK7J0DiZSp2dFQo"; @Autowired private JWTService underTest; private MongoUser user; diff --git a/backend/src/test/java/com/github/redstylzz/backend/service/PaymentServiceTest.java b/backend/src/test/java/com/github/redstylzz/backend/service/PaymentServiceTest.java index 0c0753a..1dd47ee 100644 --- a/backend/src/test/java/com/github/redstylzz/backend/service/PaymentServiceTest.java +++ b/backend/src/test/java/com/github/redstylzz/backend/service/PaymentServiceTest.java @@ -28,96 +28,96 @@ class PaymentServiceTest { void shouldReturnList_OnGet() { Category category = TestDataProvider.testCategory(); Payment actualPayment = TestDataProvider.testPayment(); - when(paymentRepo.getAllByUserIDAndCategoryIDOrderByPayDateDesc(anyString(), anyString())).thenReturn(List.of(actualPayment)); + when(paymentRepo.getAllByUserIdAndCategoryIdOrderByPayDateDesc(anyString(), anyString())).thenReturn(List.of(actualPayment)); - List payments = underTest.getPayments(category.getUserID(), category.getCategoryID()); + List payments = underTest.getPayments(category.getUserId(), category.getCategoryId()); - verify(paymentRepo).getAllByUserIDAndCategoryIDOrderByPayDateDesc(anyString(), anyString()); + verify(paymentRepo).getAllByUserIdAndCategoryIdOrderByPayDateDesc(anyString(), anyString()); assertEquals(List.of(actualPayment), payments); } @Test void shouldThrowExceptionIfCategoryDoesNotExist_OnAdd() { Payment payment = TestDataProvider.testPayment(); - String userID = payment.getUserID(); - when(categoryRepository.existsByUserIDAndCategoryID(anyString(), anyString())).thenReturn(false); + String userId = payment.getUserId(); + when(categoryRepository.existsByUserIdAndCategoryId(anyString(), anyString())).thenReturn(false); - assertThrows(CategoryDoesNotExistException.class, () -> underTest.addPayment(userID, payment)); + assertThrows(CategoryDoesNotExistException.class, () -> underTest.addPayment(userId, payment)); } @Test void shouldReturnListAfterAddingPayment_OnAdd() { Payment actualPayment = TestDataProvider.testPayment(); - String userID = actualPayment.getUserID(); - when(categoryRepository.existsByUserIDAndCategoryID(anyString(), anyString())).thenReturn(true); - when(paymentRepo.getAllByUserIDAndCategoryIDOrderByPayDateDesc(anyString(), anyString())).thenReturn(List.of(actualPayment)); + String userId = actualPayment.getUserId(); + when(categoryRepository.existsByUserIdAndCategoryId(anyString(), anyString())).thenReturn(true); + when(paymentRepo.getAllByUserIdAndCategoryIdOrderByPayDateDesc(anyString(), anyString())).thenReturn(List.of(actualPayment)); - assertEquals(List.of(actualPayment), underTest.addPayment(userID, actualPayment)); + assertEquals(List.of(actualPayment), underTest.addPayment(userId, actualPayment)); verify(paymentRepo).save(any(Payment.class)); } @Test void shouldThrowExceptionIfCategoryDoesNotExist_OnDelete() { Payment actualPayment = TestDataProvider.testPayment(); - String userID = actualPayment.getUserID(); - String categoryID = actualPayment.getCategoryID(); - String paymentID = actualPayment.getPaymentID(); - when(categoryRepository.existsByUserIDAndCategoryID(anyString(), anyString())).thenReturn(false); + String userId = actualPayment.getUserId(); + String categoryId = actualPayment.getCategoryId(); + String paymentId = actualPayment.getPaymentId(); + when(categoryRepository.existsByUserIdAndCategoryId(anyString(), anyString())).thenReturn(false); - assertThrows(CategoryDoesNotExistException.class, () -> underTest.deletePayment(userID, categoryID, paymentID)); + assertThrows(CategoryDoesNotExistException.class, () -> underTest.deletePayment(userId, categoryId, paymentId)); } @Test void shouldReturnListAfterDeletingPayment_OnDelete() { Payment actualPayment = TestDataProvider.testPayment(); - String userID = actualPayment.getUserID(); - String categoryID = actualPayment.getCategoryID(); - String paymentID = actualPayment.getPaymentID(); - when(categoryRepository.existsByUserIDAndCategoryID(anyString(), anyString())).thenReturn(true); - when(paymentRepo.getAllByUserIDAndCategoryIDOrderByPayDateDesc(anyString(), anyString())).thenReturn(List.of(actualPayment)); - - assertEquals(List.of(actualPayment), underTest.deletePayment(userID, categoryID, paymentID)); - verify(paymentRepo).deleteByPaymentID(anyString()); + String userId = actualPayment.getUserId(); + String categoryId = actualPayment.getCategoryId(); + String paymentId = actualPayment.getPaymentId(); + when(categoryRepository.existsByUserIdAndCategoryId(anyString(), anyString())).thenReturn(true); + when(paymentRepo.getAllByUserIdAndCategoryIdOrderByPayDateDesc(anyString(), anyString())).thenReturn(List.of(actualPayment)); + + assertEquals(List.of(actualPayment), underTest.deletePayment(userId, categoryId, paymentId)); + verify(paymentRepo).deleteByPaymentId(anyString()); } @Test void shouldThrowExceptionIfCategoryDoesNotExist_OnChange() { Payment payment = TestDataProvider.testPayment(); - String userID = payment.getUserID(); - when(categoryRepository.existsByUserIDAndCategoryID(anyString(), anyString())).thenReturn(false); + String userId = payment.getUserId(); + when(categoryRepository.existsByUserIdAndCategoryId(anyString(), anyString())).thenReturn(false); - assertThrows(CategoryDoesNotExistException.class, () -> underTest.changePayment(userID, payment)); + assertThrows(CategoryDoesNotExistException.class, () -> underTest.changePayment(userId, payment)); } @Test void shouldThrowExceptionIfPaymentDoesNotExist_OnChange() { Payment payment = TestDataProvider.testPayment(); - String userID = payment.getUserID(); - when(categoryRepository.existsByUserIDAndCategoryID(anyString(), anyString())).thenReturn(true); - when(paymentRepo.existsByPaymentID(anyString())).thenReturn(false); + String userId = payment.getUserId(); + when(categoryRepository.existsByUserIdAndCategoryId(anyString(), anyString())).thenReturn(true); + when(paymentRepo.existsByPaymentId(anyString())).thenReturn(false); - assertThrows(PaymentDoesNotExistException.class, () -> underTest.changePayment(userID, payment)); + assertThrows(PaymentDoesNotExistException.class, () -> underTest.changePayment(userId, payment)); } @Test void shouldReturnListAfterSuccessfulChangingPayment_OnChange() { Payment actualPayment = TestDataProvider.testPayment(); - String userID = actualPayment.getUserID(); - when(categoryRepository.existsByUserIDAndCategoryID(anyString(), anyString())).thenReturn(true); - when(paymentRepo.getAllByUserIDAndCategoryIDOrderByPayDateDesc(anyString(), anyString())).thenReturn(List.of(actualPayment)); - when(paymentRepo.existsByPaymentID(anyString())).thenReturn(true); + String userId = actualPayment.getUserId(); + when(categoryRepository.existsByUserIdAndCategoryId(anyString(), anyString())).thenReturn(true); + when(paymentRepo.getAllByUserIdAndCategoryIdOrderByPayDateDesc(anyString(), anyString())).thenReturn(List.of(actualPayment)); + when(paymentRepo.existsByPaymentId(anyString())).thenReturn(true); - assertEquals(List.of(actualPayment), underTest.changePayment(userID, actualPayment)); + assertEquals(List.of(actualPayment), underTest.changePayment(userId, actualPayment)); verify(paymentRepo).save(any(Payment.class)); } @Test void shouldSpecificPaymentFromUserAndDepositId() { Payment actualPayment = testPayment(); - String depositId = actualPayment.getPaymentID(); + String depositId = actualPayment.getPaymentId(); String userId = testUser().getId(); - String categoryId = testCategory().getCategoryID(); - when(paymentRepo.getByUserIDAndCategoryIDAndPaymentID(anyString(), anyString(), anyString())).thenReturn(actualPayment); + String categoryId = testCategory().getCategoryId(); + when(paymentRepo.getByUserIdAndCategoryIdAndPaymentId(anyString(), anyString(), anyString())).thenReturn(actualPayment); Payment deposit = underTest.getPayment(userId, depositId, categoryId); @@ -128,7 +128,7 @@ void shouldSpecificPaymentFromUserAndDepositId() { void shouldReturnAllDepositsOfCurrentMonthFromUser() { String userId = testUser().getId(); List actualPayments = List.of(testPayment()); - when(paymentRepo.getAllByUserIDAndPayDateAfterOrderByPayDateDesc(anyString(), any(Instant.class))).thenReturn(actualPayments); + when(paymentRepo.getAllByUserIdAndPayDateAfterOrderByPayDateDesc(anyString(), any(Instant.class))).thenReturn(actualPayments); List deposits = underTest.getLastPayments(userId); diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index ad65d00..76bebde 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -46,12 +46,12 @@ function App() { } /> - } /> - } diff --git a/frontend/src/components/PieChart.tsx b/frontend/src/components/PieChart.tsx index a53a92d..765de29 100644 --- a/frontend/src/components/PieChart.tsx +++ b/frontend/src/components/PieChart.tsx @@ -96,7 +96,7 @@ const MyResponsivePie = (data: PieChartData[]) => ( { on: 'hover', style: { - itemTextColor: '#000' + itemTextColor: '#656565' } } ] diff --git a/frontend/src/components/categories/CategoryItem.tsx b/frontend/src/components/categories/CategoryItem.tsx index cf92747..6f4e033 100644 --- a/frontend/src/components/categories/CategoryItem.tsx +++ b/frontend/src/components/categories/CategoryItem.tsx @@ -21,9 +21,9 @@ const mapToCategoryItem = (category: Category, categorySum: number, deleteCatego

{category.categoryName}

-
) @@ -41,19 +41,19 @@ export default function CategoryItem({category, config, deleteCategory}: Categor const navigate = useNavigate() useEffect(() => { - controller.getPayments(category.categoryID).then((response) => { + controller.getPayments(category.categoryId).then((response) => { setPayments(response) }) - }, [category.categoryID, controller]) + }, [category.categoryId, controller]) useEffect(() => { setCategorySum(calcCategorySum(payments)) }, [payments]) return ( -
+
{mapToCategoryItem(category, categorySum, deleteCategory, navigate)} -
) diff --git a/frontend/src/components/categories/HomeCategoryItem.tsx b/frontend/src/components/categories/HomeCategoryItem.tsx index cba2d48..40e4afc 100644 --- a/frontend/src/components/categories/HomeCategoryItem.tsx +++ b/frontend/src/components/categories/HomeCategoryItem.tsx @@ -14,7 +14,7 @@ export default function HomeCategoryItem(props: { category: Category }) { const {category} = props return ( -
+
{mapToCategoryItem(category)}
) diff --git a/frontend/src/components/payments/PaymentItem.tsx b/frontend/src/components/payments/PaymentItem.tsx index 8d7393a..66273ee 100644 --- a/frontend/src/components/payments/PaymentItem.tsx +++ b/frontend/src/components/payments/PaymentItem.tsx @@ -6,20 +6,20 @@ import Button from "../Button"; interface PaymentItemProps { payment: Payment - deletePayment: (paymentID: string) => void - categoryID: string + deletePayment: (paymentId: string) => void + categoryId: string } -export default function PaymentItem({payment, deletePayment, categoryID}: PaymentItemProps) { +export default function PaymentItem({payment, deletePayment, categoryId}: PaymentItemProps) { const navigate = useNavigate() return ( -
+

{payment.description}

-
) } \ No newline at end of file diff --git a/frontend/src/components/payments/Payments.tsx b/frontend/src/components/payments/Payments.tsx index f19e84f..eecff47 100644 --- a/frontend/src/components/payments/Payments.tsx +++ b/frontend/src/components/payments/Payments.tsx @@ -9,7 +9,7 @@ import InputBox from "../InputBox"; interface PaymentsProps { payments: Payment[] - categoryID: string + categoryId: string setPayments: React.Dispatch> controller: IPaymentController } @@ -20,7 +20,7 @@ interface IPaymentInput { payDate: { value: string } } -export default function Payments({payments, categoryID, setPayments, controller}: PaymentsProps) { +export default function Payments({payments, categoryId, setPayments, controller}: PaymentsProps) { const [date, setDate] = useState(new Date(Date.now())) if (!Array.isArray(payments)) return null; @@ -29,18 +29,18 @@ export default function Payments({payments, categoryID, setPayments, controller} event.preventDefault() const form = event.currentTarget const formElements = form.elements as typeof form.elements & IPaymentInput - const paymentID: string = ""; + const paymentId: string = ""; const description: string = formElements.description.value const amount: number = formElements.amount.value const payDate: Date = new Date(date.toDateString()) const payment: Payment = { - paymentID, categoryID, description, amount, payDate + paymentId: paymentId, categoryId: categoryId, description, amount, payDate } controller.addPayment(payment).then(setPayments) } - const deletePayment = (_categoryID: string) => (paymentID: string) => { - controller.deletePayment(_categoryID, paymentID).then(setPayments) + const deletePayment = (_categoryId: string) => (paymentId: string) => { + controller.deletePayment(_categoryId, paymentId).then(setPayments) } return ( @@ -75,8 +75,8 @@ export default function Payments({payments, categoryID, setPayments, controller} { payments.map((payment, index) => - + ) }
diff --git a/frontend/src/controllers/CategoryController.ts b/frontend/src/controllers/CategoryController.ts index a317f3e..987ed8f 100644 --- a/frontend/src/controllers/CategoryController.ts +++ b/frontend/src/controllers/CategoryController.ts @@ -12,8 +12,8 @@ export default function CategoryController(config: ITokenConfig | undefined): IC addCategory: categoryName => { return service.addCategory(categoryName) }, - deleteCategory: categoryID => { - return service.deleteCategory(categoryID) + deleteCategory: categoryId => { + return service.deleteCategory(categoryId) }, renameCategory: category => { return service.renameCategory(category) diff --git a/frontend/src/controllers/PaymentController.ts b/frontend/src/controllers/PaymentController.ts index 09a2689..52c269c 100644 --- a/frontend/src/controllers/PaymentController.ts +++ b/frontend/src/controllers/PaymentController.ts @@ -7,8 +7,8 @@ export default function PaymentController(config: ITokenConfig | undefined): IPa const service: IPaymentController = PaymentService(config); return { - getPayment: ((categoryID, paymentID) => { - return service.getPayment(categoryID, paymentID) + getPayment: ((categoryId, paymentId) => { + return service.getPayment(categoryId, paymentId) }), getPayments: categoryId => { return service.getPayments(categoryId) @@ -19,8 +19,8 @@ export default function PaymentController(config: ITokenConfig | undefined): IPa addPayment: payment => { return service.addPayment(payment) }, - deletePayment: (categoryID, paymentID) => { - return service.deletePayment(categoryID, paymentID) + deletePayment: (categoryId, paymentId) => { + return service.deletePayment(categoryId, paymentId) }, changePayment: (payment) => { return service.changePayment(payment) diff --git a/frontend/src/models/Category.ts b/frontend/src/models/Category.ts index 55cc32f..96f58d1 100644 --- a/frontend/src/models/Category.ts +++ b/frontend/src/models/Category.ts @@ -1,15 +1,15 @@ export interface Category { - categoryID: string; + categoryId: string; categoryName: string; paymentSum?: number; } -export type IDeleteCategory = (categoryID: string) => void +export type IDeleteCategory = (categoryId: string) => void export type IRenameCategory = (category: Category) => void export interface ICategoryController { getCategories: () => Promise addCategory: (categoryName: string) => Promise - deleteCategory: (categoryID: string) => Promise + deleteCategory: (categoryId: string) => Promise renameCategory: (category: Category) => Promise } \ No newline at end of file diff --git a/frontend/src/models/Payment.ts b/frontend/src/models/Payment.ts index 6ff6821..33f0a4f 100644 --- a/frontend/src/models/Payment.ts +++ b/frontend/src/models/Payment.ts @@ -1,6 +1,6 @@ export interface Payment { - paymentID: string; - categoryID: string; + paymentId: string; + categoryId: string; description: string; amount: number; payDate: Date; @@ -8,15 +8,15 @@ export interface Payment { export interface PaymentDTO { description: string; - categoryID: string; + categoryId: string; amount: number; } export interface IPaymentController { - getPayment: (categoryID: string, paymentID: string) => Promise - getPayments: (categoryID: string) => Promise + getPayment: (categoryId: string, paymentId: string) => Promise + getPayments: (categoryId: string) => Promise getLastPayments: () => Promise addPayment: (payment: Payment) => Promise - deletePayment: (categoryID: string, paymentID: string) => Promise + deletePayment: (categoryId: string, paymentId: string) => Promise changePayment: (payment: Payment) => Promise } \ No newline at end of file diff --git a/frontend/src/pages/CategoryPage.tsx b/frontend/src/pages/CategoryPage.tsx index bab276c..0162b29 100644 --- a/frontend/src/pages/CategoryPage.tsx +++ b/frontend/src/pages/CategoryPage.tsx @@ -33,9 +33,9 @@ export default function CategoryPage() { setCategoryInput("") } - const deleteCategory = (categoryID: string) => { - if (!categoryID && categoryID.length <= 1) return - controller.deleteCategory(categoryID).then(setCategories) + const deleteCategory = (categoryId: string) => { + if (!categoryId && categoryId.length <= 1) return + controller.deleteCategory(categoryId).then(setCategories) } const onCategoryInputChange = (event: ChangeEvent) => diff --git a/frontend/src/pages/ChangePaymentPage.tsx b/frontend/src/pages/ChangePaymentPage.tsx index ccd752a..e920dbf 100644 --- a/frontend/src/pages/ChangePaymentPage.tsx +++ b/frontend/src/pages/ChangePaymentPage.tsx @@ -12,8 +12,8 @@ import Button from "../components/Button"; export default function ChangePaymentPage() { const urlParams = useParams() - const categoryID = urlParams.categoryID - const paymentID = urlParams.paymentID + const categoryId = urlParams.categoryId + const paymentId = urlParams.paymentId const [description, setDescription] = useState("") const [amount, setAmount] = useState(0) const [date, setDate] = useState(new Date(Date.now())) @@ -22,21 +22,21 @@ export default function ChangePaymentPage() { const navigate = useNavigate() useEffect(() => { - controller.getPayment(categoryID!, paymentID!).then((response) => { + controller.getPayment(categoryId!, paymentId!).then((response) => { setDescription(response.description) setAmount(response.amount) setDate(response.payDate) }) - }, [controller, categoryID, paymentID]) + }, [controller, categoryId, paymentId]) - if (!categoryID || !paymentID) return + if (!categoryId || !paymentId) return const changePayment = (event: FormEvent) => { event.preventDefault() if ((amount) && (description && description.length) && (date)) { const payment: Payment = { - paymentID, - categoryID, + paymentId: paymentId, + categoryId: categoryId, description, amount, payDate: new Date(date) diff --git a/frontend/src/pages/RenameCategoryPage.tsx b/frontend/src/pages/RenameCategoryPage.tsx index a82e004..3def27b 100644 --- a/frontend/src/pages/RenameCategoryPage.tsx +++ b/frontend/src/pages/RenameCategoryPage.tsx @@ -10,18 +10,18 @@ import './RenameCategoryPage.scss' export default function RenameCategoryPage() { const urlParams = useParams() - const categoryID = urlParams.categoryID + const categoryId = urlParams.categoryId const [categoryName, setCategoryName] = useState(urlParams.categoryName) const config = useContext(AuthContext).config const controller: ICategoryController = useMemo(() => CategoryController(config), [config]) const navigate = useNavigate() - if (!categoryID || !categoryName) return + if (!categoryId || !categoryName) return const changeCategory = (event: FormEvent) => { event.preventDefault() if (categoryName && categoryName.length) { - controller.renameCategory({categoryID, categoryName}).then(() => navigate("/categories")) + controller.renameCategory({categoryId, categoryName}).then(() => navigate("/categories")) } } diff --git a/frontend/src/pages/SchedulePage.tsx b/frontend/src/pages/SchedulePage.tsx index eb52d48..00459b8 100644 --- a/frontend/src/pages/SchedulePage.tsx +++ b/frontend/src/pages/SchedulePage.tsx @@ -50,11 +50,11 @@ export default function SchedulePage() { if (typeName === "Payment") { const form = event.currentTarget const formElements = form.elements as typeof form.elements & SelectInput - const categoryID: string = formElements.selectCategory.value + const categoryId: string = formElements.selectCategory.value - if (!categoryID || !categoryID.length) return + if (!categoryId || !categoryId.length) return - const payment: PaymentDTO = {description, amount, categoryID} + const payment: PaymentDTO = {description, amount, categoryId: categoryId} const seriesObj: PaymentSeries = {scheduledDate, payment, startDate: rangeValue[0], endDate: rangeValue[1]} seriesController.addPaymentSeries(seriesObj).then(setPaymentSeries) } else { @@ -132,7 +132,7 @@ export default function SchedulePage() { diff --git a/frontend/src/services/CategoryService.ts b/frontend/src/services/CategoryService.ts index bb0852b..b3f96cd 100644 --- a/frontend/src/services/CategoryService.ts +++ b/frontend/src/services/CategoryService.ts @@ -11,8 +11,8 @@ export default function CategoryService(config: ITokenConfig | undefined): ICate addCategory: categoryName => { return axios.post(URL, {categoryName}, config).then(response => response.data) }, - deleteCategory: categoryID => { - return axios.delete(URL + `/?categoryID=${categoryID}`, config).then(response => response.data) + deleteCategory: categoryId => { + return axios.delete(URL + `/?categoryId=${categoryId}`, config).then(response => response.data) }, renameCategory: category => { return axios.patch(URL, category, config).then(response => response.data) diff --git a/frontend/src/services/PaymentService.ts b/frontend/src/services/PaymentService.ts index 897dae4..ba27171 100644 --- a/frontend/src/services/PaymentService.ts +++ b/frontend/src/services/PaymentService.ts @@ -4,11 +4,11 @@ import {IPaymentController} from "../models/Payment"; export default function PaymentService(config: ITokenConfig | undefined): IPaymentController { return { - getPayment: ((categoryID, paymentID) => { - return axios.get(`/api/payment/?categoryID=${categoryID}&paymentID=${paymentID}`, config).then(response => response.data) + getPayment: ((categoryId, paymentId) => { + return axios.get(`/api/payment/?categoryId=${categoryId}&paymentId=${paymentId}`, config).then(response => response.data) }), - getPayments: (categoryID) => { - return axios.get(`/api/payment/${categoryID}`, config).then(response => response.data) + getPayments: (categoryId) => { + return axios.get(`/api/payment/${categoryId}`, config).then(response => response.data) }, getLastPayments: () => { return axios.get("/api/payment", config).then(response => response.data) @@ -16,8 +16,8 @@ export default function PaymentService(config: ITokenConfig | undefined): IPayme addPayment: payment => { return axios.post("/api/payment", payment, config).then(response => response.data) }, - deletePayment: (categoryID, paymentID) => { - return axios.delete(`/api/payment/?categoryID=${categoryID}&paymentID=${paymentID}`, config).then(response => response.data) + deletePayment: (categoryId, paymentId) => { + return axios.delete(`/api/payment/?categoryId=${categoryId}&paymentId=${paymentId}`, config).then(response => response.data) }, changePayment: (payment) => { return axios.put(`/api/payment`, payment, config).then(response => response.data)