From 10e980328d7d51ad4f85c42fda48462daac12a4f Mon Sep 17 00:00:00 2001 From: Marcel Date: Sat, 18 Apr 2026 20:35:03 +0200 Subject: [PATCH] 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 --- .../familienarchiv/service/UserService.java | 8 +++---- .../service/UserServiceTest.java | 24 +++++++++---------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/backend/src/main/java/org/raddatz/familienarchiv/service/UserService.java b/backend/src/main/java/org/raddatz/familienarchiv/service/UserService.java index fd639751..d7046243 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/service/UserService.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/service/UserService.java @@ -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()); diff --git a/backend/src/test/java/org/raddatz/familienarchiv/service/UserServiceTest.java b/backend/src/test/java/org/raddatz/familienarchiv/service/UserServiceTest.java index 954614ea..317e206e 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/service/UserServiceTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/service/UserServiceTest.java @@ -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