Java tutorial
/* * This program is part of the OpenLMIS logistics management information system platform software. * Copyright 2017 VillageReach * * This program is free software: you can redistribute it and/or modify it under the terms * of the GNU Affero General Public License as published by the Free Software Foundation, either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Affero General Public License for more details. You should have received a copy of * the GNU Affero General Public License along with this program. If not, see * http://www.gnu.org/licenses. For additional information contact info@OpenLMIS.org. */ package org.openlmis.fulfillment.web; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.post; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; import static org.mockito.BDDMockito.given; import static org.springframework.util.CollectionUtils.isEmpty; import com.google.common.collect.Lists; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.CollectionLikeType; import com.fasterxml.jackson.databind.type.TypeFactory; import com.github.tomakehurst.wiremock.junit.WireMockRule; import com.jayway.restassured.RestAssured; import com.jayway.restassured.config.ObjectMapperConfig; import com.jayway.restassured.config.RestAssuredConfig; import org.junit.Before; import org.junit.Rule; import org.junit.runner.RunWith; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.openlmis.fulfillment.domain.BaseEntity; import org.openlmis.fulfillment.domain.OrderFileColumn; import org.openlmis.fulfillment.domain.OrderFileTemplate; import org.openlmis.fulfillment.domain.OrderNumberConfiguration; import org.openlmis.fulfillment.repository.OrderFileColumnRepository; import org.openlmis.fulfillment.repository.OrderFileTemplateRepository; import org.openlmis.fulfillment.repository.OrderNumberConfigurationRepository; import org.openlmis.fulfillment.service.ExporterBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.embedded.LocalServerPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.data.domain.Page; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; import guru.nidi.ramltester.RamlDefinition; import guru.nidi.ramltester.RamlLoaders; import guru.nidi.ramltester.restassured.RestAssuredClient; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.UUID; import javax.annotation.PostConstruct; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @DirtiesContext public abstract class BaseWebIntegrationTest { protected static final String ID = "id"; protected static final String MESSAGE_KEY = "messageKey"; protected static final UUID INITIAL_USER_ID = UUID.fromString("35316636-6264-6331-2d34-3933322d3462"); protected static final String RAML_ASSERT_MESSAGE = "HTTP request/response should match RAML definition."; protected static final String REFERENCEDATA_API_USERS = "/api/users/"; protected static final String REFERENCEDATA_API_RIGHTS = "/api/rights/"; protected static final RamlDefinition ramlDefinition = RamlLoaders.fromClasspath() .load("api-definition-raml.yaml").ignoringXheaders(); protected static final String UUID_REGEX = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"; protected static final String CONTENT_TYPE = "Content-Type"; protected static final String APPLICATION_JSON = "application/json"; protected static final String FACILITY_ID = "1d5bdd9c-8702-11e6-ae22-56b6b6499611"; protected static final String ORDER_ID = "orderId"; private static final String MOCK_CHECK_RESULT = "{" + " \"aud\": [\n" + " \"auth\",\n" + " \"example\",\n" + " \"requisition\",\n" + " \"notification\",\n" + " \"referencedata\",\n" + " \"fulfillment\"\n" + " ],\n" + " \"user_name\": \"admin\",\n" + " \"referenceDataUserId\": \"35316636-6264-6331-2d34-3933322d3462\",\n" + " \"scope\": [\n" + " \"read\",\n" + " \"write\"\n" + " ],\n" + " \"exp\": 1474500343,\n" + " \"authorities\": [\n" + " \"USER\",\n" + " \"ADMIN\"\n" + " ],\n" + " \"client_id\": \"trusted-client\"\n" + "}"; private static final String MOCK_TOKEN_REQUEST_RESPONSE = "{" + " \"access_token\": \"418c89c5-7f21-4cd1-a63a-38c47892b0fe\",\n" + " \"token_type\": \"bearer\",\n" + " \"expires_in\": 847,\n" + " \"scope\": \"read write\",\n" + " \"referenceDataUserId\": \"35316636-6264-6331-2d34-3933322d3462\"\n" + "}"; private static final String MOCK_FIND_PROGRAM_RESULT = "{" + " \"id\":\"5c5a6f68-8658-11e6-ae22-56b6b6499611\"," + " \"code\":\"Program Code\"," + " \"name\":\"Program Name\"," + " \"active\": true," + " \"showNonFullSupplyTab\": false," + " \"periodsSkippable\":true" + "}"; private static final String MOCK_FIND_FACILITY_RESULT = "{" + " \"id\":\"" + FACILITY_ID + "\",\n" + " \"code\":\"facilityCode\",\n" + " \"name\":\"facilityNameA\",\n" + " \"active\":true,\n" + " \"enabled\":true,\n" + " \"operator\": {\n" + " \"id\": \"9456c3e9-c4a6-4a28-9e08-47ceb16a4121\",\n" + " \"code\": \"moh\",\n" + " \"name\": \"Ministry of Health\",\n" + " \"displayOrder\": 1\n" + " },\n" + " \"type\": {\n" + " \"id\": \"ac1d268b-ce10-455f-bf87-9c667da8f060\",\n" + " \"code\": \"health_center\",\n" + " \"name\": \"Health Center\",\n" + " \"active\": \"true\",\n" + " \"displayOrder\": 1\n" + " },\n" + " \"geographicZone\": {\n" + " \"id\": \"4e471242-da63-436c-8157-ade3e615c848\",\n" + " \"code\": \"Mal\",\n" + " \"name\": \"Malawi\",\n" + " \"level\": {\n" + " \"id\": \"6b78e6c6-292e-4733-bb9c-3d802ad61206\",\n" + " \"name\": \"Country\",\n" + " \"code\": \"Country\",\n" + " \"levelNumber\": 1\n" + " }\n" + " }\n" + "}"; protected static final String MOCK_SEARCH_SUPPLYING_FACILITY_RESULT = "[" + MOCK_FIND_FACILITY_RESULT + "]"; private static final String MOCK_FIND_STOCK_ADJUSTMENT_REASONS_RESULT = "[{" + " \"id\":\"62c44f68-9200-1de2-22ea-34b5f98f121a\",\n" + " \"programId\":\"5c5a6f68-8658-11e6-ae22-56b6b6499611\",\n" + " \"additive\":\"true\",\n" + " \"displayOrder\":1\n" + "}]"; private static final String MOCK_FIND_USER_RESULT = "{" + "\"id\":\"35316636-6264-6331-2d34-3933322d3462\"," + "\"username\":\"admin\"," + "\"firstName\":\"Admin\"," + "\"lastName\":\"User\"," + "\"email\":\"example@mail.com\"," + "\"verified\":false," + "\"active\": true," + "\"loginRestricted\": false," + "\"homeFacilityId\": \"" + FACILITY_ID + "\"," + "\"fulfillmentFacilities\": [" + MOCK_FIND_FACILITY_RESULT + "]" + "}"; private static final String MOCK_USER_SEARCH_RESULT = "{" + "\"content\": [" + MOCK_FIND_USER_RESULT + "]," + "\"last\": true," + "\"totalPages\": 1," + "\"totalElements\": 1," + "\"sort\": null," + "\"first\": true," + "\"numberOfElements\": 1," + "\"size\": 1," + "\"number\": 1" + "}"; private static final String MOCK_FIND_USER_SUPERVISED_PROGRAMS = "[{" + " \"id\":\"5c5a6f68-8658-11e6-ae22-56b6b6499611\"" + "}]"; private static final String MOCK_FIND_PRODUCT_RESULT = "{" + " \"id\":\"cd9e1412-8703-11e6-ae22-56b6b6499611\",\n" + " \"productCode\":\"Product Code\",\n" + " \"fullProductName\":\"Product Name\",\n" + " \"netContent\":10,\n" + " \"packRoundingThreshold\":5,\n" + " \"roundToZero\":false\n" + "}"; private static final String MOCK_SEARCH_PRODUCTS = "{" + "\"content\": [" + MOCK_FIND_PRODUCT_RESULT + "]," + "\"last\": true," + "\"totalPages\": 1," + "\"totalElements\": 1," + "\"sort\": null," + "\"first\": true," + "\"numberOfElements\": 1," + "\"size\": 1," + "\"number\": 1" + "}"; private static final String MOCK_FIND_PROCESSING_SCHEDULE = "{" + " \"id\":\"c73ad6a4-895c-11e6-ae22-56b6b6499611\"," + " \"code\":\"Schedule Code\"," + " \"name\":\"Schedule Name\"" + "}"; private static final String MOCK_SEARCH_PROCESSING_SCHEDULE = "[" + MOCK_FIND_PROCESSING_SCHEDULE + "]"; private static final String MOCK_FIND_PROCESSING_PERIOD = "{" + " \"id\":\"4c6b05c2-894b-11e6-ae22-56b6b6499611\"," + " \"name\":\"Period Name\"," + " \"description\":\"Period Description\"," + "\"processingSchedule\":" + MOCK_FIND_PROCESSING_SCHEDULE + "," + " \"startDate\":\"2017-01-01\"," + " \"endDate\":\"2017-01-31\"" + " }"; private static final String MOCK_FIND_FACILITY_TYPE = "{" + " \"id\":\"7fbef45e-8961-11e6-ae22-56b6b6499611\"," + " \"code\":\"Facility Type Code\"" + "}"; private static final String MOCK_FIND_ORDERABLE_DISPLAY_CATEGORY = "{" + " \"id\":\"6d469a06-8962-11e6-ae22-56b6b6499611\"" + "}"; private static final String MOCK_FIND_PROGRAM_ORDERABLE = "{" + " \"id\":\"047cb32a-8962-11e6-ae22-56b6b6499611\"," + " \"program\":" + MOCK_FIND_PROGRAM_RESULT + "," + " \"product\":" + MOCK_FIND_PRODUCT_RESULT + "," + " \"OrderableDisplayCategory\":" + MOCK_FIND_ORDERABLE_DISPLAY_CATEGORY + "}"; private static final String MOCK_SEARCH_SUPPLY_LINE_RESULT = "[{\n" + " \"id\":\"99cd664e-871a-11e6-ae22-56b6b6499611\",\n" + " \"supervisoryNode\":\"aa66b244-871a-11e6-ae22-56b6b6499611\",\n" + " \"program\":\"aa66b58c-871a-11e6-ae22-56b6b6499611\",\n" + " \"supplyingFacility\":\"aa66b762-871a-11e6-ae22-56b6b6499611\"\n" + "}]"; private static final String MOCK_SEARCH_FACILITY_TYPE_APPROVED_PRODUCTS = "[{" + " \"id\":\"d0d5e0d6-8962-11e6-ae22-56b6b6499611\"," + " \"facilityType\":" + MOCK_FIND_FACILITY_TYPE + "," + " \"programOrderable\":" + MOCK_FIND_PROGRAM_ORDERABLE + "," + " \"maxPeriodsOfStock\": 2" + "}]"; private static final String MOCK_SEARCH_PROCESSING_PERIODS = "[" + MOCK_FIND_PROCESSING_PERIOD + "]"; private static final String MOCK_SEARCH_FACILITIES_WITH_SIMILAR_CODE_OR_NAME = "[" + "{" + " \"id\":\"aaf12a5a-8b16-11e6-ae22-56b6b6499611\",\n" + " \"code\":\"facilityCode\",\n" + " \"name\":\"facilityNameA\",\n" + " \"active\":true,\n" + " \"enabled\":true\n" + "}" + "]"; private static final String MOCK_RIGHT_SEARCH = "[" + "{" + "\"id\":\"00fb0d27-7ea7-4196-adf0-61103058e0e8\",\n" + "\"name\":\"rightName\"\n" + "}" + "]"; private static final String MOCK_HAS_RIGHT = "{ \"result\":true }"; private static final String ORDER = "order"; @Rule public WireMockRule wireMockRule = new WireMockRule(80); @LocalServerPort private int randomPort; protected RestAssuredClient restAssured; protected static final String BASE_URL = System.getenv("BASE_URL"); @MockBean protected OrderNumberConfigurationRepository orderNumberConfigurationRepository; @MockBean protected OrderFileTemplateRepository orderFileTemplateRepository; @MockBean protected OrderFileColumnRepository orderFileColumnRepository; @Autowired ExporterBuilder exporter; @Autowired private ObjectMapper objectMapper; /** * Constructor for test. */ public BaseWebIntegrationTest() { // This mocks the auth check to always return valid admin credentials. wireMockRule.stubFor(post(urlEqualTo("/api/oauth/check_token")) .willReturn(aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody(MOCK_CHECK_RESULT))); // This mocks the auth token request response wireMockRule.stubFor(post(urlPathEqualTo("/api/oauth/token?grant_type=client_credentials")).willReturn( aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody(MOCK_TOKEN_REQUEST_RESPONSE))); // This mocks the call to auth to post to an auth user. wireMockRule.stubFor(post(urlPathEqualTo("/api/users")).willReturn(aResponse().withStatus(200))); // This mocks the call to notification to post a notification. wireMockRule.stubFor(post(urlPathEqualTo("/api/notification")).willReturn(aResponse().withStatus(200))); // This mocks searching for users wireMockRule.stubFor(post(urlMatching("/api/users/search.*")).willReturn( aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody(MOCK_USER_SEARCH_RESULT))); // This mocks for find one user wireMockRule.stubFor(get(urlMatching(REFERENCEDATA_API_USERS + UUID_REGEX + ".*")).willReturn( aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody(MOCK_FIND_USER_RESULT))); // This mocks the call to retrieve programs supervised by the user wireMockRule.stubFor( get(urlMatching(REFERENCEDATA_API_USERS + UUID_REGEX + "/programs.*")).willReturn(aResponse() .withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody(MOCK_FIND_USER_SUPERVISED_PROGRAMS))); // This mocks the call to retrieve fulfillment facilities of the user wireMockRule.stubFor(get(urlMatching(REFERENCEDATA_API_USERS + UUID_REGEX + "/fulfillmentFacilities.*")) .willReturn(aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON) .withBody("[" + MOCK_FIND_FACILITY_RESULT + "]"))); // This mocks for find stock adjustment reasons for program wireMockRule.stubFor(get(urlMatching("/api/stockAdjustmentReasons/search.*")).willReturn(aResponse() .withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody(MOCK_FIND_STOCK_ADJUSTMENT_REASONS_RESULT))); // This mocks for find one facility wireMockRule.stubFor(get(urlMatching("/api/facilities/" + UUID_REGEX + ".*")).willReturn( aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody(MOCK_FIND_FACILITY_RESULT))); // This mocks searching for orderables wireMockRule.stubFor(get(urlMatching("/api/orderables.*")) .willReturn(aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody(MOCK_SEARCH_PRODUCTS))); // This mocks for find one orderable wireMockRule.stubFor(get(urlMatching("/api/orderables/" + UUID_REGEX + ".*")).willReturn( aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody(MOCK_FIND_PRODUCT_RESULT))); // This mocks searching for supplying facilities wireMockRule.stubFor(get(urlMatching("/api/facilities/supplying.*")).willReturn(aResponse() .withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody(MOCK_SEARCH_SUPPLYING_FACILITY_RESULT))); // This mocks searching for processingSchedules wireMockRule.stubFor(get(urlMatching("/api/processingSchedules/search.*")).willReturn( aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody(MOCK_SEARCH_PROCESSING_SCHEDULE))); // This mocks retrieving single processing schedule wireMockRule.stubFor(get(urlMatching("/api/processingSchedules/" + UUID_REGEX + ".*")).willReturn( aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody(MOCK_FIND_PROCESSING_SCHEDULE))); // This mocks searching for supplyLines wireMockRule.stubFor(get(urlMatching("/api/supplyLines/searchByUUID.*")).willReturn( aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody(MOCK_SEARCH_SUPPLY_LINE_RESULT))); // This mocks searching for facilityTypeApprovedProducts wireMockRule.stubFor(get(urlMatching("/api/facilityTypeApprovedProducts/search.*")).willReturn(aResponse() .withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody(MOCK_SEARCH_FACILITY_TYPE_APPROVED_PRODUCTS))); // This mocks searching for processingPeriods wireMockRule.stubFor(get(urlMatching("/api/processingPeriods/search.*")).willReturn( aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody(MOCK_SEARCH_PROCESSING_PERIODS))); // This mocks searching for processingPeriods by UUID and date wireMockRule.stubFor(get(urlMatching("/api/processingPeriods/searchByUUIDAndDate.*")).willReturn( aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody(MOCK_SEARCH_PROCESSING_PERIODS))); // This mocks searching facilities with similar facilityCode or facilityName wireMockRule.stubFor(get(urlMatching("/api/facilities/search.*")) .willReturn(aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON) .withBody(MOCK_SEARCH_FACILITIES_WITH_SIMILAR_CODE_OR_NAME))); // This mocks for checking if a user has a right wireMockRule.stubFor(get(urlMatching(REFERENCEDATA_API_USERS + UUID_REGEX + "/hasRight.*")) .willReturn(aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody(MOCK_HAS_RIGHT))); // This mocks searching for right by name wireMockRule.stubFor(get(urlMatching(REFERENCEDATA_API_RIGHTS + "search.*")) .willReturn(aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody(MOCK_RIGHT_SEARCH))); } /** * Initialize the REST Assured client. Done here and not in the constructor, so that randomPort is * available. */ @PostConstruct public void init() { RestAssured.baseURI = BASE_URL; RestAssured.port = randomPort; RestAssured.config = RestAssuredConfig.config().objectMapperConfig( new ObjectMapperConfig().jackson2ObjectMapperFactory((clazz, charset) -> objectMapper)); RestAssured.enableLoggingOfRequestAndResponseIfValidationFails(); restAssured = ramlDefinition.createRestAssured(); } @Before public void setUpBootstrapData() { // data from bootstrap.sql OrderFileTemplate template = addOrderFileTemplate(); OrderFileColumn column1 = addOrderFileColumn("33b2d2e9-3167-46b0-95d4-1295be9afc21", true, "fulfillment.header.order.number", "Order number", true, 1, null, ORDER, "orderCode", null, null, template); OrderFileColumn column2 = addOrderFileColumn("6b8d331b-a0dd-4a1f-aafb-40e6a72ab9f6", true, "fulfillment.header.facility.code", "Facility code", true, 2, null, ORDER, "facilityId", "Facility", "code", template); OrderFileColumn column3 = addOrderFileColumn("752cda76-0db5-4b6e-bb79-0f531ab78e2e", true, "fulfillment.header.product.code", "Product code", true, 3, null, "lineItem", "orderableId", "Orderable", "productCode", template); OrderFileColumn column4 = addOrderFileColumn("9e825396-269d-4873-baa4-89054e2722f5", true, "fulfillment.header.product.name", "Product name", true, 4, null, "lineItem", "orderableId", "Orderable", "fullProductName", template); OrderFileColumn column5 = addOrderFileColumn("cd57f329-f549-4717-882e-ecbf98122c39", true, "fulfillment.header.ordered.quantity", "Ordered quantity", true, 5, null, "lineItem", "orderedQuantity", null, null, template); OrderFileColumn column6 = addOrderFileColumn("d0e1aec7-1556-4dc1-8e21-d80a2d76b678", true, "fulfillment.header.period", "Period", true, 6, "MM/yy", ORDER, "processingPeriodId", "ProcessingPeriod", "startDate", template); OrderFileColumn column7 = addOrderFileColumn("dab6eec0-4cb4-4d4c-94b7-820308da73ff", true, "fulfillment.header.order.date", "Order date", true, 7, "dd/MM/yy", ORDER, "createdDate", null, null, template); given(orderFileColumnRepository.findAll()) .willReturn(Lists.newArrayList(column1, column2, column3, column4, column5, column6, column7)); addOrderNumberConfiguration(); } private OrderNumberConfiguration addOrderNumberConfiguration() { OrderNumberConfiguration configuration = new OrderNumberConfiguration("ORDER-", true, false, true); configuration.setId(UUID.fromString("70543032-b131-4219-b44d-7781d29db330")); given(orderNumberConfigurationRepository.findOne(configuration.getId())).willReturn(configuration); given(orderNumberConfigurationRepository.findAll()).willReturn(Lists.newArrayList(configuration)); return configuration; } private OrderFileTemplate addOrderFileTemplate() { OrderFileTemplate template = new OrderFileTemplate(); template.setId(UUID.fromString("457ed5b0-80d7-4cb6-af54-e3f6138c8128")); template.setFilePrefix("O"); template.setHeaderInFile(true); template.setOrderFileColumns(Lists.newArrayList()); given(orderFileTemplateRepository.findOne(template.getId())).willReturn(template); given(orderFileTemplateRepository.findAll()).willReturn(Lists.newArrayList(template)); return template; } private OrderFileColumn addOrderFileColumn(String id, boolean openLmisField, String dataFieldLabel, String columnLabel, boolean include, int position, String format, String nested, String keyPath, String related, String relatedKeyPath, OrderFileTemplate template) { OrderFileColumn column = new OrderFileColumn(); column.setId(UUID.fromString(id)); column.setOpenLmisField(openLmisField); column.setDataFieldLabel(dataFieldLabel); column.setColumnLabel(columnLabel); column.setInclude(include); column.setPosition(position); column.setFormat(format); column.setNested(nested); column.setKeyPath(keyPath); column.setRelated(related); column.setRelatedKeyPath(relatedKeyPath); column.setOrderFileTemplate(template); template.getOrderFileColumns().add(column); given(orderFileColumnRepository.findOne(column.getId())).willReturn(column); return column; } protected String getTokenHeader() { return "Bearer 418c89c5-7f21-4cd1-a63a-38c47892b0fe"; } protected UUID getNonMatchingUuid(UUID match) { UUID uuid; do { uuid = UUID.randomUUID(); } while (uuid.equals(match)); return uuid; } public UUID getSharedFacilityId() { return UUID.fromString("aaf12a5a-8b16-11e6-ae22-56b6b6499611"); } void denyUserAllRights() { wireMockRule.stubFor(get(urlMatching(REFERENCEDATA_API_USERS + UUID_REGEX + "/hasRight.*")).willReturn( aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody("{ \"result\":\"false\" }"))); } void denyUserAllRightsForWarehouse(UUID warehouse) { String url = String.format("%s%s/hasRight.*warehouseId=%s.*", REFERENCEDATA_API_USERS, UUID_REGEX, warehouse); wireMockRule.stubFor(get(urlMatching(url)).willReturn( aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON).withBody("{ \"result\":\"false\" }"))); } <T> List<T> getPageContent(Page page, Class<T> type) { List content = page.getContent(); if (isEmpty(content)) { // nothing to do return Collections.emptyList(); } if (type.isInstance(content.get(0))) { // content contains instances of the given type return Collections.checkedList(content, type); } if (content.get(0) instanceof Map) { // jackson does not convert json to correct type // instead it use default operation and objects are // represented by Map // We have to do manually convert map to the given type =( ObjectMapper mapper = new ObjectMapper(); mapper.findAndRegisterModules(); TypeFactory factory = mapper.getTypeFactory(); CollectionLikeType collectionType = factory.constructCollectionLikeType(List.class, type); return mapper.convertValue(content, collectionType); } throw new IllegalStateException("the page content contains unsupported type"); } static class SaveAnswer<T extends BaseEntity> implements Answer<T> { @Override public T answer(InvocationOnMock invocation) throws Throwable { T obj = (T) invocation.getArguments()[0]; if (null == obj) { return null; } if (null == obj.getId()) { obj.setId(UUID.randomUUID()); } extraSteps(obj); return obj; } void extraSteps(T obj) { // should be overridden if extra steps are required. } } }