fix: single-param JPQL queries, ResourceNotFoundException throughout ExpenseListService, remove addExpenseToList loop
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -16,11 +16,9 @@ public interface ExpenseListRepository extends JpaRepository<ExpenseList, Long>
|
|||||||
|
|
||||||
ExpenseList findByInviteCode(String inviteCode);
|
ExpenseList findByInviteCode(String inviteCode);
|
||||||
|
|
||||||
@Query("SELECT el FROM ExpenseList el WHERE el.owner.id = :userId OR el.sharedWith.id = :sharedUserId")
|
@Query("SELECT el FROM ExpenseList el WHERE el.owner.id = :userId OR el.sharedWith.id = :userId")
|
||||||
List<ExpenseList> findByOwnerIdOrSharedWithId(@Param("userId") Long userId,
|
List<ExpenseList> findByOwnerIdOrSharedWithId(@Param("userId") Long userId);
|
||||||
@Param("sharedUserId") Long sharedUserId);
|
|
||||||
|
|
||||||
@Query("SELECT el FROM ExpenseList el WHERE el.owner.username = :username OR el.sharedWith.username = :sharedUsername")
|
@Query("SELECT el FROM ExpenseList el WHERE el.owner.username = :username OR el.sharedWith.username = :username")
|
||||||
List<ExpenseList> findByOwnerUsernameOrSharedWithUsername(@Param("username") String username,
|
List<ExpenseList> findByOwnerUsernameOrSharedWithUsername(@Param("username") String username);
|
||||||
@Param("sharedUsername") String sharedUsername);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package de.zendric.app.xpensely_server.services;
|
package de.zendric.app.xpensely_server.services;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -10,9 +8,9 @@ import java.util.UUID;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import de.zendric.app.xpensely_server.model.AppUser;
|
|
||||||
import de.zendric.app.xpensely_server.model.Expense;
|
import de.zendric.app.xpensely_server.model.Expense;
|
||||||
import de.zendric.app.xpensely_server.model.ExpenseList;
|
import de.zendric.app.xpensely_server.model.ExpenseList;
|
||||||
|
import de.zendric.app.xpensely_server.model.Exception.ResourceNotFoundException;
|
||||||
import de.zendric.app.xpensely_server.model.XpenselyCustomCategory;
|
import de.zendric.app.xpensely_server.model.XpenselyCustomCategory;
|
||||||
import de.zendric.app.xpensely_server.repo.ExpenseListRepository;
|
import de.zendric.app.xpensely_server.repo.ExpenseListRepository;
|
||||||
import de.zendric.app.xpensely_server.repo.ExpenseRepository;
|
import de.zendric.app.xpensely_server.repo.ExpenseRepository;
|
||||||
@@ -62,40 +60,24 @@ public class ExpenseListService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<ExpenseList> findByUserId(Long id) {
|
public List<ExpenseList> findByUserId(Long id) {
|
||||||
return repository.findByOwnerIdOrSharedWithId(id, id);
|
return repository.findByOwnerIdOrSharedWithId(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ExpenseList> findByUsername(String username) {
|
public List<ExpenseList> findByUsername(String username) {
|
||||||
return repository.findByOwnerUsernameOrSharedWithUsername(username, username);
|
return repository.findByOwnerUsernameOrSharedWithUsername(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Expense addExpenseToList(Long expenseListId, Expense expense) {
|
public Expense addExpenseToList(Long expenseListId, Expense expense) {
|
||||||
// find expenseList
|
|
||||||
ExpenseList expenseList = repository.findById(expenseListId)
|
ExpenseList expenseList = repository.findById(expenseListId)
|
||||||
.orElseThrow(() -> new RuntimeException("ExpenseList not found with id: " + expenseListId));
|
.orElseThrow(() -> new ResourceNotFoundException("ExpenseList not found with id: " + expenseListId));
|
||||||
// get all added expenses
|
|
||||||
HashSet<Long> existingId = new HashSet<>();
|
|
||||||
for (Expense e : expenseList.getExpenses()) {
|
|
||||||
existingId.add(e.getId());
|
|
||||||
}
|
|
||||||
// add the new expense
|
|
||||||
expenseList.addExpense(expense);
|
expenseList.addExpense(expense);
|
||||||
// save
|
|
||||||
repository.save(expenseList);
|
repository.save(expenseList);
|
||||||
|
return expense;
|
||||||
Expense newExpense = new Expense();
|
|
||||||
for (Expense e : expenseList.getExpenses()) {
|
|
||||||
if (!existingId.contains(e.getId())) {
|
|
||||||
newExpense = e;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newExpense;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteExpenseFromList(Long expenseListId, Long expenseId) {
|
public void deleteExpenseFromList(Long expenseListId, Long expenseId) {
|
||||||
ExpenseList expenseList = repository.findById(expenseListId)
|
ExpenseList expenseList = repository.findById(expenseListId)
|
||||||
.orElseThrow(() -> new RuntimeException("ExpenseList not found with id: " + expenseListId));
|
.orElseThrow(() -> new ResourceNotFoundException("ExpenseList not found with id: " + expenseListId));
|
||||||
Expense expenseToRemove = null;
|
Expense expenseToRemove = null;
|
||||||
for (Expense expense : expenseList.getExpenses()) {
|
for (Expense expense : expenseList.getExpenses()) {
|
||||||
if (expense.getId().equals(expenseId)) {
|
if (expense.getId().equals(expenseId)) {
|
||||||
@@ -106,14 +88,14 @@ public class ExpenseListService {
|
|||||||
if (expenseToRemove != null) {
|
if (expenseToRemove != null) {
|
||||||
expenseList.removeExpense(expenseToRemove);
|
expenseList.removeExpense(expenseToRemove);
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Expense not found with id: " + expenseId);
|
throw new ResourceNotFoundException("Expense not found with id: " + expenseId);
|
||||||
}
|
}
|
||||||
repository.save(expenseList);
|
repository.save(expenseList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String generateInviteCode(Long listId) {
|
public String generateInviteCode(Long listId) {
|
||||||
ExpenseList list = repository.findById(listId)
|
ExpenseList list = repository.findById(listId)
|
||||||
.orElseThrow(() -> new RuntimeException("List not found"));
|
.orElseThrow(() -> new ResourceNotFoundException("List not found"));
|
||||||
String inviteCode;
|
String inviteCode;
|
||||||
if (list.getInviteCode() == null || list.getInviteCodeExpiration().isBefore(LocalDateTime.now())) {
|
if (list.getInviteCode() == null || list.getInviteCodeExpiration().isBefore(LocalDateTime.now())) {
|
||||||
|
|
||||||
@@ -158,7 +140,7 @@ public class ExpenseListService {
|
|||||||
// TODO implement API for this
|
// TODO implement API for this
|
||||||
public XpenselyCustomCategory addCustomCategory(Long expenseListId, XpenselyCustomCategory customCategory) {
|
public XpenselyCustomCategory addCustomCategory(Long expenseListId, XpenselyCustomCategory customCategory) {
|
||||||
ExpenseList expenseList = repository.findById(expenseListId)
|
ExpenseList expenseList = repository.findById(expenseListId)
|
||||||
.orElseThrow(() -> new RuntimeException("Expense List not found"));
|
.orElseThrow(() -> new ResourceNotFoundException("Expense List not found"));
|
||||||
customCategory.setExpenseList(expenseList);
|
customCategory.setExpenseList(expenseList);
|
||||||
|
|
||||||
return customCategoryRepository.save(customCategory);
|
return customCategoryRepository.save(customCategory);
|
||||||
@@ -167,7 +149,7 @@ public class ExpenseListService {
|
|||||||
// TODO implement API for this
|
// TODO implement API for this
|
||||||
public void deleteCustomCategory(Long expenseListId, Long categoryId) {
|
public void deleteCustomCategory(Long expenseListId, Long categoryId) {
|
||||||
XpenselyCustomCategory category = customCategoryRepository.findById(categoryId)
|
XpenselyCustomCategory category = customCategoryRepository.findById(categoryId)
|
||||||
.orElseThrow(() -> new RuntimeException("Custom Category not found"));
|
.orElseThrow(() -> new ResourceNotFoundException("Custom Category not found"));
|
||||||
if (!category.getExpenseList().getId().equals(expenseListId)) {
|
if (!category.getExpenseList().getId().equals(expenseListId)) {
|
||||||
throw new RuntimeException("Category does not belong to the specified Expense List");
|
throw new RuntimeException("Category does not belong to the specified Expense List");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,12 +33,12 @@ class ExpenseListServiceTest {
|
|||||||
void findByUserId_usesRepositoryQuery_notFindAll() {
|
void findByUserId_usesRepositoryQuery_notFindAll() {
|
||||||
AppUser owner = new AppUser(); owner.setId(1L);
|
AppUser owner = new AppUser(); owner.setId(1L);
|
||||||
ExpenseList list = new ExpenseList(); list.setId(10L); list.setOwner(owner);
|
ExpenseList list = new ExpenseList(); list.setId(10L); list.setOwner(owner);
|
||||||
when(repository.findByOwnerIdOrSharedWithId(1L, 1L)).thenReturn(List.of(list));
|
when(repository.findByOwnerIdOrSharedWithId(1L)).thenReturn(List.of(list));
|
||||||
|
|
||||||
List<ExpenseList> result = service.findByUserId(1L);
|
List<ExpenseList> result = service.findByUserId(1L);
|
||||||
|
|
||||||
assertThat(result).hasSize(1);
|
assertThat(result).hasSize(1);
|
||||||
verify(repository).findByOwnerIdOrSharedWithId(1L, 1L);
|
verify(repository).findByOwnerIdOrSharedWithId(1L);
|
||||||
verify(repository, never()).findAll();
|
verify(repository, never()).findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,12 +46,12 @@ class ExpenseListServiceTest {
|
|||||||
void findByUsername_usesRepositoryQuery_notFindAll() {
|
void findByUsername_usesRepositoryQuery_notFindAll() {
|
||||||
AppUser owner = new AppUser(); owner.setId(1L); owner.setUsername("alice");
|
AppUser owner = new AppUser(); owner.setId(1L); owner.setUsername("alice");
|
||||||
ExpenseList list = new ExpenseList(); list.setId(10L); list.setOwner(owner);
|
ExpenseList list = new ExpenseList(); list.setId(10L); list.setOwner(owner);
|
||||||
when(repository.findByOwnerUsernameOrSharedWithUsername("alice", "alice")).thenReturn(List.of(list));
|
when(repository.findByOwnerUsernameOrSharedWithUsername("alice")).thenReturn(List.of(list));
|
||||||
|
|
||||||
List<ExpenseList> result = service.findByUsername("alice");
|
List<ExpenseList> result = service.findByUsername("alice");
|
||||||
|
|
||||||
assertThat(result).hasSize(1);
|
assertThat(result).hasSize(1);
|
||||||
verify(repository).findByOwnerUsernameOrSharedWithUsername("alice", "alice");
|
verify(repository).findByOwnerUsernameOrSharedWithUsername("alice");
|
||||||
verify(repository, never()).findAll();
|
verify(repository, never()).findAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user