refactor(document): extract a SearchFilters record for the document search signatures (#683) #702
@@ -24,6 +24,7 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.raddatz.familienarchiv.document.SearchFiltersFixtures.noFilters;
|
||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -122,7 +123,7 @@ class DocumentLazyLoadingTest {
|
||||
savedDocument("SrDoc", "sr_doc.pdf", sender, Set.of(receiver), Set.of(tag));
|
||||
|
||||
DocumentSearchResult result = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.RECEIVER, "asc", PageRequest.of(0, 20));
|
||||
assertThat(result.totalElements()).isGreaterThan(0);
|
||||
assertThatCode(() ->
|
||||
@@ -137,7 +138,7 @@ class DocumentLazyLoadingTest {
|
||||
savedDocument("SsDoc", "ss_doc.pdf", sender, Set.of(), Set.of(tag));
|
||||
|
||||
assertThatCode(() -> documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.SENDER, "asc", PageRequest.of(0, 20)))
|
||||
.doesNotThrowAnyException();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.raddatz.familienarchiv.document.SearchFiltersFixtures.noFilters;
|
||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
|
||||
/**
|
||||
@@ -55,7 +56,7 @@ class DocumentListItemIntegrationTest {
|
||||
.build());
|
||||
|
||||
assertThatCode(() -> documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.DATE, "DESC", PageRequest.of(0, 50)))
|
||||
.doesNotThrowAnyException();
|
||||
}
|
||||
@@ -70,7 +71,7 @@ class DocumentListItemIntegrationTest {
|
||||
.build());
|
||||
|
||||
DocumentSearchResult result = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.DATE, "DESC", PageRequest.of(0, 50));
|
||||
|
||||
assertThat(result.totalElements()).isGreaterThan(0);
|
||||
@@ -91,7 +92,7 @@ class DocumentListItemIntegrationTest {
|
||||
.build());
|
||||
|
||||
DocumentSearchResult result = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.DATE, "DESC", PageRequest.of(0, 50));
|
||||
|
||||
DocumentListItem item = result.items().stream()
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.raddatz.familienarchiv.document.SearchFiltersFixtures.noFilters;
|
||||
|
||||
/**
|
||||
* End-to-end paged search test with real PostgreSQL (Testcontainers). Covers the
|
||||
@@ -61,7 +62,7 @@ class DocumentSearchPagedIntegrationTest {
|
||||
@Test
|
||||
void search_firstPage_returnsExactlyPageSizeItems_andCorrectTotalElements() {
|
||||
DocumentSearchResult result = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.DATE, "DESC", PageRequest.of(0, 50));
|
||||
|
||||
assertThat(result.items()).hasSize(50);
|
||||
@@ -74,7 +75,7 @@ class DocumentSearchPagedIntegrationTest {
|
||||
@Test
|
||||
void search_lastPartialPage_returnsRemainingItems() {
|
||||
DocumentSearchResult result = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.DATE, "DESC", PageRequest.of(2, 50));
|
||||
|
||||
// Page 2 (offset 100) of 120 docs → exactly 20 items on the tail.
|
||||
@@ -86,7 +87,7 @@ class DocumentSearchPagedIntegrationTest {
|
||||
@Test
|
||||
void search_pageBeyondLast_returnsEmptyContent_totalElementsStillCorrect() {
|
||||
DocumentSearchResult result = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.DATE, "DESC", PageRequest.of(99, 50));
|
||||
|
||||
assertThat(result.items()).isEmpty();
|
||||
@@ -99,7 +100,7 @@ class DocumentSearchPagedIntegrationTest {
|
||||
// comment in DocumentService). Proves that the in-memory slice path
|
||||
// returns the correct total from a real repository fetch.
|
||||
DocumentSearchResult result = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.SENDER, "asc", PageRequest.of(1, 50));
|
||||
|
||||
assertThat(result.items()).hasSize(50);
|
||||
@@ -125,7 +126,7 @@ class DocumentSearchPagedIntegrationTest {
|
||||
}
|
||||
|
||||
DocumentSearchResult result = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.DATE, "DESC", PageRequest.of(0, 50));
|
||||
|
||||
// Global undated count is the full undated total, independent of page size.
|
||||
@@ -153,10 +154,10 @@ class DocumentSearchPagedIntegrationTest {
|
||||
}
|
||||
|
||||
DocumentSearchResult unfiltered = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.DATE, "DESC", PageRequest.of(0, 50));
|
||||
DocumentSearchResult undatedOnly = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, true),
|
||||
noFilters().withUndated(true),
|
||||
DocumentSort.DATE, "DESC", PageRequest.of(0, 50));
|
||||
|
||||
assertThat(unfiltered.undatedCount()).isEqualTo(undatedTotal);
|
||||
@@ -188,10 +189,10 @@ class DocumentSearchPagedIntegrationTest {
|
||||
@Test
|
||||
void search_differentPagesReturnDisjointSlices() {
|
||||
DocumentSearchResult page0 = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.DATE, "DESC", PageRequest.of(0, 50));
|
||||
DocumentSearchResult page1 = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.DATE, "DESC", PageRequest.of(1, 50));
|
||||
|
||||
// No document id should appear on both pages — slicing must be exclusive.
|
||||
|
||||
@@ -45,6 +45,7 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.raddatz.familienarchiv.document.SearchFiltersFixtures.noFilters;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
@@ -1442,7 +1443,7 @@ class DocumentServiceTest {
|
||||
.thenReturn(new PageImpl<>(List.of()));
|
||||
|
||||
documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
org.raddatz.familienarchiv.document.DocumentSort.DATE, "DESC", org.springframework.data.domain.PageRequest.of(1, 50));
|
||||
|
||||
verify(documentRepository).findAll(any(org.springframework.data.jpa.domain.Specification.class), any(Pageable.class));
|
||||
@@ -1456,7 +1457,7 @@ class DocumentServiceTest {
|
||||
.thenReturn(new PageImpl<>(List.of()));
|
||||
|
||||
documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
org.raddatz.familienarchiv.document.DocumentSort.DATE, "DESC", org.springframework.data.domain.PageRequest.of(3, 25));
|
||||
|
||||
verify(documentRepository).findAll(any(org.springframework.data.jpa.domain.Specification.class), captor.capture());
|
||||
@@ -1473,7 +1474,7 @@ class DocumentServiceTest {
|
||||
.thenReturn(new PageImpl<>(List.of(d), org.springframework.data.domain.PageRequest.of(0, 50), 120L));
|
||||
|
||||
DocumentSearchResult result = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
org.raddatz.familienarchiv.document.DocumentSort.DATE, "DESC", org.springframework.data.domain.PageRequest.of(0, 50));
|
||||
|
||||
assertThat(result.totalElements()).isEqualTo(120L);
|
||||
@@ -1490,7 +1491,7 @@ class DocumentServiceTest {
|
||||
.thenReturn(new PageImpl<>(List.of()));
|
||||
|
||||
documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.DATE, "DESC", org.springframework.data.domain.PageRequest.of(0, 5));
|
||||
|
||||
verify(documentRepository).findAll(any(org.springframework.data.jpa.domain.Specification.class), captor.capture());
|
||||
@@ -1514,7 +1515,7 @@ class DocumentServiceTest {
|
||||
.thenReturn(new PageImpl<>(List.of()));
|
||||
|
||||
documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.DATE, "ASC", org.springframework.data.domain.PageRequest.of(0, 5));
|
||||
|
||||
verify(documentRepository).findAll(any(org.springframework.data.jpa.domain.Specification.class), captor.capture());
|
||||
@@ -1536,7 +1537,7 @@ class DocumentServiceTest {
|
||||
.thenReturn(new PageImpl<>(List.of()));
|
||||
|
||||
documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.UPDATED_AT, "DESC", org.springframework.data.domain.PageRequest.of(0, 5));
|
||||
|
||||
verify(documentRepository).findAll(any(org.springframework.data.jpa.domain.Specification.class), captor.capture());
|
||||
@@ -1561,7 +1562,7 @@ class DocumentServiceTest {
|
||||
.thenReturn(all);
|
||||
|
||||
DocumentSearchResult result = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
org.raddatz.familienarchiv.document.DocumentSort.SENDER, "asc", org.springframework.data.domain.PageRequest.of(1, 50));
|
||||
|
||||
assertThat(result.totalElements()).isEqualTo(120L);
|
||||
@@ -1586,7 +1587,7 @@ class DocumentServiceTest {
|
||||
.thenReturn(all);
|
||||
|
||||
DocumentSearchResult result = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
org.raddatz.familienarchiv.document.DocumentSort.SENDER, "asc", org.springframework.data.domain.PageRequest.of(10, 50));
|
||||
|
||||
assertThat(result.items()).isEmpty();
|
||||
@@ -1612,7 +1613,7 @@ class DocumentServiceTest {
|
||||
.thenReturn(new PageImpl<>(List.of()));
|
||||
|
||||
documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false), null, null, UNPAGED);
|
||||
noFilters(), null, null, UNPAGED);
|
||||
|
||||
verify(documentRepository).findAll(any(org.springframework.data.jpa.domain.Specification.class), any(Pageable.class));
|
||||
}
|
||||
@@ -1690,7 +1691,7 @@ class DocumentServiceTest {
|
||||
.thenReturn(List.of(withSender, noSender));
|
||||
|
||||
DocumentSearchResult result = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.SENDER, "asc", UNPAGED);
|
||||
|
||||
assertThat(result.items()).hasSize(2);
|
||||
@@ -1711,7 +1712,7 @@ class DocumentServiceTest {
|
||||
.thenReturn(List.of(noReceivers, withReceiver));
|
||||
|
||||
DocumentSearchResult result = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.RECEIVER, "asc", UNPAGED);
|
||||
|
||||
assertThat(result.items()).extracting(DocumentListItem::title)
|
||||
@@ -1745,7 +1746,7 @@ class DocumentServiceTest {
|
||||
.thenReturn(List.of(undatedBob, datedAnna, datedBob, undatedAnna));
|
||||
|
||||
DocumentSearchResult result = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.SENDER, "asc", UNPAGED);
|
||||
|
||||
// Bob's group precedes Anna's group (ASC by sender). The sort is stable, so
|
||||
@@ -1777,7 +1778,7 @@ class DocumentServiceTest {
|
||||
.thenReturn(List.of(undatedBob, datedAnna, datedBob, undatedAnna));
|
||||
|
||||
DocumentSearchResult result = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.SENDER, "desc", UNPAGED);
|
||||
|
||||
// Anna's group precedes Bob's (DESC by sender); undated stays inside its group.
|
||||
@@ -1801,7 +1802,7 @@ class DocumentServiceTest {
|
||||
.thenReturn(List.of(undatedFromAlice));
|
||||
|
||||
DocumentSearchResult result = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, true),
|
||||
noFilters().withUndated(true),
|
||||
DocumentSort.SENDER, "asc", UNPAGED);
|
||||
|
||||
// The in-memory path queried via a Specification (built by buildSearchSpec with
|
||||
@@ -1843,7 +1844,7 @@ class DocumentServiceTest {
|
||||
.thenReturn(List.of(docNullName, docSmith));
|
||||
|
||||
DocumentSearchResult result = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
DocumentSort.SENDER, "asc", UNPAGED);
|
||||
|
||||
// null lastName should sort to end (treated as empty), not before "smith" (as "null")
|
||||
@@ -1882,7 +1883,7 @@ class DocumentServiceTest {
|
||||
.thenReturn(new PageImpl<>(List.of()));
|
||||
|
||||
DocumentSearchResult result = documentService.searchDocuments(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false),
|
||||
noFilters(),
|
||||
null, null, UNPAGED);
|
||||
|
||||
assertThat(result.items()).isEmpty();
|
||||
@@ -2421,7 +2422,7 @@ class DocumentServiceTest {
|
||||
.thenReturn(List.of(d1, d2));
|
||||
|
||||
List<UUID> result = documentService.findIdsForFilter(
|
||||
new SearchFilters(null, null, null, null, null, null, null, null, null, false));
|
||||
noFilters());
|
||||
|
||||
assertThat(result).containsExactly(d1.getId(), d2.getId());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.raddatz.familienarchiv.document;
|
||||
|
||||
/** Test fixtures for {@link SearchFilters}. */
|
||||
final class SearchFiltersFixtures {
|
||||
|
||||
private SearchFiltersFixtures() {}
|
||||
|
||||
/**
|
||||
* A {@link SearchFilters} with no predicate active — the common search-test
|
||||
* baseline. Combine with {@code .withUndated(true)} for the undated-only case;
|
||||
* construct {@code new SearchFilters(...)} directly when a test pins a specific
|
||||
* field, so the intent stays visible at the call site.
|
||||
*/
|
||||
static SearchFilters noFilters() {
|
||||
return new SearchFilters(null, null, null, null, null, null, null, null, null, false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user