feat(#68): fall back to filename as title when createDocument gets no title
When a document is created without an explicit title (null or blank), the service now derives the title from the uploaded filename using the same titleFromFilename() logic already used by storeDocument — stripping the extension for plain names and formatting structured names as "Firstname Lastname (DD.MM.YYYY)". Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -108,9 +108,13 @@ public class DocumentService {
|
|||||||
|| (dto.getReceiverIds() != null && !dto.getReceiverIds().isEmpty());
|
|| (dto.getReceiverIds() != null && !dto.getReceiverIds().isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String titleToUse = (dto.getTitle() != null && !dto.getTitle().isBlank())
|
||||||
|
? dto.getTitle()
|
||||||
|
: titleFromFilename(filename);
|
||||||
|
|
||||||
Document doc = Document.builder()
|
Document doc = Document.builder()
|
||||||
.originalFilename(filename)
|
.originalFilename(filename)
|
||||||
.title(dto.getTitle())
|
.title(titleToUse)
|
||||||
.documentDate(dto.getDocumentDate())
|
.documentDate(dto.getDocumentDate())
|
||||||
.location(dto.getLocation())
|
.location(dto.getLocation())
|
||||||
.documentLocation(dto.getDocumentLocation())
|
.documentLocation(dto.getDocumentLocation())
|
||||||
|
|||||||
@@ -467,6 +467,62 @@ class DocumentServiceTest {
|
|||||||
assertThat(captor.getValue().getSender()).isNull();
|
assertThat(captor.getValue().getSender()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── createDocument title fallback ────────────────────────────────────────
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void createDocument_usesTitleFromFilename_whenDtoTitleIsNull() throws Exception {
|
||||||
|
DocumentUpdateDTO dto = new DocumentUpdateDTO();
|
||||||
|
// dto.title is null
|
||||||
|
MockMultipartFile file = new MockMultipartFile("file", "Brief_1965.pdf", "application/pdf", new byte[]{1});
|
||||||
|
Document saved = Document.builder().id(UUID.randomUUID()).title("Brief_1965")
|
||||||
|
.originalFilename("Brief_1965.pdf").status(DocumentStatus.PLACEHOLDER).build();
|
||||||
|
when(documentRepository.save(any())).thenReturn(saved);
|
||||||
|
when(documentRepository.findById(any())).thenReturn(Optional.of(saved));
|
||||||
|
when(fileService.uploadFile(any(), any())).thenReturn(new FileService.UploadResult("path", "hash"));
|
||||||
|
|
||||||
|
ArgumentCaptor<Document> captor = ArgumentCaptor.forClass(Document.class);
|
||||||
|
documentService.createDocument(dto, file);
|
||||||
|
|
||||||
|
verify(documentRepository, atLeastOnce()).save(captor.capture());
|
||||||
|
assertThat(captor.getAllValues().get(0).getTitle()).isEqualTo("Brief_1965");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void createDocument_usesTitleFromFilename_whenDtoTitleIsBlank() throws Exception {
|
||||||
|
DocumentUpdateDTO dto = new DocumentUpdateDTO();
|
||||||
|
dto.setTitle(" ");
|
||||||
|
MockMultipartFile file = new MockMultipartFile("file", "Rechnung_1980.pdf", "application/pdf", new byte[]{1});
|
||||||
|
Document saved = Document.builder().id(UUID.randomUUID()).title("Rechnung_1980")
|
||||||
|
.originalFilename("Rechnung_1980.pdf").status(DocumentStatus.PLACEHOLDER).build();
|
||||||
|
when(documentRepository.save(any())).thenReturn(saved);
|
||||||
|
when(documentRepository.findById(any())).thenReturn(Optional.of(saved));
|
||||||
|
when(fileService.uploadFile(any(), any())).thenReturn(new FileService.UploadResult("path", "hash"));
|
||||||
|
|
||||||
|
ArgumentCaptor<Document> captor = ArgumentCaptor.forClass(Document.class);
|
||||||
|
documentService.createDocument(dto, file);
|
||||||
|
|
||||||
|
verify(documentRepository, atLeastOnce()).save(captor.capture());
|
||||||
|
assertThat(captor.getAllValues().get(0).getTitle()).isEqualTo("Rechnung_1980");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void createDocument_keepsDtoTitle_whenProvided() throws Exception {
|
||||||
|
DocumentUpdateDTO dto = new DocumentUpdateDTO();
|
||||||
|
dto.setTitle("Mein Titel");
|
||||||
|
MockMultipartFile file = new MockMultipartFile("file", "scan.pdf", "application/pdf", new byte[]{1});
|
||||||
|
Document saved = Document.builder().id(UUID.randomUUID()).title("Mein Titel")
|
||||||
|
.originalFilename("scan.pdf").status(DocumentStatus.PLACEHOLDER).build();
|
||||||
|
when(documentRepository.save(any())).thenReturn(saved);
|
||||||
|
when(documentRepository.findById(any())).thenReturn(Optional.of(saved));
|
||||||
|
when(fileService.uploadFile(any(), any())).thenReturn(new FileService.UploadResult("path", "hash"));
|
||||||
|
|
||||||
|
ArgumentCaptor<Document> captor = ArgumentCaptor.forClass(Document.class);
|
||||||
|
documentService.createDocument(dto, file);
|
||||||
|
|
||||||
|
verify(documentRepository, atLeastOnce()).save(captor.capture());
|
||||||
|
assertThat(captor.getAllValues().get(0).getTitle()).isEqualTo("Mein Titel");
|
||||||
|
}
|
||||||
|
|
||||||
// ─── createDocument metadataComplete ─────────────────────────────────────
|
// ─── createDocument metadataComplete ─────────────────────────────────────
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user