test(person): tighten generation null-clear coverage (#689)
Sara's QA concerns: 1. PersonControllerTest.updatePerson_returns200_whenGenerationNull was asymmetric — only checked status 200, no body assertion. Now also asserts `$.generation` is null in the JSON response, mirroring the in-range test's body check. 2. New full-stack PUT→DB→GET round-trip in PersonServiceIntegrationTest (updatePerson_clearGenerationToNull_readsBackNullFromDb) seeds a person with generation=3, calls updatePerson with generation=null, flushes the persistence context, and asserts the column reads back null from the DB. Without this we only had the mocked WebMvcTest boundary; nothing proved JPA actually wrote SQL NULL. 3. Sibling test (updatePerson_setGenerationToZero_readsBackZeroFromDb) pins the G 0 end-to-end so a primitive zero can't silently coerce to null anywhere along controller → service → JPA. Refs #689 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -746,6 +746,10 @@ class PersonControllerTest {
|
||||
@Test
|
||||
@WithMockUser(authorities = "WRITE_ALL")
|
||||
void updatePerson_returns200_whenGenerationNull() throws Exception {
|
||||
// Symmetric body assertion: the response must echo generation as null (not
|
||||
// absent), so the frontend re-hydrates the "(none)" option after a clear.
|
||||
// Without this, the in-range test below would be the only end-to-end proof
|
||||
// that the field flows through the controller.
|
||||
Person saved = Person.builder().id(UUID.randomUUID()).firstName("Hans").lastName("Müller").build();
|
||||
when(personService.updatePerson(any(), any())).thenReturn(saved);
|
||||
|
||||
@@ -753,7 +757,8 @@ class PersonControllerTest {
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("{\"firstName\":\"Hans\",\"lastName\":\"Müller\","
|
||||
+ "\"personType\":\"PERSON\",\"generation\":null}"))
|
||||
.andExpect(status().isOk());
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.generation").value(org.hamcrest.Matchers.nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -124,6 +124,59 @@ class PersonServiceIntegrationTest {
|
||||
assertThat(personRepository.findById(target.getId())).isEmpty();
|
||||
}
|
||||
|
||||
// ─── generation full-stack round-trip (#689) ──────────────────────────────
|
||||
|
||||
@Test
|
||||
void updatePerson_clearGenerationToNull_readsBackNullFromDb() {
|
||||
// Sara's QA concern: pin the full PUT→DB→GET round-trip for the
|
||||
// null-clear path. Without this we only have the WebMvcTest mocked
|
||||
// boundary; nothing proved the JPA flush actually wrote SQL NULL.
|
||||
Person seeded = personRepository.save(Person.builder()
|
||||
.firstName("Hans").lastName("Raddatz")
|
||||
.personType(PersonType.PERSON).generation(3).build());
|
||||
entityManager.flush();
|
||||
entityManager.clear();
|
||||
|
||||
PersonUpdateDTO dto = new PersonUpdateDTO();
|
||||
dto.setPersonType(PersonType.PERSON);
|
||||
dto.setFirstName("Hans");
|
||||
dto.setLastName("Raddatz");
|
||||
dto.setGeneration(null);
|
||||
|
||||
personService.updatePerson(seeded.getId(), dto);
|
||||
entityManager.flush();
|
||||
entityManager.clear();
|
||||
|
||||
Person reloaded = personRepository.findById(seeded.getId()).orElseThrow();
|
||||
assertThat(reloaded.getGeneration()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void updatePerson_setGenerationToZero_readsBackZeroFromDb() {
|
||||
// Pin the G 0 case end-to-end. The form-action spec covers that 0
|
||||
// doesn't get spread-dropped at the SvelteKit boundary; this test
|
||||
// covers that the controller + service + JPA chain preserves the
|
||||
// primitive zero (not coerced to null somewhere along the way).
|
||||
Person seeded = personRepository.save(Person.builder()
|
||||
.firstName("Walter").lastName("Raddatz")
|
||||
.personType(PersonType.PERSON).build());
|
||||
entityManager.flush();
|
||||
entityManager.clear();
|
||||
|
||||
PersonUpdateDTO dto = new PersonUpdateDTO();
|
||||
dto.setPersonType(PersonType.PERSON);
|
||||
dto.setFirstName("Walter");
|
||||
dto.setLastName("Raddatz");
|
||||
dto.setGeneration(0);
|
||||
|
||||
personService.updatePerson(seeded.getId(), dto);
|
||||
entityManager.flush();
|
||||
entityManager.clear();
|
||||
|
||||
Person reloaded = personRepository.findById(seeded.getId()).orElseThrow();
|
||||
assertThat(reloaded.getGeneration()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void deletePerson_detachesSentAndReceivedReferences_beforeDelete_noOrphan() {
|
||||
// A person referenced as BOTH a document sender and a document receiver must delete
|
||||
|
||||
Reference in New Issue
Block a user