test(document): close review-flagged coverage gaps for auto-title sync (#726)
- save-time: precision+raw carry-over when the DTO omits them (exercises the shared skip-null resolvers), and a RANGE label round-trip (Sara/Elicit) - factory: a bare Document with a null index builds "" rather than NPE-ing (Felix) - backfill matcher: negative near-misses — ASCII hyphen vs en dash, missing separator before trailing text, year-with-trailing-letters, index followed by text without a separator (Sara) - backfill integration: tighten the count assertion to exactly 1 on the clean test DB (Sara) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -371,6 +371,43 @@ class DocumentServiceTest {
|
||||
assertThat(stored.getTitle()).isEqualTo("C-0029 – Frühling 1943");
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateDocument_carriesStoredPrecisionAndRaw_whenDtoOmitsThem() throws Exception {
|
||||
// Only the year changes; precision/end/raw are omitted from the DTO, so projectedState
|
||||
// must carry them from the entity (exercises the skip-null effective* resolvers).
|
||||
Document stored = makeStored("C-0029", LocalDate.of(1943, 4, 1), DatePrecision.SEASON, null);
|
||||
stored.setMetaDateRaw("Frühling 1943");
|
||||
stored.setTitle(documentTitleFactory.build(stored)); // "C-0029 – Frühling 1943"
|
||||
DocumentUpdateDTO dto = editDto(stored.getTitle(), LocalDate.of(1944, 4, 1), null, null);
|
||||
|
||||
runUpdate(stored, dto);
|
||||
|
||||
assertThat(stored.getTitle()).isEqualTo("C-0029 – Frühling 1944");
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateDocument_roundTripsRangeLabel_atSaveTime() throws Exception {
|
||||
Document stored = Document.builder()
|
||||
.id(UUID.randomUUID())
|
||||
.originalFilename("C-0029")
|
||||
.documentDate(LocalDate.of(1917, 1, 10))
|
||||
.metaDatePrecision(DatePrecision.RANGE)
|
||||
.metaDateEnd(LocalDate.of(1917, 1, 11))
|
||||
.receivers(new HashSet<>())
|
||||
.tags(new HashSet<>())
|
||||
.build();
|
||||
stored.setTitle(documentTitleFactory.build(stored)); // "C-0029 – 10.–11. Jan. 1917"
|
||||
DocumentUpdateDTO dto = new DocumentUpdateDTO();
|
||||
dto.setTitle(stored.getTitle());
|
||||
dto.setDocumentDate(LocalDate.of(1918, 1, 10));
|
||||
dto.setMetaDatePrecision(DatePrecision.RANGE);
|
||||
dto.setMetaDateEnd(LocalDate.of(1918, 1, 11));
|
||||
|
||||
runUpdate(stored, dto);
|
||||
|
||||
assertThat(stored.getTitle()).isEqualTo("C-0029 – 10.–11. Jan. 1918");
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateDocument_doesNotRegenerateToBlank_whenSubmittedTitleEmpty() throws Exception {
|
||||
Document stored = makeStored("C-0029", LocalDate.of(1928, 1, 1), DatePrecision.YEAR, "Berlin");
|
||||
|
||||
@@ -52,7 +52,7 @@ class DocumentTitleBackfillIntegrationTest {
|
||||
|
||||
int count = documentService.backfillTitles();
|
||||
|
||||
assertThat(count).isGreaterThanOrEqualTo(1);
|
||||
assertThat(count).isEqualTo(1); // exactly the one stale row seeded (clean test DB)
|
||||
assertThat(documentRepository.findById(stale.getId()).orElseThrow().getTitle())
|
||||
.isEqualTo("C-0029 – 1928 – Berlin");
|
||||
}
|
||||
|
||||
@@ -118,6 +118,30 @@ class DocumentTitleBackfillMatcherTest {
|
||||
assertThat(overwritable("Ganz anderer Titel", null)).isFalse();
|
||||
}
|
||||
|
||||
// ─── near-miss: shapes that look almost machine-built but are not ──────────
|
||||
|
||||
@Test
|
||||
void ascii_hyphen_instead_of_en_dash_separator_is_skipped() {
|
||||
// The separator is " – " (en dash); a plain " - " is not the machine separator.
|
||||
assertThat(overwritable("C-0029 - 1916", null)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void date_label_without_separator_before_trailing_text_is_skipped() {
|
||||
// "1916 Berlin" is not a date label and is not joined by " – "; prose, not machine.
|
||||
assertThat(overwritable("C-0029 – 1916 Berlin", null)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void year_with_trailing_letters_is_not_a_year_label() {
|
||||
assertThat(overwritable("C-0029 – 1916er Brief", null)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void index_immediately_followed_by_text_without_separator_is_skipped() {
|
||||
assertThat(overwritable("C-0029x – 1916", null)).isFalse();
|
||||
}
|
||||
|
||||
// ─── fail-closed guards ───────────────────────────────────────────────────
|
||||
|
||||
@Test
|
||||
|
||||
@@ -71,6 +71,13 @@ class DocumentTitleFactoryTest {
|
||||
assertThat(factory.build(d)).isEqualTo("C-0029 – 1928");
|
||||
}
|
||||
|
||||
@Test
|
||||
void bare_document_with_null_index_builds_empty_string_not_npe() {
|
||||
// originalFilename is NOT NULL in production; the guard keeps a synthetic/partial entity
|
||||
// from tripping StringBuilder(null) with an opaque NPE.
|
||||
assertThat(factory.build(Document.builder().build())).isEqualTo("");
|
||||
}
|
||||
|
||||
@Test
|
||||
void day_precision_renders_the_full_german_label() {
|
||||
Document d = doc("C-0029")
|
||||
|
||||
Reference in New Issue
Block a user