Skip to content

Commit

Permalink
Pass fields in GET list contents request
Browse files Browse the repository at this point in the history
  • Loading branch information
bvsharp committed Mar 12, 2024
1 parent 443014d commit 24e3c3e
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 35 deletions.
4 changes: 2 additions & 2 deletions src/main/java/org/folio/list/controller/ListController.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ public ResponseEntity<ListRefreshDTO> performRefresh(UUID id) {
}

@Override
public ResponseEntity<ResultsetPage> getListContents(UUID id, Integer offset, Integer size) {
return listService.getListContents(id, offset, size)
public ResponseEntity<ResultsetPage> getListContents(UUID id, List<String> fields, Integer offset, Integer size) {
return listService.getListContents(id, fields, offset, size)
.map(ResponseEntity::ok)
.orElseThrow(() -> new ListNotFoundException(id, ListActions.READ));
}
Expand Down
15 changes: 8 additions & 7 deletions src/main/java/org/folio/list/services/ListService.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@

import java.time.OffsetDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toMap;
import static java.util.Objects.nonNull;
Expand Down Expand Up @@ -208,13 +207,13 @@ public Optional<ListRefreshDTO> performRefresh(UUID listId) {
});
}

public Optional<ResultsetPage> getListContents(UUID listId, Integer offset, Integer size) {
public Optional<ResultsetPage> getListContents(UUID listId, List<String> fields, Integer offset, Integer size) {
log.info("Attempting to get contents for list with listId {}, tenantId {}, offset {}, size {}",
listId, executionContext.getTenantId(), offset, size);
return listRepository.findByIdAndIsDeletedFalse(listId)
.map(list -> {
validationService.assertSharedOrOwnedByUser(list, ListActions.READ);
return getListContents(list, offset, size);
return getListContents(list, fields, offset, size);
});
}

Expand Down Expand Up @@ -271,14 +270,16 @@ private void deleteListAndContents(ListEntity list) {
listRepository.save(list.withIsDeleted(true));
}

private ResultsetPage getListContents(ListEntity list, Integer offset, Integer limit) {
List<Map<String, Object>> sortedContents = List.of();
EntityType entityType = getEntityType(list.getEntityTypeId());
private ResultsetPage getListContents(ListEntity list, List<String> fields, Integer offset, Integer limit) {
// As a workaround for a UI bug, we are temporarily retrieving all fields defined in the entity type definition.
// In the long term, this method needs to be updated to accept a list of fields to retrieve content for. The UI
// will pull the fields to retrieve from local storage, and pass them to this method. If the user selects a new
// field to display that doesn't have data, then another contents request containing the new field will be sent.
List<String> fields = getFieldsFromEntityType(entityType);
if (isEmpty(fields)) {
EntityType entityType = getEntityType(list.getEntityTypeId());
fields = getFieldsFromEntityType(entityType);
}
List<Map<String, Object>> sortedContents = List.of();
if (list.isRefreshed()) {
List<List<String>> contentIds = listContentsRepository.getContents(list.getId(), list.getSuccessRefresh().getId(), new OffsetRequest(offset, limit))
.stream()
Expand Down
9 changes: 9 additions & 0 deletions src/main/resources/swagger.api/list.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,15 @@ paths:
description: gets the list contents (if exists).
parameters:
- $ref: '#/components/parameters/id'
- name: fields
in: query
description: List of fields to retrieve content for
required: false
schema:
type: array
items:
type:
string
- name: offset
in: query
description: Offset to start retrieving items from
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,15 @@ void shouldGetListContents() throws Exception {
UUID listId = UUID.randomUUID();
Integer offset = 0;
Integer size = 2;
var requestBuilder = get("/lists/" + listId + "/contents?size=2&offset=0")
List<String> fields = List.of("key1", "key2", "key3", "key4");
var requestBuilder = get("/lists/" + listId + "/contents?size=2&offset=0&fields=key1,key2,key3,key4")
.contentType(APPLICATION_JSON)
.header(XOkapiHeaders.TENANT, listId);
List<Map<String, Object>> expectedList = List.of(
Map.of("key1", "value1", "key2", "value2"),
Map.of("key3", "value3", "key4", "value4"));
Optional<ResultsetPage> expectedContent = Optional.of(new ResultsetPage().content(expectedList).totalRecords(expectedList.size()));
when(listService.getListContents(listId, offset, size)).thenReturn(expectedContent);
when(listService.getListContents(listId, fields, offset, size)).thenReturn(expectedContent);
mockMvc.perform(requestBuilder)
.andExpect(status().isOk())
.andExpect(jsonPath("$.content[0]", is(expectedList.get(0))))
Expand All @@ -56,11 +57,12 @@ void getListContentsShouldReturnHttp404WhenListNotFound() throws Exception {
UUID listId = UUID.randomUUID();
Integer offset = 0;
Integer size = 0;
var requestBuilder = get("/lists/" + listId + "/contents?size=0&offset=0")
List<String> fields = List.of("key1");
var requestBuilder = get("/lists/" + listId + "/contents?size=0&offset=0&fields=key1")
.contentType(APPLICATION_JSON)
.header(XOkapiHeaders.TENANT, listId);
Optional<ResultsetPage> expectedContent = Optional.empty();
when(listService.getListContents(listId, offset, size)).thenReturn(expectedContent);
when(listService.getListContents(listId, fields, offset, size)).thenReturn(expectedContent);
mockMvc.perform(requestBuilder)
.andExpect(status().isNotFound())
.andExpect(jsonPath("$.code", is("read-list.not.found")));
Expand All @@ -73,12 +75,13 @@ void shouldReturnHttp401ForAccessingPrivateListContents() throws Exception {
listEntity.setId(listId);
Integer offset = 0;
Integer size = 0;
List<String> fields = List.of("key1");

var requestBuilder = get("/lists/" + listId + "/contents?size=0&offset=0")
var requestBuilder = get("/lists/" + listId + "/contents?size=0&offset=0&fields=key1")
.contentType(APPLICATION_JSON)
.header(XOkapiHeaders.TENANT, listId);

when(listService.getListContents(listId, offset, size))
when(listService.getListContents(listId, fields, offset, size))
.thenThrow(new PrivateListOfAnotherUserException(listEntity, ListActions.READ));

mockMvc.perform(requestBuilder)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,6 @@ class ListServiceGetListContentsTest {
void shouldReturnValidContentPage() {
String tenantId = "tenant_01";
UUID entityTypeId = UUID.randomUUID();
List<EntityTypeColumn> columns = List.of(
new EntityTypeColumn().name("id"),
new EntityTypeColumn().name("key1"),
new EntityTypeColumn().name("key2")
);
EntityType entityType = new EntityType().columns(columns);
UUID listId = UUID.randomUUID();
List<List<String>> contentIds = List.of(
List.of(UUID.randomUUID().toString()),
Expand Down Expand Up @@ -99,11 +93,10 @@ void shouldReturnValidContentPage() {
expectedEntity.getSuccessRefresh().setRecordsCount(2);

when(executionContext.getTenantId()).thenReturn(tenantId);
when(entityTypeClient.getEntityType(entityTypeId)).thenReturn(entityType);
when(listRepository.findByIdAndIsDeletedFalse(listId)).thenReturn(Optional.of(expectedEntity));
when(listContentsRepository.getContents(listId, successRefresh.getId(), new OffsetRequest(offset, size))).thenReturn(listContents);
when(queryClient.getContents(contentsRequest)).thenReturn(expectedList);
Optional<ResultsetPage> actualContent = listService.getListContents(listId, offset, size);
Optional<ResultsetPage> actualContent = listService.getListContents(listId, fields, offset, size);
assertThat(actualContent).isEqualTo(expectedContent);
}

Expand Down Expand Up @@ -149,7 +142,7 @@ void shouldReturnRequestedFieldsPlusIdsIfIdsNotIncludedInFields() {
when(listRepository.findByIdAndIsDeletedFalse(listId)).thenReturn(Optional.of(expectedEntity));
when(listContentsRepository.getContents(listId, successRefresh.getId(), new OffsetRequest(offset, size))).thenReturn(listContents);
when(queryClient.getContents(contentsRequest)).thenReturn(expectedList);
Optional<ResultsetPage> actualContent = listService.getListContents(listId, offset, size);
Optional<ResultsetPage> actualContent = listService.getListContents(listId, fields, offset, size);
assertThat(actualContent).isEqualTo(expectedContent);
}

Expand Down Expand Up @@ -195,7 +188,7 @@ void shouldReturnContentPageWithIdsForEmptyFields() {
when(listRepository.findByIdAndIsDeletedFalse(listId)).thenReturn(Optional.of(expectedEntity));
when(listContentsRepository.getContents(listId, successRefresh.getId(), new OffsetRequest(offset, size))).thenReturn(listContents);
when(queryClient.getContents(contentsRequest)).thenReturn(expectedList);
Optional<ResultsetPage> actualContent = listService.getListContents(listId, offset, size);
Optional<ResultsetPage> actualContent = listService.getListContents(listId, fields, offset, size);
assertThat(actualContent).isEqualTo(expectedContent);
}

Expand Down Expand Up @@ -240,34 +233,29 @@ void shouldReturnContentPageWithIdsForNullFields() {
when(listRepository.findByIdAndIsDeletedFalse(listId)).thenReturn(Optional.of(expectedEntity));
when(listContentsRepository.getContents(listId, successRefresh.getId(), new OffsetRequest(offset, size))).thenReturn(listContents);
when(queryClient.getContents(contentsRequest)).thenReturn(expectedList);
Optional<ResultsetPage> actualContent = listService.getListContents(listId, offset, size);
Optional<ResultsetPage> actualContent = listService.getListContents(listId, fields, offset, size);
assertThat(actualContent).isEqualTo(expectedContent);
}

@Test
void shouldReturnEmptyContentPageIfNotRefreshed() {
UUID listId = UUID.randomUUID();
List<EntityTypeColumn> columns = List.of(
new EntityTypeColumn().name("id"),
new EntityTypeColumn().name("key1"),
new EntityTypeColumn().name("key2")
);
EntityType entityType = new EntityType().columns(columns);
List<String> fields = List.of("id", "key1", "key2");
Optional<ResultsetPage> emptyContent = Optional.of(new ResultsetPage().content(List.of()).totalRecords(0));
ListEntity neverRefreshedList = TestDataFixture.getNeverRefreshedListEntity();
when(listRepository.findByIdAndIsDeletedFalse(listId)).thenReturn(Optional.of(neverRefreshedList));
when(entityTypeClient.getEntityType(neverRefreshedList.getEntityTypeId())).thenReturn(entityType);
Optional<ResultsetPage> actualContent = listService.getListContents(listId, 0, 100);
Optional<ResultsetPage> actualContent = listService.getListContents(listId, fields, 0, 100);
assertThat(actualContent).isEqualTo(emptyContent);
}

@Test
void shouldThrowExceptionWhenValidationFailed() {
UUID listId = UUID.randomUUID();
ListEntity listEntity = TestDataFixture.getNeverRefreshedListEntity();
List<String> fields = List.of("id", "key1", "key2");
when(listRepository.findByIdAndIsDeletedFalse(listId)).thenReturn(Optional.of(listEntity));
doThrow(new PrivateListOfAnotherUserException(listEntity, ListActions.READ))
.when(listValidationService).assertSharedOrOwnedByUser(listEntity, ListActions.READ);
Assertions.assertThrows(PrivateListOfAnotherUserException.class, () -> listService.getListContents(listId, 0, 100));
Assertions.assertThrows(PrivateListOfAnotherUserException.class, () -> listService.getListContents(listId, fields, 0, 100));
}
}

0 comments on commit 24e3c3e

Please sign in to comment.