feat(persons): accept PersonUpdateDTO for POST /api/persons (all 6 fields)
createPerson now takes PersonUpdateDTO, persisting birthYear, deathYear, notes in addition to firstName, lastName, alias. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
||||||
import org.raddatz.familienarchiv.dto.PersonUpdateDTO;
|
import org.raddatz.familienarchiv.dto.PersonUpdateDTO;
|
||||||
import org.raddatz.familienarchiv.model.Document;
|
import org.raddatz.familienarchiv.model.Document;
|
||||||
import org.raddatz.familienarchiv.model.Person;
|
import org.raddatz.familienarchiv.model.Person;
|
||||||
@@ -58,13 +59,14 @@ public class PersonController {
|
|||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
@RequirePermission(Permission.WRITE_ALL)
|
@RequirePermission(Permission.WRITE_ALL)
|
||||||
public ResponseEntity<Person> createPerson(@RequestBody Map<String, String> body) {
|
public ResponseEntity<Person> createPerson(@Valid @RequestBody PersonUpdateDTO dto) {
|
||||||
String firstName = body.get("firstName");
|
if (dto.getFirstName() == null || dto.getFirstName().isBlank()
|
||||||
String lastName = body.get("lastName");
|
|| dto.getLastName() == null || dto.getLastName().isBlank()) {
|
||||||
if (firstName == null || firstName.isBlank() || lastName == null || lastName.isBlank()) {
|
|
||||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Vor- und Nachname sind Pflichtfelder");
|
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Vor- und Nachname sind Pflichtfelder");
|
||||||
}
|
}
|
||||||
return ResponseEntity.ok(personService.createPerson(firstName.trim(), lastName.trim(), body.get("alias")));
|
dto.setFirstName(dto.getFirstName().trim());
|
||||||
|
dto.setLastName(dto.getLastName().trim());
|
||||||
|
return ResponseEntity.ok(personService.createPerson(dto));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/{id}")
|
@PutMapping("/{id}")
|
||||||
|
|||||||
@@ -72,6 +72,20 @@ public class PersonService {
|
|||||||
return personRepository.save(person);
|
return personRepository.save(person);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Person createPerson(PersonUpdateDTO dto) {
|
||||||
|
validateYears(dto.getBirthYear(), dto.getDeathYear());
|
||||||
|
Person person = Person.builder()
|
||||||
|
.firstName(dto.getFirstName())
|
||||||
|
.lastName(dto.getLastName())
|
||||||
|
.alias(dto.getAlias() == null || dto.getAlias().isBlank() ? null : dto.getAlias().trim())
|
||||||
|
.notes(dto.getNotes() == null || dto.getNotes().isBlank() ? null : dto.getNotes().trim())
|
||||||
|
.birthYear(dto.getBirthYear())
|
||||||
|
.deathYear(dto.getDeathYear())
|
||||||
|
.build();
|
||||||
|
return personRepository.save(person);
|
||||||
|
}
|
||||||
|
|
||||||
private void validateYears(Integer birthYear, Integer deathYear) {
|
private void validateYears(Integer birthYear, Integer deathYear) {
|
||||||
if (birthYear != null && birthYear <= 0) {
|
if (birthYear != null && birthYear <= 0) {
|
||||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Geburtsjahr muss eine positive Zahl sein");
|
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Geburtsjahr muss eine positive Zahl sein");
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ class PersonControllerTest {
|
|||||||
@WithMockUser(authorities = "WRITE_ALL")
|
@WithMockUser(authorities = "WRITE_ALL")
|
||||||
void createPerson_returns200_whenValid() throws Exception {
|
void createPerson_returns200_whenValid() throws Exception {
|
||||||
Person saved = Person.builder().id(UUID.randomUUID()).firstName("Hans").lastName("Müller").build();
|
Person saved = Person.builder().id(UUID.randomUUID()).firstName("Hans").lastName("Müller").build();
|
||||||
when(personService.createPerson(eq("Hans"), eq("Müller"), any())).thenReturn(saved);
|
when(personService.createPerson(any(org.raddatz.familienarchiv.dto.PersonUpdateDTO.class))).thenReturn(saved);
|
||||||
|
|
||||||
mockMvc.perform(post("/api/persons")
|
mockMvc.perform(post("/api/persons")
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
@@ -305,6 +305,27 @@ class PersonControllerTest {
|
|||||||
.andExpect(status().isBadRequest());
|
.andExpect(status().isBadRequest());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── Phase 2.2: POST /api/persons with full PersonUpdateDTO ───────────────
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(authorities = "WRITE_ALL")
|
||||||
|
void createPerson_returns200_withAllSixFields() throws Exception {
|
||||||
|
UUID id = UUID.randomUUID();
|
||||||
|
Person saved = Person.builder().id(id).firstName("Maria").lastName("Raddatz")
|
||||||
|
.alias("Oma Maria").birthYear(1901).deathYear(1975).notes("Some notes").build();
|
||||||
|
when(personService.createPerson(any(org.raddatz.familienarchiv.dto.PersonUpdateDTO.class))).thenReturn(saved);
|
||||||
|
|
||||||
|
mockMvc.perform(post("/api/persons")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content("{\"firstName\":\"Maria\",\"lastName\":\"Raddatz\"," +
|
||||||
|
"\"alias\":\"Oma Maria\",\"birthYear\":1901,\"deathYear\":1975," +
|
||||||
|
"\"notes\":\"Some notes\"}"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.firstName").value("Maria"))
|
||||||
|
.andExpect(jsonPath("$.alias").value("Oma Maria"))
|
||||||
|
.andExpect(jsonPath("$.birthYear").value(1901));
|
||||||
|
}
|
||||||
|
|
||||||
// ─── Phase 1.2: @Size constraints ─────────────────────────────────────────
|
// ─── Phase 1.2: @Size constraints ─────────────────────────────────────────
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -110,6 +110,37 @@ class PersonServiceTest {
|
|||||||
assertThat(result.getAlias()).isEqualTo("Hans Müller");
|
assertThat(result.getAlias()).isEqualTo("Hans Müller");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── Phase 2.1: createPerson(PersonUpdateDTO) ─────────────────────────────
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void createPerson_dto_persistsAllSixFields() {
|
||||||
|
when(personRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));
|
||||||
|
|
||||||
|
PersonUpdateDTO dto = new PersonUpdateDTO();
|
||||||
|
dto.setFirstName("Maria"); dto.setLastName("Raddatz"); dto.setAlias("Oma Maria");
|
||||||
|
dto.setBirthYear(1901); dto.setDeathYear(1975); dto.setNotes("Some notes");
|
||||||
|
|
||||||
|
Person result = personService.createPerson(dto);
|
||||||
|
|
||||||
|
assertThat(result.getFirstName()).isEqualTo("Maria");
|
||||||
|
assertThat(result.getLastName()).isEqualTo("Raddatz");
|
||||||
|
assertThat(result.getAlias()).isEqualTo("Oma Maria");
|
||||||
|
assertThat(result.getBirthYear()).isEqualTo(1901);
|
||||||
|
assertThat(result.getDeathYear()).isEqualTo(1975);
|
||||||
|
assertThat(result.getNotes()).isEqualTo("Some notes");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void createPerson_dto_yearValidationFires_whenBirthYearNegative() {
|
||||||
|
PersonUpdateDTO dto = new PersonUpdateDTO();
|
||||||
|
dto.setFirstName("Anna"); dto.setLastName("Test"); dto.setBirthYear(-1);
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> personService.createPerson(dto))
|
||||||
|
.isInstanceOf(ResponseStatusException.class)
|
||||||
|
.extracting(e -> ((ResponseStatusException) e).getStatusCode().value())
|
||||||
|
.isEqualTo(400);
|
||||||
|
}
|
||||||
|
|
||||||
// ─── updatePerson (alias) ─────────────────────────────────────────────────
|
// ─── updatePerson (alias) ─────────────────────────────────────────────────
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user