Commit 270e9931 authored by Artem Hrybeniuk's avatar Artem Hrybeniuk
Browse files

WIP: Public API v1

parent e47ef600
/*
* Copyright 2021 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gringlobal.api.v1;
import com.querydsl.core.types.OrderSpecifier;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import org.apache.commons.lang3.ArrayUtils;
import org.genesys.blocks.model.EmptyModel;
import org.genesys.blocks.model.filters.EmptyModelFilter;
import org.gringlobal.api.PageableAsQueryParam;
import org.gringlobal.custom.elasticsearch.SearchException;
import org.gringlobal.service.PublicService;
import org.gringlobal.service.ShortFilterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
public abstract class PublicController<E extends EmptyModel, S extends PublicService<E, F>, F extends EmptyModelFilter<F, E>> extends ApiBaseController{
public static final String ENDPOINT_LIST = "/public/list";
public static final String ENDPOINT_FILTER = "/public/filter";
@Autowired
protected ShortFilterService shortFilterService;
@Autowired
protected S publicService;
@PostMapping(value = ENDPOINT_LIST, produces = { MediaType.APPLICATION_JSON_VALUE })
@Operation(description = "Retrieve list of public records matching the filter", summary = "List of public public by filter")
@PageableAsQueryParam
public FilteredPage<E, F> list(@Parameter(hidden = true) final Pagination page, @RequestBody(required = false) final F filter) throws SearchException, IOException {
F normalizedFilter = shortFilterService.normalizeFilter(filter, filterType());
Pageable pageable = ArrayUtils.isEmpty(page.getS()) ? page.toPageRequest(MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE, defaultSort()) : page.toPageRequest(MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE);
FilteredPage<E, F> results = new FilteredPage<>(normalizedFilter, publicService.listPublic(filter, pageable));
return results;
}
@PostMapping(value = ENDPOINT_FILTER, produces = { MediaType.APPLICATION_JSON_VALUE })
@Operation(description = "Retrieve list of public records matching the filter or filter code", summary = "List of public by filter code or filter")
@PageableAsQueryParam
public FilteredPage<E, F> filter(@RequestParam(name = "f", required = false) String filterCode, @Parameter(hidden = true) final Pagination page, @RequestBody(required = false) F filter) throws IOException, SearchException {
if (filterCode != null) {
filter = shortFilterService.filterByCode(filterCode, filterType());
} else {
filterCode = shortFilterService.getCode(filter);
}
ShortFilterService.FilterInfo<F> filterInfo = shortFilterService.processFilter(filterCode, filter, filterType());
Pageable pageable = ArrayUtils.isEmpty(page.getS()) ? page.toPageRequest(MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE, defaultSort()) : page.toPageRequest(MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE);
FilteredPage<E, F> results = new FilteredPage<>(filterInfo.filterCode, filterInfo.filter, publicService.listPublic(filterInfo.filter, pageable));
return results;
}
/**
* Default order specifier for this entity.
*
* @return the order specifier
*/
protected OrderSpecifier<?>[] defaultSort() {
return null;
}
/**
* Filter type
*
* @return the class
*/
@SuppressWarnings("unchecked")
protected Class<F> filterType() {
return ((Class<F>)((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[2]);
}
}
......@@ -34,6 +34,7 @@ import org.gringlobal.api.v1.ApiBaseController;
import org.gringlobal.api.v1.FilteredCRUDController;
import org.gringlobal.api.v1.FilteredPage;
import org.gringlobal.api.v1.Pagination;
import org.gringlobal.api.v1.PublicController;
import org.gringlobal.custom.elasticsearch.SearchException;
import org.gringlobal.model.Accession;
import org.gringlobal.model.AccessionAction;
......@@ -125,6 +126,26 @@ public class AccessionController extends FilteredCRUDController<Accession, Acces
}
}
@RestController("publicAccessionApi1")
@RequestMapping(PublicAccessionController.API_URL)
@Tag(name = "Accession")
public static class PublicAccessionController extends PublicController<Accession, AccessionService, AccessionFilter> {
public static final String API_URL = AccessionController.API_URL;
/**
* Retrieve public accession details by id
*
* @param id the id
* @return the public accession details
*/
@GetMapping(value = "/public/details/{id}", produces = { MediaType.APPLICATION_JSON_VALUE })
@Operation(operationId = "getPublicDetails", description = "Retrieve public accession details by ID", summary = "Details")
public AccessionService.AccessionDetails details(@PathVariable("id") final long id) {
return publicService.getAccessionDetails(publicService.loadPublic(id));
}
}
@Override
public Accession create(@RequestBody Accession entity) {
return super.create(entity);
......
......@@ -21,6 +21,7 @@ import java.util.stream.Collectors;
import org.apache.commons.lang3.ArrayUtils;
import org.gringlobal.api.v1.FilteredCRUDController;
import org.gringlobal.api.v1.Pagination;
import org.gringlobal.api.v1.PublicController;
import org.gringlobal.custom.elasticsearch.SearchException;
import org.gringlobal.model.Accession;
import org.gringlobal.model.AccessionInvGroup;
......@@ -64,6 +65,15 @@ public class InventoryGroupController extends FilteredCRUDController<AccessionIn
return new OrderSpecifier[] { QAccessionInvGroupMap.accessionInvGroupMap.inventory.inventoryNumberPart1.asc(), QAccessionInvGroupMap.accessionInvGroupMap.inventory.inventoryNumberPart2.asc(), QAccessionInvGroupMap.accessionInvGroupMap.inventory.inventoryNumberPart3.asc() };
}
@RestController("publicInventoryGroupApi1")
@RequestMapping(PublicInventoryGroupController.API_URL)
@Tag(name = "Inventory")
public static class PublicInventoryGroupController extends PublicController<AccessionInvGroup, AccessionInvGroupService, AccessionInvGroupFilter> {
/** The Constant API_URL. */
public static final String API_URL = InventoryGroupController.API_URL;
}
@Override
protected Class<AccessionInvGroupFilter> filterType() {
return AccessionInvGroupFilter.class;
......
......@@ -28,7 +28,7 @@ import org.springframework.data.domain.Pageable;
/**
* The Interface AccessionInvGroupService.
*/
public interface AccessionInvGroupService extends FilteredCRUDService<AccessionInvGroup, AccessionInvGroupFilter> {
public interface AccessionInvGroupService extends FilteredCRUDService<AccessionInvGroup, AccessionInvGroupFilter>, PublicService<AccessionInvGroup, AccessionInvGroupFilter> {
Page<AccessionInvGroupMap> listMembers(AccessionInvGroup accessionInvGroup, Pageable page);
......
......@@ -31,7 +31,7 @@ import com.fasterxml.jackson.annotation.JsonUnwrapped;
/**
* The Interface AccessionService.
*/
public interface AccessionService extends FilteredCRUDService<Accession, AccessionFilter>{
public interface AccessionService extends FilteredCRUDService<Accession, AccessionFilter>, PublicService<Accession, AccessionFilter> {
/**
* Value of -1 is used to indicate that GG-CE should automatically assign the
......
/*
* Copyright 2021 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gringlobal.service;
import org.genesys.blocks.model.EmptyModel;
import org.genesys.blocks.model.filters.EmptyModelFilter;
import org.gringlobal.custom.elasticsearch.SearchException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
@Transactional(readOnly = true)
public interface PublicService<T extends EmptyModel, F extends EmptyModelFilter<F, T>> {
/**
* List public records matching the filter.
*
* @param filter filter data
* @param page Pageable
* @return list of matches
* @throws SearchException
*/
Page<T> listPublic(F filter, Pageable page) throws SearchException;
T loadPublic(long id);
}
......@@ -34,6 +34,9 @@ public class AccessionInvGroupFilter extends CooperatorOwnedModelFilter<Accessio
private static final long serialVersionUID = 6538687263701155313L;
/** Any text. */
public StringFilter groupName;
/** is web visible */
public Boolean webVisible;
/**
* Builds the query.
......@@ -60,6 +63,9 @@ public class AccessionInvGroupFilter extends CooperatorOwnedModelFilter<Accessio
if (groupName != null) {
predicates.add(groupName.buildQuery(accessionInvGroup.groupName));
}
if (webVisible != null) {
predicates.add(accessionInvGroup.isWebVisible.eq(convertToString(webVisible)));
}
return predicates;
}
......
......@@ -37,6 +37,7 @@ import org.gringlobal.service.filter.AccessionInvGroupFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
......@@ -187,4 +188,22 @@ public class AccessionInvGroupServiceImpl extends FilteredCRUDServiceImpl<Access
accessionInvGroupMapRepository.deleteAll(toRemove);
return reload(group);
}
@Override
public Page<AccessionInvGroup> listPublic(AccessionInvGroupFilter filter, Pageable page) throws SearchException {
if (filter == null) {
filter = new AccessionInvGroupFilter();
}
filter.webVisible = true;
return list(filter, page);
}
@Override
public AccessionInvGroup loadPublic(long id) {
AccessionInvGroup accessionInvGroup = load(id);
if(Objects.equals(accessionInvGroup.getIsWebVisible(), "N")) {
throw new AccessDeniedException("AccessionInvGroup isn't available for public");
}
return accessionInvGroup;
}
}
......@@ -19,6 +19,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
......@@ -75,6 +76,7 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
......@@ -529,4 +531,23 @@ public class AccessionServiceImpl extends FilteredCRUDServiceImpl<Accession, Acc
LOG.info("Done.");
}
@Override
public Page<Accession> listPublic(AccessionFilter filter, Pageable page) throws SearchException {
if (filter == null) {
filter = new AccessionFilter();
}
filter.webVisible = true;
return list(filter, page);
}
@Override
public Accession loadPublic(long id) {
Accession accession = load(id);
if(Objects.equals(accession.getIsWebVisible(), "N")) {
throw new AccessDeniedException("Accession isn't available for public");
}
return accession;
}
}
......@@ -330,6 +330,177 @@ public class AccessionControllerTest extends AbstractApiV1Test {
/*@formatter:on*/
}
@Test
public void getPublicAccessionDetailsTest() throws Exception {
// build accession
Accession a = new Accession();
a.setAccessionNumberPart1("AccessionNumberPart1");
a.setIsBackedUp(TRUE);
a.setIsCore(TRUE);
a.setIsWebVisible(TRUE);
a.setStatusCode(ACCESSION_STATUS_CODE);
a.setTaxonomySpecies(addTaxonomySpeciesToDB());
a.setSite(DEFAULT_SITE);
a.setBackupLocation1Site(IITA_SITE);
a.setBackupLocation2Site(CIP_SITE);
// add accession to DB
Accession savedAccession = accessionService.create(a);
assertThat(savedAccession, is(notNullValue()));
// add source with linked accession to DB
AccessionSource source = addAccessionSourceToDB(savedAccession);
assertThat(source, is(notNullValue()));
AccessionSource source2 = addAccessionSourceToDB(savedAccession, CommunityCodeValues.ACCESSION_SOURCE_TYPE_DEVELOPED.value, null);
assertThat(source2, is(notNullValue()));
// link source and cooperator
AccessionSourceMap accessionSourceMap = accessionSourceMapService.create(new AccessionSourceMap(source2, cooperator));
assertThat(accessionSourceMap, is(notNullValue()));
// add action with linked accession to DB
AccessionAction savedAction = addAccessionActionToDB(savedAccession);
assertThat(savedAction, is(notNullValue()));
// add ipr with linked accession to DB
AccessionIpr savedIpr = addAccessionIprToDB(savedAccession);
assertThat(savedIpr, is(notNullValue()));
// add pedigree with linked accession to DB
AccessionPedigree savedPedigree = addAccessionPedigreeToDB(savedAccession);
assertThat(savedPedigree, is(notNullValue()));
// add accessionQuarantine with linked accession to DB
AccessionQuarantine savedQuarantine = addAccessionQuarantineToDB(savedAccession);
assertThat(savedQuarantine, is(notNullValue()));
// add citation with linked accession to DB
Citation savedCitation = addCitationToDB(savedAccession);
assertThat(savedCitation, is(notNullValue()));
// add invName to DB
assertThat(inventoryRepository.count(), is(1L));
Inventory sysInventory = inventoryRepository.getSystemInventory(savedAccession);
AccessionInvName savedInvName = addAccessionInvNameToDB(sysInventory, "Plant name");
assertThat(savedInvName, is(notNullValue()));
// populated in aspect
var accessionAnnotation = annotationRepository.findAccessionAnnotations(savedAccession, Inventory.SYSTEM_INVENTORY_FTC).get(0);
/*@formatter:off*/
mockMvc
.perform(get(AccessionController.API_URL.concat("/public/details/{id}"), savedAccession.getId())
.contentType(MediaType.APPLICATION_JSON))
// .andDo(org.springframework.test.web.servlet.result.MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$", not(nullValue())))
.andExpect(jsonPath("$.id", is(savedAccession.getId().intValue())))
.andExpect(jsonPath("$.createdBy", is(AbstractServicesTest.USER_CURATOR1)))
.andExpect(jsonPath("$.modifiedBy", is(AbstractServicesTest.USER_CURATOR1)))
.andExpect(jsonPath("$.ownedBy", is(AbstractServicesTest.USER_CURATOR1)))
// May be serialized as ID only
.andExpect(jsonPath("$.site").exists())
.andExpect(jsonPath("$.accessionNumber", is(GGCE.accessionNumber(savedAccession))))
.andExpect(jsonPath("$.accessionNumberPart1", is(savedAccession.getAccessionNumberPart1())))
.andExpect(jsonPath("$.statusCode", is(savedAccession.getStatusCode())))
.andExpect(jsonPath("$.isBackedUp", is(TRUE)))
.andExpect(jsonPath("$.isCore", is(TRUE)))
.andExpect(jsonPath("$.isWebVisible", is(TRUE)))
.andExpect(jsonPath("$.taxonomySpecies").isMap())
.andExpect(jsonPath("$.backupLocation1Site").isMap())
.andExpect(jsonPath("$.backupLocation1Site.id", is(IITA_SITE.getId().intValue())))
.andExpect(jsonPath("$.backupLocation2Site").isMap())
.andExpect(jsonPath("$.backupLocation2Site.id", is(CIP_SITE.getId().intValue())))
// check sources
.andExpect(jsonPath("$.sources").isArray())
.andExpect(jsonPath("$.sources", hasSize(2)))
.andExpect(jsonPath("$.sources[0].id", is(oneOf(source.getId().intValue(), source2.getId().intValue()))))
.andExpect(jsonPath("$.sources[0].sourceTypeCode", is(oneOf(source.getSourceTypeCode(), source2.getSourceTypeCode()))))
.andExpect(jsonPath("$.sources[0].isWebVisible", is(FALSE)))
.andExpect(jsonPath("$.sources[1].id", is(oneOf(source.getId().intValue(), source2.getId().intValue()))))
.andExpect(jsonPath("$.sources[1].sourceTypeCode", is(oneOf(source.getSourceTypeCode(), source2.getSourceTypeCode()))))
.andExpect(jsonPath("$.sources[1].isWebVisible", is(FALSE)))
// check sourceMaps
.andExpect(jsonPath("$.sourceCooperators").isArray())
.andExpect(jsonPath("$.sourceCooperators", hasSize(1)))
.andExpect(jsonPath("$.sourceCooperators[0].id", is(greaterThan(0))))
.andExpect(jsonPath("$.sourceCooperators[0].accessionSource").isNumber())
.andExpect(jsonPath("$.sourceCooperators[0].accessionSource", is(source2.getId().intValue())))
.andExpect(jsonPath("$.sourceCooperators[0].cooperator").isMap())
.andExpect(jsonPath("$.sourceCooperators[0].cooperator.id", is(cooperator.getId().intValue())))
// check actions
.andExpect(jsonPath("$.actions").isArray())
.andExpect(jsonPath("$.actions", hasSize(1)))
.andExpect(jsonPath("$.actions[0].id", is(savedAction.getId().intValue())))
.andExpect(jsonPath("$.actions[0].actionNameCode", is(savedAction.getActionNameCode())))
.andExpect(jsonPath("$.actions[0].isWebVisible", is(TRUE)))
.andExpect(jsonPath("$.actions[0].notBeforeDate").hasJsonPath())
.andExpect(jsonPath("$.actions[0].notBeforeDateCode").hasJsonPath())
// check ipr
.andExpect(jsonPath("$.ipr").isArray())
.andExpect(jsonPath("$.ipr", hasSize(1)))
.andExpect(jsonPath("$.ipr[0].id", is(savedIpr.getId().intValue())))
.andExpect(jsonPath("$.ipr[0].typeCode", is(savedIpr.getTypeCode())))
// check pedigree
.andExpect(jsonPath("$.pedigree").isArray())
.andExpect(jsonPath("$.pedigree", hasSize(1)))
.andExpect(jsonPath("$.pedigree[0].id", is(savedPedigree.getId().intValue())))
.andExpect(jsonPath("$.pedigree[0].description", is(savedPedigree.getDescription())))
// check quarantine
.andExpect(jsonPath("$.quarantine").isArray())
.andExpect(jsonPath("$.quarantine", hasSize(1)))
.andExpect(jsonPath("$.quarantine[0].id", is(savedQuarantine.getId().intValue())))
.andExpect(jsonPath("$.quarantine[0].quarantineTypeCode", is(savedQuarantine.getQuarantineTypeCode())))
.andExpect(jsonPath("$.quarantine[0].custodialCooperator").isNumber())
.andExpect(jsonPath("$.quarantine[0].custodialCooperator", is(cooperator.getId().intValue())))
// check citations
.andExpect(jsonPath("$.citations").isArray())
.andExpect(jsonPath("$.citations", hasSize(1)))
.andExpect(jsonPath("$.citations[0].id", is(savedCitation.getId().intValue())))
.andExpect(jsonPath("$.citations[0].description", is(savedCitation.getDescription())))
.andExpect(jsonPath("$.citations[0].isAcceptedName", is(TRUE)))
// check names
.andExpect(jsonPath("$.names").isArray())
.andExpect(jsonPath("$.names", hasSize(2)))
// check annotations
.andExpect(jsonPath("$.annotations").isArray())
.andExpect(jsonPath("$.annotations", hasSize(1)))
.andExpect(jsonPath("$.annotations.[0]").isMap())
.andExpect(jsonPath("$.annotations.[0].id", is(accessionAnnotation.getId().intValue())))
.andExpect(jsonPath("$.annotations.[0].annotationTypeCode", is(CommunityCodeValues.ANNOTATION_TYPE_RECEIVED.value)))
.andExpect(jsonPath("$.annotations.[0].annotationDateCode", is(CommunityCodeValues.DATE_FORMAT_DATETIME.value)))
;
/*@formatter:on*/
}
@Test
public void getPublicAccessionDetailsFailedTest() throws Exception {
// build accession WebVisible=false
Accession a = new Accession();
a.setAccessionNumberPart1("AccessionNumberPart1");
a.setIsBackedUp(TRUE);
a.setIsCore(TRUE);
a.setIsWebVisible(FALSE);
a.setStatusCode(ACCESSION_STATUS_CODE);
a.setTaxonomySpecies(addTaxonomySpeciesToDB());
a.setSite(DEFAULT_SITE);
a.setBackupLocation1Site(IITA_SITE);
a.setBackupLocation2Site(CIP_SITE);
// add accession to DB
Accession accession = accessionService.create(a);
assertThat(accession, is(notNullValue()));
mockMvc
.perform(get(AccessionController.API_URL.concat("/public/details/{id}"), accession.getId())
.contentType(MediaType.APPLICATION_JSON))
// .andDo(org.springframework.test.web.servlet.result.MockMvcResultHandlers.print())
.andExpect(status().isForbidden());
}
@Test
public void updateBackupSitesOfAccessionTest() throws Exception {
// build accession
......@@ -686,6 +857,64 @@ public class AccessionControllerTest extends AbstractApiV1Test {
/*@formatter:on*/
}
@Test
public void testPublicAccessionsList() throws Exception {
// build accessions
TaxonomySpecies ts = addTaxonomySpeciesToDB();
Accession a1 = new Accession();
a1.setAccessionNumberPart1("AccessionNumberPart1");
a1.setIsBackedUp(TRUE);
a1.setIsCore(TRUE);
a1.setIsWebVisible(TRUE);
a1.setStatusCode(ACCESSION_STATUS_CODE);
a1.setSite(DEFAULT_SITE);
a1.setBackupLocation1Site(IITA_SITE);
a1.setBackupLocation2Site(CIP_SITE);
a1.setTaxonomySpecies(ts);
Accession accession1 = accessionService.create(a1);
assertThat(accession1, notNullValue());
assertThat(accession1.getId(), notNullValue());
assertThat(accessionRepository.findById(accession1.getId()).isPresent(), is(true));
Accession a2 = new Accession();
a2.setAccessionNumberPart1("AccessionNumberPart2");
a2.setIsBackedUp(TRUE);
a2.setIsCore(TRUE);
a2.setIsWebVisible(FALSE);
a2.setStatusCode(ACCESSION_STATUS_CODE);
a2.setSite(DEFAULT_SITE);
a2.setBackupLocation1Site(IITA_SITE);
a2.setBackupLocation2Site(CIP_SITE);
a2.setTaxonomySpecies(ts);
Accession accession2 = accessionService.create(a2);
assertThat(accession2, notNullValue());
assertThat(accession2.getId(), notNullValue());
assertThat(accessionRepository.findById(accession2.getId()).isPresent(), is(true));
AccessionFilter filter = new AccessionFilter();
/*@formatter:off*/
mockMvc
.perform(post(AccessionController.API_URL + "/public/list")
.contentType(MediaType.APPLICATION_JSON)
.content(verboseMapper.writeValueAsString(filter))
)
// .andDo(org.springframework.test.web.servlet.result.MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$", not(nullValue())))
.andExpect(jsonPath("$.totalElements", is(1)))
.andExpect(jsonPath("$.content").isArray())
.andExpect(jsonPath("$.content[0].id", is(accession1.getId().intValue())))
.andExpect(jsonPath("$.content[0].taxonomySpecies.id", is(ts.getId().intValue())))
;
/*@formatter:on*/
}
@Test
public void testAccessionsListByAccessionInvGroup() throws Exception {
......
......@@ -16,6 +16,7 @@
package org.gringlobal.test.api.v1;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
......@@ -32,6 +33,7 @@ import org.gringlobal.persistence.AccessionInvGroupMapRepository;
import org.gringlobal.persistence.AccessionInvGroupRepository;
import org.gringlobal.service.AccessionInvGroupService;
import org.gringlobal.service.AccessionService;
import org.gringlobal.service.filter.AccessionInvGroupFilter;
import org.gringlobal.test.service.AbstractServicesTest;
import org.junit.After;
import org.junit.Test;
......@@ -186,6 +188,41 @@ public class InventoryGroupControllerTest extends AbstractApiV1Test {
assertThat(membersRepository.exists(QAccessionInvGroupMap.accessionInvGroupMap.inventory.eq(inventory2)), is(true));
}