|
|
@@ -1,7 +1,7 @@
|
|
|
package com.danielbohry.authservice.api;
|
|
|
|
|
|
import com.danielbohry.authservice.api.dto.AuthenticationResponse;
|
|
|
-import com.danielbohry.authservice.api.dto.PasswordChangeRequest;
|
|
|
+import com.danielbohry.authservice.api.dto.ProfileUpdateRequest;
|
|
|
import com.danielbohry.authservice.api.dto.UserResponse;
|
|
|
import com.danielbohry.authservice.domain.ApplicationUser;
|
|
|
import com.danielbohry.authservice.domain.Role;
|
|
|
@@ -22,9 +22,10 @@ import java.util.List;
|
|
|
|
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
|
import static org.mockito.ArgumentMatchers.anyString;
|
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
|
import static org.mockito.Mockito.*;
|
|
|
|
|
|
-class UserControllerUnitTest {
|
|
|
+class UserControllerTest {
|
|
|
|
|
|
@Mock
|
|
|
private AuthService authService;
|
|
|
@@ -34,7 +35,7 @@ class UserControllerUnitTest {
|
|
|
|
|
|
private ApplicationUser testUser;
|
|
|
private ApplicationUser adminUser;
|
|
|
- private PasswordChangeRequest passwordChangeRequest;
|
|
|
+ private ProfileUpdateRequest profileUpdateRequest;
|
|
|
private AuthenticationResponse authResponse;
|
|
|
|
|
|
@BeforeEach
|
|
|
@@ -59,11 +60,15 @@ class UserControllerUnitTest {
|
|
|
.active(true)
|
|
|
.build();
|
|
|
|
|
|
- passwordChangeRequest = new PasswordChangeRequest("oldPassword", "newPassword");
|
|
|
+ profileUpdateRequest = new ProfileUpdateRequest();
|
|
|
+ profileUpdateRequest.setCurrentPassword("oldPassword");
|
|
|
+ profileUpdateRequest.setNewPassword("newPassword");
|
|
|
+ profileUpdateRequest.setEmail("newemail@example.com");
|
|
|
|
|
|
authResponse = AuthenticationResponse.builder()
|
|
|
.id("user-id-123")
|
|
|
.username("testuser")
|
|
|
+ .email("test@example.com")
|
|
|
.token("new-jwt-token-123")
|
|
|
.expirationDate(Instant.now().plusSeconds(3600))
|
|
|
.roles(List.of("ROLE_USER"))
|
|
|
@@ -130,30 +135,31 @@ class UserControllerUnitTest {
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- void shouldChangePasswordSuccessfully() {
|
|
|
+ void shouldUpdateProfileSuccessfully() {
|
|
|
// given
|
|
|
mockSecurityContext(testUser);
|
|
|
- when(authService.changePassword(anyString(), anyString(), anyString()))
|
|
|
+ when(authService.updateProfile(anyString(), anyString(), anyString(), anyString()))
|
|
|
.thenReturn(authResponse);
|
|
|
|
|
|
// when
|
|
|
- ResponseEntity<AuthenticationResponse> response = userController.changePassword(passwordChangeRequest);
|
|
|
+ ResponseEntity<AuthenticationResponse> response = userController.updateProfile(profileUpdateRequest);
|
|
|
|
|
|
// then
|
|
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
|
|
assertNotNull(response.getBody());
|
|
|
assertEquals("user-id-123", response.getBody().getId());
|
|
|
assertEquals("testuser", response.getBody().getUsername());
|
|
|
+ assertEquals("test@example.com", response.getBody().getEmail());
|
|
|
assertEquals("new-jwt-token-123", response.getBody().getToken());
|
|
|
|
|
|
- verify(authService).changePassword("user-id-123", "oldPassword", "newPassword");
|
|
|
+ verify(authService).updateProfile("user-id-123", "oldPassword", "newPassword", "newemail@example.com");
|
|
|
|
|
|
// cleanup
|
|
|
SecurityContextHolder.clearContext();
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- void shouldRejectPasswordChangeWhenNotAuthenticated() {
|
|
|
+ void shouldRejectProfileUpdateWhenNotAuthenticated() {
|
|
|
// given - no authentication in security context
|
|
|
SecurityContext securityContext = mock(SecurityContext.class);
|
|
|
Authentication authentication = mock(Authentication.class);
|
|
|
@@ -162,7 +168,7 @@ class UserControllerUnitTest {
|
|
|
SecurityContextHolder.setContext(securityContext);
|
|
|
|
|
|
// when
|
|
|
- ResponseEntity<AuthenticationResponse> response = userController.changePassword(passwordChangeRequest);
|
|
|
+ ResponseEntity<AuthenticationResponse> response = userController.updateProfile(profileUpdateRequest);
|
|
|
|
|
|
// then
|
|
|
assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode());
|
|
|
@@ -172,18 +178,18 @@ class UserControllerUnitTest {
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- void shouldHandlePasswordChangeServiceError() {
|
|
|
+ void shouldHandleProfileUpdateServiceError() {
|
|
|
// given
|
|
|
mockSecurityContext(testUser);
|
|
|
- when(authService.changePassword(anyString(), anyString(), anyString()))
|
|
|
+ when(authService.updateProfile(anyString(), anyString(), anyString(), anyString()))
|
|
|
.thenThrow(new RuntimeException("Service error"));
|
|
|
|
|
|
// when/then
|
|
|
assertThrows(RuntimeException.class, () -> {
|
|
|
- userController.changePassword(passwordChangeRequest);
|
|
|
+ userController.updateProfile(profileUpdateRequest);
|
|
|
});
|
|
|
|
|
|
- verify(authService).changePassword("user-id-123", "oldPassword", "newPassword");
|
|
|
+ verify(authService).updateProfile("user-id-123", "oldPassword", "newPassword", "newemail@example.com");
|
|
|
|
|
|
// cleanup
|
|
|
SecurityContextHolder.clearContext();
|
|
|
@@ -219,29 +225,140 @@ class UserControllerUnitTest {
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- void shouldReturnNewTokenAfterPasswordChange() {
|
|
|
+ void shouldReturnNewTokenAfterProfileUpdate() {
|
|
|
// given
|
|
|
mockSecurityContext(testUser);
|
|
|
AuthenticationResponse newTokenResponse = AuthenticationResponse.builder()
|
|
|
.id("user-id-123")
|
|
|
.username("testuser")
|
|
|
+ .email("test@example.com")
|
|
|
.token("brand-new-jwt-token")
|
|
|
.expirationDate(Instant.now().plusSeconds(7200))
|
|
|
.roles(List.of("ROLE_USER"))
|
|
|
.build();
|
|
|
|
|
|
- when(authService.changePassword(anyString(), anyString(), anyString()))
|
|
|
+ when(authService.updateProfile(anyString(), anyString(), anyString(), anyString()))
|
|
|
.thenReturn(newTokenResponse);
|
|
|
|
|
|
// when
|
|
|
- ResponseEntity<AuthenticationResponse> response = userController.changePassword(passwordChangeRequest);
|
|
|
+ ResponseEntity<AuthenticationResponse> response = userController.updateProfile(profileUpdateRequest);
|
|
|
|
|
|
// then
|
|
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
|
|
assertEquals("brand-new-jwt-token", response.getBody().getToken());
|
|
|
assertNotNull(response.getBody().getExpirationDate());
|
|
|
|
|
|
- verify(authService).changePassword("user-id-123", "oldPassword", "newPassword");
|
|
|
+ verify(authService).updateProfile("user-id-123", "oldPassword", "newPassword", "newemail@example.com");
|
|
|
+
|
|
|
+ // cleanup
|
|
|
+ SecurityContextHolder.clearContext();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void shouldUpdateEmailOnly() {
|
|
|
+ // given
|
|
|
+ mockSecurityContext(testUser);
|
|
|
+ ProfileUpdateRequest emailOnlyRequest = new ProfileUpdateRequest();
|
|
|
+ emailOnlyRequest.setCurrentPassword("oldPassword");
|
|
|
+ emailOnlyRequest.setEmail("new-email@example.com");
|
|
|
+ // newPassword is null - email only update
|
|
|
+
|
|
|
+ when(authService.updateProfile(anyString(), anyString(), any(), anyString()))
|
|
|
+ .thenReturn(authResponse);
|
|
|
+
|
|
|
+ // when
|
|
|
+ ResponseEntity<AuthenticationResponse> response = userController.updateProfile(emailOnlyRequest);
|
|
|
+
|
|
|
+ // then
|
|
|
+ assertEquals(HttpStatus.OK, response.getStatusCode());
|
|
|
+ assertNotNull(response.getBody());
|
|
|
+ assertEquals("test@example.com", response.getBody().getEmail());
|
|
|
+
|
|
|
+ verify(authService).updateProfile("user-id-123", "oldPassword", null, "new-email@example.com");
|
|
|
+
|
|
|
+ // cleanup
|
|
|
+ SecurityContextHolder.clearContext();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void shouldUpdatePasswordOnly() {
|
|
|
+ // given
|
|
|
+ mockSecurityContext(testUser);
|
|
|
+ ProfileUpdateRequest passwordOnlyRequest = new ProfileUpdateRequest();
|
|
|
+ passwordOnlyRequest.setCurrentPassword("oldPassword");
|
|
|
+ passwordOnlyRequest.setNewPassword("newPassword123");
|
|
|
+ // email is null - password only update
|
|
|
+
|
|
|
+ when(authService.updateProfile(anyString(), anyString(), anyString(), any()))
|
|
|
+ .thenReturn(authResponse);
|
|
|
+
|
|
|
+ // when
|
|
|
+ ResponseEntity<AuthenticationResponse> response = userController.updateProfile(passwordOnlyRequest);
|
|
|
+
|
|
|
+ // then
|
|
|
+ assertEquals(HttpStatus.OK, response.getStatusCode());
|
|
|
+ assertNotNull(response.getBody());
|
|
|
+ assertEquals("new-jwt-token-123", response.getBody().getToken());
|
|
|
+
|
|
|
+ verify(authService).updateProfile("user-id-123", "oldPassword", "newPassword123", null);
|
|
|
+
|
|
|
+ // cleanup
|
|
|
+ SecurityContextHolder.clearContext();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void shouldUpdateBothEmailAndPassword() {
|
|
|
+ // given
|
|
|
+ mockSecurityContext(testUser);
|
|
|
+ ProfileUpdateRequest bothRequest = new ProfileUpdateRequest();
|
|
|
+ bothRequest.setCurrentPassword("oldPassword");
|
|
|
+ bothRequest.setNewPassword("newPassword123");
|
|
|
+ bothRequest.setEmail("updated@example.com");
|
|
|
+
|
|
|
+ AuthenticationResponse updatedResponse = AuthenticationResponse.builder()
|
|
|
+ .id("user-id-123")
|
|
|
+ .username("testuser")
|
|
|
+ .email("updated@example.com")
|
|
|
+ .token("updated-jwt-token")
|
|
|
+ .expirationDate(Instant.now().plusSeconds(3600))
|
|
|
+ .roles(List.of("ROLE_USER"))
|
|
|
+ .build();
|
|
|
+
|
|
|
+ when(authService.updateProfile(anyString(), anyString(), anyString(), anyString()))
|
|
|
+ .thenReturn(updatedResponse);
|
|
|
+
|
|
|
+ // when
|
|
|
+ ResponseEntity<AuthenticationResponse> response = userController.updateProfile(bothRequest);
|
|
|
+
|
|
|
+ // then
|
|
|
+ assertEquals(HttpStatus.OK, response.getStatusCode());
|
|
|
+ assertNotNull(response.getBody());
|
|
|
+ assertEquals("updated@example.com", response.getBody().getEmail());
|
|
|
+ assertEquals("updated-jwt-token", response.getBody().getToken());
|
|
|
+
|
|
|
+ verify(authService).updateProfile("user-id-123", "oldPassword", "newPassword123", "updated@example.com");
|
|
|
+
|
|
|
+ // cleanup
|
|
|
+ SecurityContextHolder.clearContext();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void shouldHandleNullFieldsInProfileUpdate() {
|
|
|
+ // given
|
|
|
+ mockSecurityContext(testUser);
|
|
|
+ ProfileUpdateRequest minimalRequest = new ProfileUpdateRequest();
|
|
|
+ minimalRequest.setCurrentPassword("oldPassword");
|
|
|
+ // both newPassword and email are null
|
|
|
+
|
|
|
+ when(authService.updateProfile(anyString(), anyString(), any(), any()))
|
|
|
+ .thenReturn(authResponse);
|
|
|
+
|
|
|
+ // when
|
|
|
+ ResponseEntity<AuthenticationResponse> response = userController.updateProfile(minimalRequest);
|
|
|
+
|
|
|
+ // then
|
|
|
+ assertEquals(HttpStatus.OK, response.getStatusCode());
|
|
|
+ verify(authService).updateProfile("user-id-123", "oldPassword", null, null);
|
|
|
|
|
|
// cleanup
|
|
|
SecurityContextHolder.clearContext();
|