From d72b5b48e1bff804174bc36d5d52fbfec95794d1 Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Fri, 13 Feb 2026 10:41:12 +0200
Subject: [PATCH 01/23] Update project to Java 21, Spring Boot 4.0.2, and add
new test dependencies
---
pom.xml | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/pom.xml b/pom.xml
index 6058c82..0d1ce1c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,14 +8,14 @@
1.0.0
war
Simple-Invoicing
- Final Project — Spring Boot Advanced — May 2024
+ Final Project – Spring Boot Advanced – May 2024
- 17
- 17
+ 21
+ 21
UTF-8
- 17
- 3.5.7
+ 21
+ 4.0.2
3.2.6
2.3.2
9.5.0
@@ -91,6 +91,16 @@
spring-boot-starter-test
test
+
+ org.springframework.boot
+ spring-boot-starter-webmvc-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa-test
+ test
+
org.springframework.security
spring-security-test
From f13da7b840537fa86f402a946d108a45150da925 Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Fri, 13 Feb 2026 10:41:31 +0200
Subject: [PATCH 02/23] Update system properties to require Java 21
---
system.properties | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/system.properties b/system.properties
index 0dc726c..ec9df9a 100644
--- a/system.properties
+++ b/system.properties
@@ -1 +1 @@
-java.runtime.version=17
\ No newline at end of file
+java.runtime.version=21
\ No newline at end of file
From 919e5fd86e5cdffcb7d93f391f10246b4be7af96 Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Fri, 13 Feb 2026 10:41:48 +0200
Subject: [PATCH 03/23] Update Dockerfile to use Java 21 alpine image
---
Dockerfile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Dockerfile b/Dockerfile
index 8f4201f..5680209 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM eclipse-temurin:17-jdk-alpine
+FROM eclipse-temurin:21-jdk-alpine
WORKDIR /app
From ceeb76b1f80a3dc32b8526b88ac12f0aca5201d4 Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Fri, 13 Feb 2026 10:42:55 +0200
Subject: [PATCH 04/23] Restrict /log/** to ROOT role and update static
resource matchers
---
.../softuni/invoice/config/SecurityConfiguration.java | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/main/java/bg/softuni/invoice/config/SecurityConfiguration.java b/src/main/java/bg/softuni/invoice/config/SecurityConfiguration.java
index bafc390..1d2753b 100644
--- a/src/main/java/bg/softuni/invoice/config/SecurityConfiguration.java
+++ b/src/main/java/bg/softuni/invoice/config/SecurityConfiguration.java
@@ -1,7 +1,6 @@
package bg.softuni.invoice.config;
import lombok.AllArgsConstructor;
-import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
@@ -34,9 +33,16 @@ public SecurityFilterChain configureSecurity(HttpSecurity httpSecurity) throws E
.csrf(csrf -> csrf.csrfTokenRepository(csrfTokenRepository()))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/").permitAll()
- .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
+ .requestMatchers(
+ "/css/**",
+ "/js/**",
+ "/images/**",
+ "/webjars/**",
+ "/favicon.ico"
+ ).permitAll()
.requestMatchers("/actuator/health").permitAll()
.requestMatchers("/user/register", "/user/login").anonymous()
+ .requestMatchers("/log/**").hasRole("ROOT")
.anyRequest().authenticated()
)
.formLogin(form -> form
From 0dc55df6bb6ecfb2919ef6452c80d205b2da4b95 Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Fri, 13 Feb 2026 10:43:47 +0200
Subject: [PATCH 05/23] Fix import for PathRequest to match Spring Boot 4
changes
---
.../bg/softuni/invoice/web/interceptor/LoggingInterceptor.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/bg/softuni/invoice/web/interceptor/LoggingInterceptor.java b/src/main/java/bg/softuni/invoice/web/interceptor/LoggingInterceptor.java
index 37edd70..95ad581 100644
--- a/src/main/java/bg/softuni/invoice/web/interceptor/LoggingInterceptor.java
+++ b/src/main/java/bg/softuni/invoice/web/interceptor/LoggingInterceptor.java
@@ -7,7 +7,7 @@
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
-import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
+import org.springframework.boot.security.autoconfigure.web.servlet.PathRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
From bfd34905492ae27ab8269490779090a20486f2c4 Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Fri, 13 Feb 2026 10:44:29 +0200
Subject: [PATCH 06/23] Refactor HomeController to improve authentication check
using Authentication instead of Principal
---
.../invoice/web/controller/HomeController.java | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/main/java/bg/softuni/invoice/web/controller/HomeController.java b/src/main/java/bg/softuni/invoice/web/controller/HomeController.java
index aca6ecc..7f271e5 100644
--- a/src/main/java/bg/softuni/invoice/web/controller/HomeController.java
+++ b/src/main/java/bg/softuni/invoice/web/controller/HomeController.java
@@ -2,19 +2,23 @@
import bg.softuni.invoice.web.annotation.PageTitle;
import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
-import java.security.Principal;
-
@Controller
public class HomeController {
@GetMapping("/")
@PageTitle("invoices")
- public String index(Principal principal) {
+ public String index(Authentication authentication) {
+
+ boolean isLoggedIn = authentication != null
+ && authentication.isAuthenticated()
+ && !(authentication instanceof AnonymousAuthenticationToken);
- if (principal != null) {
+ if (isLoggedIn) {
return "home/home";
}
From 07b968bf854df3795ea68ca793bbe30f3d73958b Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Fri, 13 Feb 2026 10:44:59 +0200
Subject: [PATCH 07/23] Replace ROLE_ROOT with ROOT in PreAuthorize annotations
for consistency
---
.../softuni/invoice/web/controller/UserController.java | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/main/java/bg/softuni/invoice/web/controller/UserController.java b/src/main/java/bg/softuni/invoice/web/controller/UserController.java
index bf7cc84..2354429 100644
--- a/src/main/java/bg/softuni/invoice/web/controller/UserController.java
+++ b/src/main/java/bg/softuni/invoice/web/controller/UserController.java
@@ -149,7 +149,7 @@ public String profileConfirm(@Valid
@GetMapping("/all")
@PageTitle("User all")
- @PreAuthorize("hasRole('ROLE_ROOT')")
+ @PreAuthorize("hasRole('ROOT')")
public String allUsers(Model model) {
List users = this.userService.getAllUsers()
@@ -172,7 +172,7 @@ public String allUsers(Model model) {
}
@PostMapping("/set-admin/{id}")
- @PreAuthorize("hasRole('ROLE_ROOT')")
+ @PreAuthorize("hasRole('ROOT')")
public String setAdminRole(@PathVariable String id) {
this.userService.setAdmin(id);
@@ -180,7 +180,7 @@ public String setAdminRole(@PathVariable String id) {
}
@PostMapping("/set-user/{id}")
- @PreAuthorize("hasRole('ROLE_ROOT')")
+ @PreAuthorize("hasRole('ROOT')")
public String setUserRole(@PathVariable String id) {
this.userService.setUser(id);
@@ -188,7 +188,7 @@ public String setUserRole(@PathVariable String id) {
}
@PostMapping("/set-enabled/{id}")
- @PreAuthorize("hasRole('ROLE_ROOT')")
+ @PreAuthorize("hasRole('ROOT')")
public String setEnabled(@PathVariable String id) {
this.userService.setUserEnabled(id);
@@ -196,7 +196,7 @@ public String setEnabled(@PathVariable String id) {
}
@PostMapping("/set-disabled/{id}")
- @PreAuthorize("hasRole('ROLE_ROOT')")
+ @PreAuthorize("hasRole('ROOT')")
public String setDisabled(@PathVariable String id) {
this.userService.setUserDisabled(id);
From 617c01e620add6495d6c9bb0fa90e967f6827ee8 Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Fri, 13 Feb 2026 11:25:25 +0200
Subject: [PATCH 08/23] Remove unnecessary @Async and @EnableAsync annotations
from ScheduleService interface
---
.../java/bg/softuni/invoice/service/ScheduleService.java | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/src/main/java/bg/softuni/invoice/service/ScheduleService.java b/src/main/java/bg/softuni/invoice/service/ScheduleService.java
index bb519a1..31dea1e 100644
--- a/src/main/java/bg/softuni/invoice/service/ScheduleService.java
+++ b/src/main/java/bg/softuni/invoice/service/ScheduleService.java
@@ -1,14 +1,8 @@
package bg.softuni.invoice.service;
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.scheduling.annotation.EnableAsync;
-
-@EnableAsync
public interface ScheduleService {
-
- @Async
void deleteLogs();
- @Async
void changeStatus();
}
+
From e7e3ef4840a934ec117216ef07a44e4fe22885d4 Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Sat, 14 Feb 2026 05:55:52 +0200
Subject: [PATCH 09/23] Fix incorrect import to use correct DataJpaTest
annotation
---
.../bg/softuni/invoice/repository/CompanyRepositoryTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/test/java/bg/softuni/invoice/repository/CompanyRepositoryTest.java b/src/test/java/bg/softuni/invoice/repository/CompanyRepositoryTest.java
index 452b94a..c1c0629 100644
--- a/src/test/java/bg/softuni/invoice/repository/CompanyRepositoryTest.java
+++ b/src/test/java/bg/softuni/invoice/repository/CompanyRepositoryTest.java
@@ -7,7 +7,7 @@
import org.junit.jupiter.params.provider.NullSource;
import org.junit.jupiter.params.provider.ValueSource;
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.List;
import java.util.Optional;
From b15a55a7731c3ecaa98f706f711189576d3bb91c Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Sat, 14 Feb 2026 05:56:04 +0200
Subject: [PATCH 10/23] Fix incorrect import in UserRepositoryTest
---
.../java/bg/softuni/invoice/repository/UserRepositoryTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/test/java/bg/softuni/invoice/repository/UserRepositoryTest.java b/src/test/java/bg/softuni/invoice/repository/UserRepositoryTest.java
index 9ba4089..d82d89c 100644
--- a/src/test/java/bg/softuni/invoice/repository/UserRepositoryTest.java
+++ b/src/test/java/bg/softuni/invoice/repository/UserRepositoryTest.java
@@ -4,7 +4,7 @@
import jakarta.persistence.EntityManager;
import org.junit.jupiter.api.Test;
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;
From dd631903130879fdf4122d9b0a122bbb711647ca Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Sat, 14 Feb 2026 05:59:17 +0200
Subject: [PATCH 11/23] Fix incorrect import to use correct DataJpaTest
annotation
---
.../java/bg/softuni/invoice/repository/RoleRepositoryTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/test/java/bg/softuni/invoice/repository/RoleRepositoryTest.java b/src/test/java/bg/softuni/invoice/repository/RoleRepositoryTest.java
index 7770348..4cf667e 100644
--- a/src/test/java/bg/softuni/invoice/repository/RoleRepositoryTest.java
+++ b/src/test/java/bg/softuni/invoice/repository/RoleRepositoryTest.java
@@ -4,7 +4,7 @@
import jakarta.persistence.EntityManager;
import org.junit.jupiter.api.Test;
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;
From a3e2d2925cf48b6a34b6f3b0130425c2256869f5 Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Sat, 14 Feb 2026 06:01:40 +0200
Subject: [PATCH 12/23] Fix incorrect import in LogRepositoryTest
---
.../java/bg/softuni/invoice/repository/LogRepositoryTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/test/java/bg/softuni/invoice/repository/LogRepositoryTest.java b/src/test/java/bg/softuni/invoice/repository/LogRepositoryTest.java
index 060f377..7119912 100644
--- a/src/test/java/bg/softuni/invoice/repository/LogRepositoryTest.java
+++ b/src/test/java/bg/softuni/invoice/repository/LogRepositoryTest.java
@@ -5,7 +5,7 @@
import jakarta.persistence.EntityManager;
import org.junit.jupiter.api.Test;
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.time.LocalDateTime;
import java.util.List;
From d3bbe1db71d9319f050bf5e7ecb54b6c243ba7ec Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Sun, 15 Feb 2026 05:45:11 +0200
Subject: [PATCH 13/23] Fix incorrect import to use correct DataJpaTest
annotation
---
.../java/bg/softuni/invoice/repository/ItemRepositoryTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/test/java/bg/softuni/invoice/repository/ItemRepositoryTest.java b/src/test/java/bg/softuni/invoice/repository/ItemRepositoryTest.java
index 3fd08c5..da8a911 100644
--- a/src/test/java/bg/softuni/invoice/repository/ItemRepositoryTest.java
+++ b/src/test/java/bg/softuni/invoice/repository/ItemRepositoryTest.java
@@ -5,7 +5,7 @@
import jakarta.persistence.EntityManager;
import org.junit.jupiter.api.Test;
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.math.BigDecimal;
import java.util.Optional;
From 35d3b1a3a48c3cee2e12bf74e1e46ddbc56c86e5 Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Sun, 15 Feb 2026 05:48:03 +0200
Subject: [PATCH 14/23] Fix incorrect import in InvoiceRepositoryTest
---
.../bg/softuni/invoice/repository/InvoiceRepositoryTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/test/java/bg/softuni/invoice/repository/InvoiceRepositoryTest.java b/src/test/java/bg/softuni/invoice/repository/InvoiceRepositoryTest.java
index 50cb51d..69525ba 100644
--- a/src/test/java/bg/softuni/invoice/repository/InvoiceRepositoryTest.java
+++ b/src/test/java/bg/softuni/invoice/repository/InvoiceRepositoryTest.java
@@ -9,7 +9,7 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
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.math.BigDecimal;
import java.time.LocalDate;
From 2f1f7c29adcc40e9611a603726cd25888eff8147 Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Sun, 15 Feb 2026 05:52:50 +0200
Subject: [PATCH 15/23] Fix incorrect annotation in CompanyControllerTest and
replace WithMockUser with MockMvc user setup
---
.../web/controller/CompanyControllerTest.java | 20 +++++++++----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/src/test/java/bg/softuni/invoice/web/controller/CompanyControllerTest.java b/src/test/java/bg/softuni/invoice/web/controller/CompanyControllerTest.java
index 37f7147..4b5be1a 100644
--- a/src/test/java/bg/softuni/invoice/web/controller/CompanyControllerTest.java
+++ b/src/test/java/bg/softuni/invoice/web/controller/CompanyControllerTest.java
@@ -10,18 +10,20 @@
import org.mockito.Mockito;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.http.MediaType;
-import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.flash;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
-@WebMvcTest(CompanyController.class)
+@SpringBootTest
+@AutoConfigureMockMvc
class CompanyControllerTest {
@Autowired
@@ -43,7 +45,6 @@ class CompanyControllerTest {
private ItemService itemService;
@Test
- @WithMockUser(roles = {"ADMIN"})
void testAddConfirm_withValidInput_shouldRedirectToAll() throws Exception {
CompanyAddBindingModel validModel = new CompanyAddBindingModel();
validModel.setName("Valid Name");
@@ -59,7 +60,7 @@ void testAddConfirm_withValidInput_shouldRedirectToAll() throws Exception {
Mockito.when(companyService.getCompanyByUniqueIdentifier(validModel.getUniqueIdentifier())).thenReturn(null);
Mockito.when(modelMapper.map(validModel, CompanyServiceModel.class)).thenReturn(serviceModel);
- mockMvc.perform(post("/company/add")
+ mockMvc.perform(post("/company/add").with(user("test-admin").roles("ADMIN"))
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.with(csrf())
.param("name", validModel.getName())
@@ -69,7 +70,6 @@ void testAddConfirm_withValidInput_shouldRedirectToAll() throws Exception {
}
@Test
- @WithMockUser(roles = {"ADMIN"})
void testAddConfirm_withNameConflict_shouldRedirectToAdd() throws Exception {
CompanyAddBindingModel conflictingModel = new CompanyAddBindingModel();
conflictingModel.setName("Existing Company");
@@ -81,7 +81,7 @@ void testAddConfirm_withNameConflict_shouldRedirectToAdd() throws Exception {
Mockito.when(companyService.getCompanyByName(conflictingModel.getName())).thenReturn(conflictingServiceModel);
- mockMvc.perform(post("/company/add")
+ mockMvc.perform(post("/company/add").with(user("test-admin").roles("ADMIN"))
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.with(csrf())
.param("name", conflictingModel.getName())
@@ -93,7 +93,6 @@ void testAddConfirm_withNameConflict_shouldRedirectToAdd() throws Exception {
}
@Test
- @WithMockUser(roles = {"ADMIN"})
void testAddConfirm_withUniqueIdentifierConflict_shouldRedirectToAdd() throws Exception {
CompanyAddBindingModel conflictingModel = new CompanyAddBindingModel();
conflictingModel.setName("New Company");
@@ -106,7 +105,7 @@ void testAddConfirm_withUniqueIdentifierConflict_shouldRedirectToAdd() throws Ex
Mockito.when(companyService.getCompanyByName(conflictingModel.getName())).thenReturn(null);
Mockito.when(companyService.getCompanyByUniqueIdentifier(conflictingModel.getUniqueIdentifier())).thenReturn(conflictingServiceModel);
- mockMvc.perform(post("/company/add")
+ mockMvc.perform(post("/company/add").with(user("test-admin").roles("ADMIN"))
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.with(csrf())
.param("name", conflictingModel.getName())
@@ -118,9 +117,8 @@ void testAddConfirm_withUniqueIdentifierConflict_shouldRedirectToAdd() throws Ex
}
@Test
- @WithMockUser(roles = {"ADMIN"})
void testAddConfirm_withValidationErrors_shouldRedirectToAdd() throws Exception {
- mockMvc.perform(post("/company/add")
+ mockMvc.perform(post("/company/add").with(user("test-admin").roles("ADMIN"))
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.with(csrf())
.param("name", "")
From 7db1700568deca115d2806c649ea9f44744e5ed2 Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Sun, 15 Feb 2026 05:56:54 +0200
Subject: [PATCH 16/23] Fix incorrect imports and assertions
---
.../invoice/web/error/GlobalExceptionHandlerTest.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/test/java/bg/softuni/invoice/web/error/GlobalExceptionHandlerTest.java b/src/test/java/bg/softuni/invoice/web/error/GlobalExceptionHandlerTest.java
index 5278194..b5dfcc5 100644
--- a/src/test/java/bg/softuni/invoice/web/error/GlobalExceptionHandlerTest.java
+++ b/src/test/java/bg/softuni/invoice/web/error/GlobalExceptionHandlerTest.java
@@ -2,8 +2,8 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.Model;
@@ -11,7 +11,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@@ -28,7 +28,7 @@ class GlobalExceptionHandlerTest {
void handleAllErrors_whenFailureUrl_redirectsToLoginPage() throws Exception {
mockMvc.perform(get("/a-nonexistent-url"))
.andExpect(status().is3xxRedirection())
- .andExpect(redirectedUrlPattern("**/user/login"));
+ .andExpect(redirectedUrl("/user/login"));
}
@Test
From 73e3f8ab523e66b6c8a6b008a3f132639abec767 Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Mon, 16 Feb 2026 05:57:19 +0200
Subject: [PATCH 17/23] Remove redundant exception declaration from
configureSecurity method
---
.../java/bg/softuni/invoice/config/SecurityConfiguration.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/bg/softuni/invoice/config/SecurityConfiguration.java b/src/main/java/bg/softuni/invoice/config/SecurityConfiguration.java
index 1d2753b..50a52d8 100644
--- a/src/main/java/bg/softuni/invoice/config/SecurityConfiguration.java
+++ b/src/main/java/bg/softuni/invoice/config/SecurityConfiguration.java
@@ -27,7 +27,7 @@ public class SecurityConfiguration {
private final BCryptPasswordEncoder bCryptPasswordEncoder;
@Bean
- public SecurityFilterChain configureSecurity(HttpSecurity httpSecurity) throws Exception {
+ public SecurityFilterChain configureSecurity(HttpSecurity httpSecurity) {
httpSecurity
.cors(AbstractHttpConfigurer::disable)
.csrf(csrf -> csrf.csrfTokenRepository(csrfTokenRepository()))
From df74baa95b5a15f05eee010804c7c6cb0d0e7e03 Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Mon, 16 Feb 2026 05:58:16 +0200
Subject: [PATCH 18/23] Fix assertion method in InvoiceRepositoryTest
---
.../bg/softuni/invoice/repository/InvoiceRepositoryTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/test/java/bg/softuni/invoice/repository/InvoiceRepositoryTest.java b/src/test/java/bg/softuni/invoice/repository/InvoiceRepositoryTest.java
index 69525ba..523ff34 100644
--- a/src/test/java/bg/softuni/invoice/repository/InvoiceRepositoryTest.java
+++ b/src/test/java/bg/softuni/invoice/repository/InvoiceRepositoryTest.java
@@ -84,7 +84,7 @@ void testGetAllByUser_withDifferentUser_returnsOnlyRelevantInvoices() {
List resultForUser2 = invoiceRepository.getAllByUser(user2);
assertThat(resultForUser1).hasSize(1);
- assertThat(resultForUser1.get(0).getTotalValue()).isEqualByComparingTo("200.00");
+ assertThat(resultForUser1.getFirst().getTotalValue()).isEqualByComparingTo("200.00");
assertThat(resultForUser2).isEmpty();
}
From a40b3a10457eb6ac102ade603f51b043164edd24 Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Mon, 16 Feb 2026 06:01:58 +0200
Subject: [PATCH 19/23] Fix incorrect imports and replace WithMockUser with
MockMvc user setup
---
.../controller/UserControllerTest.java | 31 +++++++++----------
1 file changed, 15 insertions(+), 16 deletions(-)
rename src/test/java/bg/softuni/invoice/{ => web}/controller/UserControllerTest.java (83%)
diff --git a/src/test/java/bg/softuni/invoice/controller/UserControllerTest.java b/src/test/java/bg/softuni/invoice/web/controller/UserControllerTest.java
similarity index 83%
rename from src/test/java/bg/softuni/invoice/controller/UserControllerTest.java
rename to src/test/java/bg/softuni/invoice/web/controller/UserControllerTest.java
index 185b69d..b7a5449 100644
--- a/src/test/java/bg/softuni/invoice/controller/UserControllerTest.java
+++ b/src/test/java/bg/softuni/invoice/web/controller/UserControllerTest.java
@@ -1,4 +1,4 @@
-package bg.softuni.invoice.controller;
+package bg.softuni.invoice.web.controller;
import bg.softuni.invoice.repository.UserRepository;
import bg.softuni.invoice.service.RoleService;
@@ -6,12 +6,12 @@
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl;
@@ -45,10 +45,9 @@ void login_shouldReturnCorrectView() throws Exception {
}
@Test
- @WithMockUser
void login_withLoggedInUserShouldReturnErrorView() throws Exception {
this.mockMvc
- .perform(get("/user/login"))
+ .perform(get("/user/login").with(user("test-user").roles("USER")))
.andExpect(status().is4xxClientError())
.andExpect(forwardedUrl("/error"));
}
@@ -64,7 +63,8 @@ void register_shouldReturnCorrectView() throws Exception {
@Test
void register_registerSuccessfullyRedirect() throws Exception {
this.mockMvc
- .perform(post("/user/register").with(csrf())
+ .perform(post("/user/register")
+ .with(csrf())
.param("username", "admin@admin.com")
.param("firstName", "Admin")
.param("lastName", "Admin")
@@ -80,7 +80,8 @@ void register_registerSuccessfullyRedirect() throws Exception {
@Test
void register_whenBindingResultHasErrorsRedirect() throws Exception {
this.mockMvc
- .perform(post("/user/register").with(csrf())
+ .perform(post("/user/register")
+ .with(csrf())
.param("username", "")
.param("firstName", "")
.param("lastName", "")
@@ -95,7 +96,8 @@ void register_whenBindingResultHasErrorsRedirect() throws Exception {
void register_whenUsernameAlreadyExistsRedirect() throws Exception {
this.mockMvc
- .perform(post("/user/register").with(csrf())
+ .perform(post("/user/register")
+ .with(csrf())
.param("username", "admin@admin.com")
.param("firstName", "Admin")
.param("lastName", "Admin")
@@ -104,7 +106,8 @@ void register_whenUsernameAlreadyExistsRedirect() throws Exception {
);
this.mockMvc
- .perform(post("/user/register").with(csrf())
+ .perform(post("/user/register")
+ .with(csrf())
.param("username", "admin@admin.com")
.param("firstName", "Test")
.param("lastName", "Test")
@@ -116,30 +119,26 @@ void register_whenUsernameAlreadyExistsRedirect() throws Exception {
}
@Test
- @WithMockUser
void register_withLoggedInUserShouldReturnErrorView() throws Exception {
this.mockMvc
- .perform(get("/user/register").with(csrf()))
+ .perform(get("/user/register").with(user("test-user").roles("USER")))
.andExpect(status().is4xxClientError())
.andExpect(forwardedUrl("/error"));
}
@Test
- @WithMockUser(roles = "ROOT")
void all_withLoggedInRootUserShouldReturnCorrectView() throws Exception {
this.mockMvc
- .perform(get("/user/all").with(csrf()))
+ .perform(get("/user/all").with(user("test-root").roles("ROOT")))
.andExpect(model().attributeExists("users"))
.andExpect(model().attributeExists("comparator"))
.andExpect(view().name("user/all"));
}
@Test
- @WithMockUser(roles = "ADMIN")
void all_withLoggedInAdminOrUserShouldReturnCorrectViewAdmin() throws Exception {
this.mockMvc
- .perform(get("/user/all").with(csrf()))
+ .perform(get("/user/all").with(user("test-admin").roles("ADMIN")))
.andExpect(view().name("error"));
}
-
}
From f1923cfb7795c42d632b00671e3f4edb5167755a Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Mon, 16 Feb 2026 06:07:43 +0200
Subject: [PATCH 20/23] Fix incorrect imports and adjust LogControllerTest to
replace WithMockUser with MockMvc user setup
---
.../{ => web}/controller/LogControllerTest.java | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
rename src/test/java/bg/softuni/invoice/{ => web}/controller/LogControllerTest.java (64%)
diff --git a/src/test/java/bg/softuni/invoice/controller/LogControllerTest.java b/src/test/java/bg/softuni/invoice/web/controller/LogControllerTest.java
similarity index 64%
rename from src/test/java/bg/softuni/invoice/controller/LogControllerTest.java
rename to src/test/java/bg/softuni/invoice/web/controller/LogControllerTest.java
index e7ae2a6..81ac88a 100644
--- a/src/test/java/bg/softuni/invoice/controller/LogControllerTest.java
+++ b/src/test/java/bg/softuni/invoice/web/controller/LogControllerTest.java
@@ -1,17 +1,16 @@
-package bg.softuni.invoice.controller;
+package bg.softuni.invoice.web.controller;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.test.web.servlet.MockMvc;
-import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
-
@SpringBootTest
@AutoConfigureMockMvc
class LogControllerTest {
@@ -20,10 +19,10 @@ class LogControllerTest {
private MockMvc mockMvc;
@Test
- @WithMockUser(roles = {"ROOT"})
void all_shouldReturnCorrectView() throws Exception {
this.mockMvc
- .perform(get("/log/all").with(csrf()))
+ .perform(get("/log/all").with(user("test-root").roles("ROOT")))
+ .andExpect(status().isOk())
.andExpect(view().name("log/all"));
}
-}
\ No newline at end of file
+}
From a1bd77de38f70b51d4ba525e2febe567186f6fff Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Tue, 17 Feb 2026 05:03:32 +0200
Subject: [PATCH 21/23] Fix incorrect imports in HomeControllerTest and replace
WithMockUser with MockMvc user setup
---
.../controller/HomeControllerTest.java | 21 +++++++++----------
1 file changed, 10 insertions(+), 11 deletions(-)
rename src/test/java/bg/softuni/invoice/{ => web}/controller/HomeControllerTest.java (73%)
diff --git a/src/test/java/bg/softuni/invoice/controller/HomeControllerTest.java b/src/test/java/bg/softuni/invoice/web/controller/HomeControllerTest.java
similarity index 73%
rename from src/test/java/bg/softuni/invoice/controller/HomeControllerTest.java
rename to src/test/java/bg/softuni/invoice/web/controller/HomeControllerTest.java
index 4ca8c47..23fa6c2 100644
--- a/src/test/java/bg/softuni/invoice/controller/HomeControllerTest.java
+++ b/src/test/java/bg/softuni/invoice/web/controller/HomeControllerTest.java
@@ -1,18 +1,16 @@
-package bg.softuni.invoice.controller;
+package bg.softuni.invoice.web.controller;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.test.web.servlet.MockMvc;
-import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
-
@SpringBootTest
@AutoConfigureMockMvc
class HomeControllerTest {
@@ -24,22 +22,22 @@ class HomeControllerTest {
void index_shouldReturnCorrectView() throws Exception {
this.mockMvc
.perform(get("/"))
+ .andExpect(status().isOk())
.andExpect(view().name("home/index"));
}
@Test
- @WithMockUser
void index_withAuthenticatedUserShouldReturnCorrectView() throws Exception {
this.mockMvc
- .perform(get("/"))
+ .perform(get("/").with(user("test-user").roles("USER")))
+ .andExpect(status().isOk())
.andExpect(view().name("home/home"));
}
@Test
- @WithMockUser()
void home_shouldReturnCorrectView() throws Exception {
this.mockMvc
- .perform(get("/home").with(csrf()))
+ .perform(get("/home").with(user("test-user").roles("USER")))
.andExpect(status().is3xxRedirection())
.andExpect(view().name("redirect:/invoice/all"));
}
@@ -48,14 +46,15 @@ void home_shouldReturnCorrectView() throws Exception {
void index_withNullPrincipal_shouldReturnIndexView() throws Exception {
this.mockMvc
.perform(get("/"))
+ .andExpect(status().isOk())
.andExpect(view().name("home/index"));
}
@Test
- @WithMockUser
void index_withAuthenticatedPrincipal_shouldReturnHomeView() throws Exception {
this.mockMvc
- .perform(get("/"))
+ .perform(get("/").with(user("test-user").roles("USER")))
+ .andExpect(status().isOk())
.andExpect(view().name("home/home"));
}
}
From e7d65d72573bc3be81a7573d177d51a6d7df5530 Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Tue, 17 Feb 2026 05:07:37 +0200
Subject: [PATCH 22/23] Update GitHub Actions workflow to use JDK 21
---
.github/workflows/build.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 76e32f5..1065820 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -13,10 +13,10 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- - name: Set up JDK 17
+ - name: Set up JDK 21
uses: actions/setup-java@v4
with:
- java-version: 17
+ java-version: 21
distribution: 'zulu'
- name: Cache SonarQube packages
uses: actions/cache@v4
From 9b67d4bd434f89b1c7f87db45165ba386ad76aab Mon Sep 17 00:00:00 2001
From: mark79-github <52877024+mark79-github@users.noreply.github.com>
Date: Tue, 17 Feb 2026 05:21:57 +0200
Subject: [PATCH 23/23] Update dependency versions in pom.xml
---
pom.xml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/pom.xml b/pom.xml
index 0d1ce1c..2423941 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,11 +18,11 @@
4.0.2
3.2.6
2.3.2
- 9.5.0
- 42.7.8
+ 9.6.0
+ 42.7.10
3.20.0
0.8.14
- 3.14.1
+ 3.15.0
1.18.42
mark79-github