Skip to content

Commit acb7c19

Browse files
committed
Added a filter to the publisher list page [#2386]
1 parent 3f72abe commit acb7c19

File tree

17 files changed

+215
-36
lines changed

17 files changed

+215
-36
lines changed

comixed-model/src/main/java/org/comixedproject/model/net/collections/LoadPublisherListRequest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
*/
3131
@AllArgsConstructor
3232
public class LoadPublisherListRequest {
33+
@JsonProperty("searchText")
34+
@Getter
35+
private String searchText;
36+
3337
@JsonProperty("page")
3438
@Getter
3539
private int page;

comixed-repositories/src/main/java/org/comixedproject/repositories/collections/PublisherDetailRepository.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.springframework.data.domain.Pageable;
2424
import org.springframework.data.jpa.repository.JpaRepository;
2525
import org.springframework.data.jpa.repository.Query;
26+
import org.springframework.data.repository.query.Param;
2627
import org.springframework.stereotype.Repository;
2728

2829
@Repository
@@ -31,16 +32,37 @@ public interface PublisherDetailRepository extends JpaRepository<PublisherDetail
3132
/**
3233
* Returns the list of all publishers with the count of series for each.
3334
*
35+
* @param pageable the page request
3436
* @return the publisher list
3537
*/
3638
@Query("SELECT p FROM PublisherDetail p WHERE p.name IS NOT NULL AND LENGTH(p.name) > 0")
3739
Page<PublisherDetail> findAll(Pageable pageable);
3840

41+
/**
42+
* Returns the list of all publishers with the count of series for each, where the name matches
43+
* the filter.
44+
*
45+
* @param filterText the filter text
46+
* @param pageable the page request
47+
* @return the publisher list
48+
*/
49+
@Query("SELECT p FROM PublisherDetail p WHERE p.name ILIKE :filterText")
50+
Page<PublisherDetail> findAllFiltered(@Param("filterText") String filterText, Pageable pageable);
51+
3952
/**
4053
* Returns the number of publishers in the database.
4154
*
4255
* @return the publisher count
4356
*/
4457
@Query("SELECT COUNT(p) FROM PublisherDetail p WHERE p.name IS NOT NULL AND LENGTH(p.name) > 0")
4558
long getPublisherCount();
59+
60+
/**
61+
* Returns the number of publishers whose name matches the provided filter.
62+
*
63+
* @param filterText the filter text
64+
* @return the publisher count
65+
*/
66+
@Query("SELECT COUNT(p) FROM PublisherDetail p WHERE p.name ILIKE :filterText")
67+
long getPublisherCountWithFilter(@Param("filterText") String filterText);
4668
}

comixed-rest/src/main/java/org/comixedproject/rest/collections/PublisherDetailController.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,21 @@ public class PublisherDetailController {
5353
@Timed(value = "comixed.publishers.load-list")
5454
public LoadPublisherListResponse loadPublisherList(
5555
@RequestBody final LoadPublisherListRequest request) {
56+
final String searchText = request.getSearchText();
5657
final int page = request.getPage();
5758
final int size = request.getSize();
5859
final String sortBy = request.getSortBy();
5960
final String sortDirection = request.getSortDirection();
60-
log.info("Getting all publishers");
61+
log.info(
62+
"Getting all publishers: search text={} page={} size={} sort by={} sort dir={}",
63+
searchText,
64+
page,
65+
size,
66+
sortBy,
67+
sortDirection);
6168
return new LoadPublisherListResponse(
62-
this.publisherDetailService.getAllPublishers(page, size, sortBy, sortDirection),
63-
this.publisherDetailService.getPublisherCount());
69+
this.publisherDetailService.getAllPublishers(searchText, page, size, sortBy, sortDirection),
70+
this.publisherDetailService.getPublisherCount(searchText));
6471
}
6572

6673
/**

comixed-rest/src/test/java/org/comixedproject/rest/collections/PublisherDetailControllerTest.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public class PublisherDetailControllerTest {
4545
private static final String TEST_SORT_DIRECTION = "asc";
4646
private static final long TEST_SERIES_COUNT = 921L;
4747
private static final long TEST_PUBLISHER_COUNT = 73L;
48+
private static final String TEST_FILTER_TEXT = "The filter text";
4849

4950
@InjectMocks private PublisherDetailController controller;
5051
@Mock private ComicBookService comicBookService;
@@ -56,21 +57,23 @@ public class PublisherDetailControllerTest {
5657
public void testLoadPublisherList() {
5758
Mockito.when(
5859
publisherDetailService.getAllPublishers(
59-
TEST_PAGE_NUMBER, TEST_PAGE_SIZE, "name", "asc"))
60+
TEST_FILTER_TEXT, TEST_PAGE_NUMBER, TEST_PAGE_SIZE, "name", "asc"))
6061
.thenReturn(publisherDetailList);
61-
Mockito.when(publisherDetailService.getPublisherCount()).thenReturn(TEST_PUBLISHER_COUNT);
62+
Mockito.when(publisherDetailService.getPublisherCount(TEST_FILTER_TEXT))
63+
.thenReturn(TEST_PUBLISHER_COUNT);
6264

6365
final LoadPublisherListResponse result =
6466
controller.loadPublisherList(
65-
new LoadPublisherListRequest(TEST_PAGE_NUMBER, TEST_PAGE_SIZE, "name", "asc"));
67+
new LoadPublisherListRequest(
68+
TEST_FILTER_TEXT, TEST_PAGE_NUMBER, TEST_PAGE_SIZE, "name", "asc"));
6669

6770
assertNotNull(result);
6871
assertSame(publisherDetailList, result.getPublishers());
6972
assertEquals(TEST_PUBLISHER_COUNT, result.getTotal());
7073

7174
Mockito.verify(publisherDetailService, Mockito.times(1))
72-
.getAllPublishers(TEST_PAGE_NUMBER, TEST_PAGE_SIZE, "name", "asc");
73-
Mockito.verify(publisherDetailService, Mockito.times(1)).getPublisherCount();
75+
.getAllPublishers(TEST_FILTER_TEXT, TEST_PAGE_NUMBER, TEST_PAGE_SIZE, "name", "asc");
76+
Mockito.verify(publisherDetailService, Mockito.times(1)).getPublisherCount(TEST_FILTER_TEXT);
7477
}
7578

7679
@Test

comixed-services/src/main/java/org/comixedproject/service/collections/PublisherDetailService.java

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public class PublisherDetailService {
3737
/**
3838
* Returns the list of all publishers.
3939
*
40+
* @param filterText optional filter text
4041
* @param pageIndex the page index
4142
* @param pageSize the page size
4243
* @param sortBy the optional sort field
@@ -45,11 +46,20 @@ public class PublisherDetailService {
4546
*/
4647
@Transactional(readOnly = true)
4748
public List<PublisherDetail> getAllPublishers(
48-
final int pageIndex, final int pageSize, final String sortBy, final String sortDirection) {
49-
return this.publisherDetailRepository
50-
.findAll(PageRequest.of(pageIndex, pageSize, this.doCreateSort(sortBy, sortDirection)))
51-
.stream()
52-
.toList();
49+
final String filterText,
50+
final int pageIndex,
51+
final int pageSize,
52+
final String sortBy,
53+
final String sortDirection) {
54+
var pageRequest = PageRequest.of(pageIndex, pageSize, this.doCreateSort(sortBy, sortDirection));
55+
if (StringUtils.hasLength(filterText)) {
56+
return this.publisherDetailRepository
57+
.findAllFiltered(String.format("%%%s%%", filterText), pageRequest)
58+
.stream()
59+
.toList();
60+
} else {
61+
return this.publisherDetailRepository.findAll(pageRequest).stream().toList();
62+
}
5363
}
5464

5565
/**
@@ -58,8 +68,13 @@ public List<PublisherDetail> getAllPublishers(
5868
* @return the publisher count
5969
*/
6070
@Transactional(readOnly = true)
61-
public long getPublisherCount() {
62-
return this.publisherDetailRepository.getPublisherCount();
71+
public long getPublisherCount(final String filterText) {
72+
if (StringUtils.hasLength(filterText)) {
73+
return this.publisherDetailRepository.getPublisherCountWithFilter(
74+
String.format("%%%s%%", filterText));
75+
} else {
76+
return this.publisherDetailRepository.getPublisherCount();
77+
}
6378
}
6479

6580
private Sort doCreateSort(final String sortBy, final String sortDirection) {

comixed-services/src/test/java/org/comixedproject/service/collections/PublisherDetailServiceTest.java

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
@RunWith(MockitoJUnitRunner.class)
3636
public class PublisherDetailServiceTest {
37+
private static final String TEST_FILTER_TEXT = "The filter text";
3738
private static final int TEST_PAGE_INDEX = 32;
3839
private static final int TEST_PAGE_SIZE = 25;
3940
private static final long TEST_PUBLISHER_COUNT = 475L;
@@ -57,72 +58,74 @@ public void testGetAllPublishers_sortedByName_ascending() {
5758
Mockito.when(publisherDetailRepository.findAll(pageableArgumentCaptor.capture()))
5859
.thenReturn(publisherDetailPage);
5960

60-
doGetAllPublishersTest("name", "asc");
61+
doGetAllPublishers("name", "asc");
6162
}
6263

6364
@Test
6465
public void testGetAllPublishers_sortedByName_descending() {
6566
Mockito.when(publisherDetailRepository.findAll(pageableArgumentCaptor.capture()))
6667
.thenReturn(publisherDetailPage);
6768

68-
doGetAllPublishersTest("name", "desc");
69+
doGetAllPublishers("name", "desc");
6970
}
7071

7172
@Test
7273
public void testGetAllPublishers_sortedByIssueCount_ascending() {
7374
Mockito.when(publisherDetailRepository.findAll(pageableArgumentCaptor.capture()))
7475
.thenReturn(publisherDetailPage);
7576

76-
doGetAllPublishersTest("issue-count", "asc");
77+
doGetAllPublishers("issue-count", "asc");
7778
}
7879

7980
@Test
8081
public void testGetAllPublishers_sortedByIssueCount_descending() {
8182
Mockito.when(publisherDetailRepository.findAll(pageableArgumentCaptor.capture()))
8283
.thenReturn(publisherDetailPage);
8384

84-
doGetAllPublishersTest("issue-count", "desc");
85+
doGetAllPublishers("issue-count", "desc");
8586
}
8687

8788
@Test
8889
public void testGetAllPublishers_sortedBySeriesCount_ascending() {
8990
Mockito.when(publisherDetailRepository.findAll(pageableArgumentCaptor.capture()))
9091
.thenReturn(publisherDetailPage);
9192

92-
doGetAllPublishersTest("series-count", "asc");
93+
doGetAllPublishers("series-count", "asc");
9394
}
9495

9596
@Test
9697
public void testGetAllPublishers_sortedBySeriesCount_descending() {
9798
Mockito.when(publisherDetailRepository.findAll(pageableArgumentCaptor.capture()))
9899
.thenReturn(publisherDetailPage);
99100

100-
doGetAllPublishersTest("series-count", "desc");
101+
doGetAllPublishers("series-count", "desc");
101102
}
102103

103104
@Test
104105
public void testGetAllPublishers_sortedByUnknown_ascending() {
105106
Mockito.when(publisherDetailRepository.findAll(pageableArgumentCaptor.capture()))
106107
.thenReturn(publisherDetailPage);
107108

108-
doGetAllPublishersTest("series-counts", "asc");
109+
doGetAllPublishers("series-counts", "asc");
109110
}
110111

111112
@Test
112113
public void testGetAllPublishers_sortedByUnknown_descending() {
113114
Mockito.when(publisherDetailRepository.findAll(pageableArgumentCaptor.capture()))
114115
.thenReturn(publisherDetailPage);
115116

116-
doGetAllPublishersTest("series-counts", "desc");
117+
doGetAllPublishers("series-counts", "desc");
117118
}
118119

119120
@Test
120121
public void testGetAllPublishers_unsorted() {
121-
Mockito.when(publisherDetailRepository.findAll(pageableArgumentCaptor.capture()))
122+
Mockito.when(
123+
publisherDetailRepository.findAllFiltered(
124+
Mockito.anyString(), pageableArgumentCaptor.capture()))
122125
.thenReturn(publisherDetailPage);
123126

124127
final List<PublisherDetail> result =
125-
service.getAllPublishers(TEST_PAGE_INDEX, TEST_PAGE_SIZE, "", "");
128+
service.getAllPublishers(TEST_FILTER_TEXT, TEST_PAGE_INDEX, TEST_PAGE_SIZE, "", "");
126129

127130
assertNotNull(result);
128131
assertSame(publisherDetailList, result);
@@ -132,25 +135,40 @@ public void testGetAllPublishers_unsorted() {
132135
assertEquals(TEST_PAGE_SIZE, pageable.getPageSize());
133136
assertFalse(pageable.getSort().isSorted());
134137

135-
Mockito.verify(publisherDetailRepository, Mockito.times(1)).findAll(pageable);
138+
Mockito.verify(publisherDetailRepository, Mockito.times(1))
139+
.findAllFiltered(String.format("%%%s%%", TEST_FILTER_TEXT), pageable);
136140
}
137141

138142
@Test
139143
public void testGetPublisherCount() {
140144
Mockito.when(publisherDetailRepository.getPublisherCount()).thenReturn(TEST_PUBLISHER_COUNT);
141145

142-
final long result = service.getPublisherCount();
146+
final long result = service.getPublisherCount("");
143147

144148
assertEquals(TEST_PUBLISHER_COUNT, result);
145149

146150
Mockito.verify(publisherDetailRepository, Mockito.times(1)).getPublisherCount();
147151
}
148152

149-
private void doGetAllPublishersTest(final String sortField, final String sortDirection) {
153+
@Test
154+
public void getPublisherCountWithFilter() {
155+
Mockito.when(publisherDetailRepository.getPublisherCountWithFilter(Mockito.anyString()))
156+
.thenReturn(TEST_PUBLISHER_COUNT);
157+
158+
final long result = service.getPublisherCount(TEST_FILTER_TEXT);
159+
160+
assertEquals(TEST_PUBLISHER_COUNT, result);
161+
162+
Mockito.verify(publisherDetailRepository, Mockito.times(1))
163+
.getPublisherCountWithFilter(String.format("%%%s%%", TEST_FILTER_TEXT));
164+
}
165+
166+
private void doGetAllPublishers(final String sortField, final String sortDirection) {
150167
List<PublisherDetail> result;
151168
Pageable pageable;
152169

153-
result = service.getAllPublishers(TEST_PAGE_INDEX, TEST_PAGE_SIZE, sortField, sortDirection);
170+
result =
171+
service.getAllPublishers("", TEST_PAGE_INDEX, TEST_PAGE_SIZE, sortField, sortDirection);
154172

155173
assertNotNull(result);
156174
assertSame(publisherDetailList, result);

comixed-webui/src/app/collections/actions/publisher.actions.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,13 @@ import { Series } from '@app/collections/models/series';
2222

2323
export const loadPublisherList = createAction(
2424
'[Publishers] Load publishers',
25-
props<{ size: number; page: number; sortBy: string; sortDirection: string }>()
25+
props<{
26+
searchText: string;
27+
size: number;
28+
page: number;
29+
sortBy: string;
30+
sortDirection: string;
31+
}>()
2632
);
2733

2834
export const loadPublisherListSuccess = createAction(

comixed-webui/src/app/collections/effects/publisher.effects.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import { LoadPublisherListResponse } from '@app/collections/models/net/load-publ
4949
import { LoadPublisherDetailResponse } from '@app/collections/models/net/load-publisher-detail-response';
5050

5151
describe('PublisherEffects', () => {
52+
const SEARCH_TEXT = 'some text';
5253
const PAGE_NUMBER = 1;
5354
const PAGE_SIZE = 25;
5455
const SORT_BY = 'name';
@@ -107,6 +108,7 @@ describe('PublisherEffects', () => {
107108
publishers: PUBLISHERS
108109
} as LoadPublisherListResponse;
109110
const action = loadPublisherList({
111+
searchText: SEARCH_TEXT,
110112
page: PAGE_NUMBER,
111113
size: PAGE_SIZE,
112114
sortBy: SORT_BY,
@@ -120,6 +122,7 @@ describe('PublisherEffects', () => {
120122
actions$ = hot('-a', { a: action });
121123
publisherService.loadPublishers
122124
.withArgs({
125+
searchText: SEARCH_TEXT,
123126
page: PAGE_NUMBER,
124127
size: PAGE_SIZE,
125128
sortBy: SORT_BY,
@@ -134,6 +137,7 @@ describe('PublisherEffects', () => {
134137
it('fires an action on service failure', () => {
135138
const serviceResponse = new HttpErrorResponse({});
136139
const action = loadPublisherList({
140+
searchText: SEARCH_TEXT,
137141
page: PAGE_NUMBER,
138142
size: PAGE_SIZE,
139143
sortBy: SORT_BY,
@@ -144,6 +148,7 @@ describe('PublisherEffects', () => {
144148
actions$ = hot('-a', { a: action });
145149
publisherService.loadPublishers
146150
.withArgs({
151+
searchText: SEARCH_TEXT,
147152
page: PAGE_NUMBER,
148153
size: PAGE_SIZE,
149154
sortBy: SORT_BY,
@@ -158,6 +163,7 @@ describe('PublisherEffects', () => {
158163

159164
it('fires an action on general failure', () => {
160165
const action = loadPublisherList({
166+
searchText: SEARCH_TEXT,
161167
page: PAGE_NUMBER,
162168
size: PAGE_SIZE,
163169
sortBy: SORT_BY,
@@ -168,6 +174,7 @@ describe('PublisherEffects', () => {
168174
actions$ = hot('-a', { a: action });
169175
publisherService.loadPublishers
170176
.withArgs({
177+
searchText: SEARCH_TEXT,
171178
page: PAGE_NUMBER,
172179
size: PAGE_SIZE,
173180
sortBy: SORT_BY,

comixed-webui/src/app/collections/effects/publisher.effects.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export class PublisherEffects {
4444
switchMap(action =>
4545
this.publisherService
4646
.loadPublishers({
47+
searchText: action.searchText,
4748
page: action.page,
4849
size: action.size,
4950
sortBy: action.sortBy,

comixed-webui/src/app/collections/models/net/load-publisher-list-request.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818

1919
export interface LoadPublisherListRequest {
20+
searchText: string;
2021
page: number;
2122
size: number;
2223
sortBy: string;

0 commit comments

Comments
 (0)