This commit is contained in:
2026-05-09 23:04:27 +02:00
parent b1324e3048
commit 3d456f2f81
8 changed files with 159 additions and 152 deletions
+12 -1
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.1</version> <version>4.0.6</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath/> <!-- lookup parent from repository -->
</parent> </parent>
<groupId>de.zendric.app</groupId> <groupId>de.zendric.app</groupId>
@@ -28,6 +28,7 @@
</scm> </scm>
<properties> <properties>
<java.version>21</java.version> <java.version>21</java.version>
<lombok.version>1.18.46</lombok.version>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
@@ -80,6 +81,16 @@
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa-test</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>com.h2database</groupId> <groupId>com.h2database</groupId>
<artifactId>h2</artifactId> <artifactId>h2</artifactId>
@@ -9,7 +9,6 @@ import org.springframework.web.server.ResponseStatusException;
import de.zendric.app.xpensely_server.model.AppUser; import de.zendric.app.xpensely_server.model.AppUser;
import de.zendric.app.xpensely_server.model.AppUserCreateRequest; import de.zendric.app.xpensely_server.model.AppUserCreateRequest;
import de.zendric.app.xpensely_server.model.Exception.UsernameAlreadyExistsException;
import de.zendric.app.xpensely_server.security.AuthenticatedUserResolver; import de.zendric.app.xpensely_server.security.AuthenticatedUserResolver;
import de.zendric.app.xpensely_server.services.UserService; import de.zendric.app.xpensely_server.services.UserService;
@@ -47,15 +46,9 @@ public class AppUserController {
@PostMapping("/createUser") @PostMapping("/createUser")
public ResponseEntity<AppUser> createUser(@RequestBody @Valid AppUserCreateRequest userRequest) { public ResponseEntity<AppUser> createUser(@RequestBody @Valid AppUserCreateRequest userRequest) {
try {
AppUser convertedUser = userRequest.convertToAppUser(); AppUser convertedUser = userRequest.convertToAppUser();
AppUser nUser = userService.createUser(convertedUser); AppUser nUser = userService.createUser(convertedUser);
return new ResponseEntity<>(nUser, HttpStatus.CREATED); return new ResponseEntity<>(nUser, HttpStatus.CREATED);
} catch (UsernameAlreadyExistsException e) {
return new ResponseEntity<>(null, HttpStatus.CONFLICT);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
}
} }
@DeleteMapping @DeleteMapping
@@ -68,6 +68,7 @@ public class ExpenseListController {
expenseList.setXpenselyStandardCategories(standardCategories); expenseList.setXpenselyStandardCategories(standardCategories);
expenseList.setSharedWith(null); expenseList.setSharedWith(null);
ExpenseList savedItem = expenseListService.createList(expenseList); ExpenseList savedItem = expenseListService.createList(expenseList);
log.debug("Created expense list '{}' for user {}", savedItem.getName(), authenticatedUser.getId());
return new ResponseEntity<>(savedItem, HttpStatus.CREATED); return new ResponseEntity<>(savedItem, HttpStatus.CREATED);
} }
@@ -106,7 +107,7 @@ public class ExpenseListController {
AppUser user = authenticatedUserResolver.resolveCurrentUser(authentication); AppUser user = authenticatedUserResolver.resolveCurrentUser(authentication);
Optional<ExpenseList> expenseListOpt = expenseListService.findById(expenseListId); Optional<ExpenseList> expenseListOpt = expenseListService.findById(expenseListId);
if (expenseListOpt.isEmpty()) if (expenseListOpt.isEmpty())
return new ResponseEntity<>(null, HttpStatus.NOT_FOUND); return new ResponseEntity<>(HttpStatus.NOT_FOUND);
assertMember(user, expenseListOpt.get()); assertMember(user, expenseListOpt.get());
AppUser expenseOwner = userService.getUserByName(expenseChangeRequest.getOwnerName()); AppUser expenseOwner = userService.getUserByName(expenseChangeRequest.getOwnerName());
Expense expense = expenseChangeRequest.convertToExpense(expenseOwner.getId(), expenseListOpt.get()); Expense expense = expenseChangeRequest.convertToExpense(expenseOwner.getId(), expenseListOpt.get());
@@ -6,7 +6,7 @@ import org.springframework.context.annotation.Profile;
import org.springframework.security.config.Customizer; import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter; import org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
@Configuration @Configuration
@@ -18,7 +18,7 @@ public class SecurityConfig {
http http
.authorizeHttpRequests(auth -> auth .authorizeHttpRequests(auth -> auth
.anyRequest().permitAll()) .anyRequest().permitAll())
.csrf().disable(); .csrf(csrf -> csrf.disable());
return http.build(); return http.build();
} }
@@ -33,7 +33,7 @@ public class SecurityConfig {
.jwt(Customizer.withDefaults())) .jwt(Customizer.withDefaults()))
.oauth2Login(Customizer.withDefaults()) .oauth2Login(Customizer.withDefaults())
.addFilterAfter(new RateLimitFilter(), BearerTokenAuthenticationFilter.class) .addFilterAfter(new RateLimitFilter(), BearerTokenAuthenticationFilter.class)
.csrf().disable(); .csrf(csrf -> csrf.disable());
return http.build(); return http.build();
} }
@@ -31,18 +31,10 @@ public class ExpenseListService {
this.customCategoryRepository = customCategoryRepository; this.customCategoryRepository = customCategoryRepository;
} }
public List<ExpenseList> getAllLists() {
return repository.findAll();
}
public ExpenseList createList(ExpenseList list) { public ExpenseList createList(ExpenseList list) {
return repository.save(list); return repository.save(list);
} }
public void deleteList(Long id) {
repository.deleteById(id);
}
public void deleteById(Long id) { public void deleteById(Long id) {
repository.deleteById(id); repository.deleteById(id);
} }
@@ -51,10 +43,6 @@ public class ExpenseListService {
return repository.findById(id); return repository.findById(id);
} }
public Iterable<ExpenseList> findAll() {
return repository.findAll();
}
public ExpenseList save(ExpenseList expenseList) { public ExpenseList save(ExpenseList expenseList) {
return repository.save(expenseList); return repository.save(expenseList);
} }
@@ -4,7 +4,7 @@ import de.zendric.app.xpensely_server.model.ExpenseList;
import de.zendric.app.xpensely_server.repo.ExpenseListRepository; import de.zendric.app.xpensely_server.repo.ExpenseListRepository;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest;
import java.util.Optional; import java.util.Optional;
@@ -6,8 +6,11 @@ import de.zendric.app.xpensely_server.security.AuthenticatedUserResolver;
import de.zendric.app.xpensely_server.services.UserService; import de.zendric.app.xpensely_server.services.UserService;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.security.oauth2.client.autoconfigure.OAuth2ClientAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.security.oauth2.client.autoconfigure.servlet.OAuth2ClientWebSecurityAutoConfiguration;
import org.springframework.boot.security.oauth2.server.resource.autoconfigure.servlet.OAuth2ResourceServerAutoConfiguration;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.bean.override.mockito.MockitoBean;
@@ -18,7 +21,11 @@ import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@WebMvcTest(AppUserController.class) @WebMvcTest(value = AppUserController.class, excludeAutoConfiguration = {
OAuth2ClientAutoConfiguration.class,
OAuth2ClientWebSecurityAutoConfiguration.class,
OAuth2ResourceServerAutoConfiguration.class
})
@AutoConfigureMockMvc(addFilters = false) @AutoConfigureMockMvc(addFilters = false)
@ActiveProfiles("test") @ActiveProfiles("test")
class AppUserControllerTest { class AppUserControllerTest {
@@ -9,8 +9,11 @@ import de.zendric.app.xpensely_server.services.ExpenseListService;
import de.zendric.app.xpensely_server.services.UserService; import de.zendric.app.xpensely_server.services.UserService;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.security.oauth2.client.autoconfigure.OAuth2ClientAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.security.oauth2.client.autoconfigure.servlet.OAuth2ClientWebSecurityAutoConfiguration;
import org.springframework.boot.security.oauth2.server.resource.autoconfigure.servlet.OAuth2ResourceServerAutoConfiguration;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.bean.override.mockito.MockitoBean;
@@ -24,7 +27,11 @@ import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@WebMvcTest(ExpenseListController.class) @WebMvcTest(value = ExpenseListController.class, excludeAutoConfiguration = {
OAuth2ClientAutoConfiguration.class,
OAuth2ClientWebSecurityAutoConfiguration.class,
OAuth2ResourceServerAutoConfiguration.class
})
@AutoConfigureMockMvc(addFilters = false) @AutoConfigureMockMvc(addFilters = false)
@ActiveProfiles("test") @ActiveProfiles("test")
class ExpenseListControllerTest { class ExpenseListControllerTest {