feat(users): reject blank email in updateProfile and adminUpdateUser

Previously a blank email string would silently set email to null,
which would cause a DB constraint violation after V44 migration.
Now throws DomainException.badRequest instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-18 20:35:03 +02:00
committed by marcel
parent 79259aa348
commit c4444a07d1
2 changed files with 15 additions and 17 deletions

View File

@@ -103,8 +103,8 @@ public class UserService {
}
});
user.setEmail(dto.getEmail().trim());
} else if (dto.getEmail() != null && dto.getEmail().isBlank()) {
user.setEmail(null);
} else if (dto.getEmail() != null) {
throw DomainException.badRequest(ErrorCode.VALIDATION_ERROR, "Email must not be blank");
}
user.setFirstName(dto.getFirstName());
@@ -126,8 +126,8 @@ public class UserService {
}
});
user.setEmail(dto.getEmail().trim());
} else if (dto.getEmail() != null && dto.getEmail().isBlank()) {
user.setEmail(null);
} else if (dto.getEmail() != null) {
throw DomainException.badRequest(ErrorCode.VALIDATION_ERROR, "Email must not be blank");
}
user.setFirstName(dto.getFirstName());

View File

@@ -328,18 +328,17 @@ class UserServiceTest {
// ─── updateProfile — email edge cases ─────────────────────────────────────
@Test
void updateProfile_setsEmailToNull_whenEmailIsBlank() {
void updateProfile_throwsBadRequest_whenEmailIsBlank() {
UUID id = UUID.randomUUID();
AppUser user = AppUser.builder().id(id).username("max").email("old@example.com").build();
AppUser user = AppUser.builder().id(id).email("old@example.com").build();
when(userRepository.findById(id)).thenReturn(Optional.of(user));
when(userRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));
UpdateProfileDTO dto = new UpdateProfileDTO();
dto.setEmail(" "); // blank — should clear email
dto.setEmail(" ");
AppUser result = userService.updateProfile(id, dto);
assertThat(result.getEmail()).isNull();
assertThatThrownBy(() -> userService.updateProfile(id, dto))
.isInstanceOf(DomainException.class)
.hasMessageContaining("blank");
}
@Test
@@ -407,18 +406,17 @@ class UserServiceTest {
}
@Test
void adminUpdateUser_setsEmailToNull_whenEmailIsBlank() {
void adminUpdateUser_throwsBadRequest_whenEmailIsBlank() {
UUID id = UUID.randomUUID();
AppUser user = AppUser.builder().id(id).username("admin").email("old@example.com").build();
AppUser user = AppUser.builder().id(id).email("old@example.com").build();
when(userRepository.findById(id)).thenReturn(Optional.of(user));
when(userRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));
AdminUpdateUserRequest dto = new AdminUpdateUserRequest();
dto.setEmail(" ");
AppUser result = userService.adminUpdateUser(id, dto);
assertThat(result.getEmail()).isNull();
assertThatThrownBy(() -> userService.adminUpdateUser(id, dto))
.isInstanceOf(DomainException.class)
.hasMessageContaining("blank");
}
@Test