| /******************************************************************************** |
| * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation |
| * |
| * See the NOTICE file(s) distributed with this work for additional |
| * information regarding copyright ownership. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| ********************************************************************************/ |
| |
| package org.eclipse.mdm.businessobjects.boundary.integrationtest; |
| |
| import static io.restassured.RestAssured.given; |
| import static org.hamcrest.Matchers.equalTo; |
| |
| import org.junit.Assume; |
| import org.junit.FixMethodOrder; |
| import org.junit.Test; |
| import org.junit.runners.MethodSorters; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import com.google.gson.JsonObject; |
| import com.google.gson.JsonParser; |
| import com.google.gson.JsonPrimitive; |
| |
| import io.restassured.http.ContentType; |
| import io.restassured.response.ExtractableResponse; |
| import io.restassured.response.Response; |
| |
| /** |
| * Abstract test class for Entity resources. Tests are executed in |
| * {@code FixMethodOrder(MethodSorters.NAME_ASCENDING)} as {@link test1Create}, |
| * {@link test2Find()}, {@link test3FindAll()}, {@link test4Update()} and |
| * {@link test5Delete()} depend on the entity created by test1Create(). |
| * |
| * @author Alexander Nehmer, science+computing AG Tuebingen (Atos SE) |
| * |
| */ |
| // TODO anehmer on 2017-11-23: test for specific return codes |
| // TODO anehmer on 2017-11-24: expand tests to localization and search attribute |
| // information |
| @FixMethodOrder(MethodSorters.NAME_ASCENDING) |
| public abstract class EntityResourceIntegrationTest extends ResourceIntegrationTest { |
| |
| private static final Logger LOGGER = LoggerFactory.getLogger(EntityResourceIntegrationTest.class); |
| |
| @Test |
| public void test1Create() { |
| // only execute if not skipped by implementing test class |
| Assume.assumeFalse(testsToSkip.get(getContextClass()).get().contains(TestType.CREATE)); |
| |
| createEntity(); |
| } |
| |
| /** |
| * Static method that can be utilised by tests to create a specific entity or is |
| * called indirectly by JUnit |
| */ |
| public static void createEntity() { |
| // do not create entity if it was already created in a currently running |
| // prepareTestData() cascade |
| if (isTestDataValuePresent(TESTDATA_ENTITY_ID)) { |
| LOGGER.debug(getContextClass().getSimpleName() + ".create() aborted as entity " |
| + getTestDataValue(TESTDATA_ENTITY_NAME) + " of type " + getTestDataValue(TESTDATA_ENTITY_TYPE) |
| + " was already created"); |
| return; |
| } |
| |
| LOGGER.debug(getContextClass().getSimpleName() + ".create() sending POST to " |
| + getTestDataValue(TESTDATA_RESOURCE_URI) + " with: " + getTestDataValue(TESTDATA_CREATE_JSON_BODY)); |
| |
| ExtractableResponse<io.restassured.response.Response> response = given().contentType(ContentType.JSON) |
| .body(getTestDataValue(TESTDATA_CREATE_JSON_BODY)).post(getTestDataValue(TESTDATA_RESOURCE_URI)).then() |
| .log().ifError().contentType(ContentType.JSON) |
| // do not check for name equality as that might be created randomly |
| .and().body("data.first().type", equalTo(getTestDataValue(TESTDATA_ENTITY_TYPE))).extract(); |
| |
| LOGGER.debug(getContextClass().getSimpleName() + " created " + response.asString()); |
| |
| putTestDataValue(TESTDATA_ENTITY_ID, response.path("data.first().id")); |
| putTestDataValue(TESTDATA_ENTITY_NAME, response.path("data.first().name")); |
| } |
| |
| @Test |
| public void test2Find() { |
| // only execute if not skipped by implementing test class |
| Assume.assumeFalse(testsToSkip.get(getContextClass()).get().contains(TestType.FIND)); |
| |
| String uri = getTestDataValue(TESTDATA_RESOURCE_URI) + "/" |
| + (EntityResourceIntegrationTest.findByName.getOrElse(getContextClass(), false) |
| ? getTestDataValue(TESTDATA_ENTITY_NAME) |
| : getTestDataValue(TESTDATA_ENTITY_ID)); |
| |
| LOGGER.debug(getContextClass().getSimpleName() + ".find() sending GET to " + uri); |
| |
| ExtractableResponse<Response> response = given().get(uri).then().log().ifError().contentType(ContentType.JSON) |
| .body("data.first().name", equalTo(getTestDataValue(TESTDATA_ENTITY_NAME))) |
| .body("data.first().type", equalTo(getTestDataValue(TESTDATA_ENTITY_TYPE))).extract(); |
| |
| LOGGER.debug(getContextClass().getSimpleName() + " found " + response.asString()); |
| } |
| |
| /** |
| * Finds the first entity of the {@code EntityType} set in the context and put |
| * the found ID in the context for further usage |
| */ |
| public static void findFirst() { |
| LOGGER.debug(getContextClass().getSimpleName() + ".find() sending GET to " |
| + getTestDataValue(TESTDATA_RESOURCE_URI)); |
| |
| String id = given().get(getTestDataValue(TESTDATA_RESOURCE_URI)).then().log().ifError() |
| .contentType(ContentType.JSON) |
| .body("data.first().name", equalTo(getTestDataValue(TESTDATA_ENTITY_NAME))) |
| .body("data.first().type", equalTo(getTestDataValue(TESTDATA_ENTITY_TYPE))).extract() |
| .path("data.first().id"); |
| |
| LOGGER.debug(getContextClass().getSimpleName() + " found " + getTestDataValue(TESTDATA_ENTITY_TYPE) |
| + " with ID " + id); |
| |
| putTestDataValue(TESTDATA_ENTITY_ID, id); |
| } |
| |
| @Test |
| public void test3FindAll() { |
| // only execute if not skipped by implementing test class |
| Assume.assumeFalse(testsToSkip.get(getContextClass()).get().contains(TestType.FINDALL)); |
| |
| LOGGER.debug(getContextClass().getSimpleName() + ".findAll() sending GET to " |
| + getTestDataValue(TESTDATA_RESOURCE_URI)); |
| |
| ExtractableResponse<Response> response = given().get(getTestDataValue(TESTDATA_RESOURCE_URI)).then().log() |
| .ifError().contentType(ContentType.JSON) |
| .body("data.first().type", equalTo(getTestDataValue(TESTDATA_ENTITY_TYPE))).extract(); |
| |
| LOGGER.debug(getContextClass().getSimpleName() + " found all " + response.asString()); |
| } |
| |
| // TODO anehmer on 2017-11-09: test findAll with filter |
| |
| // TODO anehmer on 2018-02-06: update of relations are not checked as the |
| // returned Json does not include relations |
| @Test |
| public void test4Update() { |
| // only execute if not skipped by implementing test class |
| Assume.assumeFalse(testsToSkip.get(getContextClass()).get().contains(TestType.UPDATE)); |
| |
| updateEntity(); |
| } |
| |
| /** |
| * Static method that can be utilised by tests to update a specific entity or is |
| * called indirectly by JUnit |
| */ |
| public static void updateEntity() { |
| JsonObject json; |
| // if no UPDATE_JSON_BODY is defined in implementing test, just run the MimeType |
| // update |
| if (!isTestDataValuePresent(TESTDATA_UPDATE_JSON_BODY)) { |
| json = new JsonObject(); |
| } |
| // or add it to the existing update |
| else { |
| json = new JsonParser().parse(getTestDataValue(TESTDATA_UPDATE_JSON_BODY)).getAsJsonObject(); |
| } |
| json.add("MimeType", new JsonPrimitive("updatedMimeType")); |
| putTestDataValue(TESTDATA_UPDATE_JSON_BODY, json.toString()); |
| |
| String uri = getTestDataValue(TESTDATA_RESOURCE_URI) + "/" + getTestDataValue(TESTDATA_ENTITY_ID); |
| |
| LOGGER.debug(getContextClass().getSimpleName() + ".update() sending PUT to " + uri + " with: " |
| + getTestDataValue(TESTDATA_UPDATE_JSON_BODY)); |
| |
| ExtractableResponse<Response> response = given().contentType(ContentType.JSON) |
| // TODO anehmer on 2017-11-15: the update should use different data but as the |
| // returned JSON represents |
| // the entity prior update it does not make any difference as the update is |
| // performed just based on identical data. We should discuss the PUT-behaviour |
| // instead: return the old or updated object as returning the updated one would |
| // mean to perform another get as the ODSTransaction.update() does not return |
| // the updated entity |
| // TODO anehmer on 2017-11-15: use Description to test update |
| .body(getTestDataValue(TESTDATA_UPDATE_JSON_BODY)).put(uri).then().log().ifError() |
| .contentType(ContentType.JSON) |
| .body("data.first().name", equalTo(getTestDataValue(TESTDATA_ENTITY_NAME))) |
| .body("data.first().type", equalTo(getTestDataValue(TESTDATA_ENTITY_TYPE))) |
| .body("data.first().attributes.find {it.name == 'MimeType'}.value", equalTo("updatedMimeType")) |
| .extract(); |
| |
| LOGGER.debug(getContextClass().getSimpleName() + " updated " + response.asString()); |
| } |
| |
| @Test |
| public void test5Delete() { |
| // only execute if not skipped by implementing test class |
| Assume.assumeFalse(testsToSkip.get(getContextClass()).get().contains(TestType.DELETE)); |
| |
| deleteEntity(); |
| } |
| |
| /** |
| * Static method that can be utilised by tests to delete a specific entity or is |
| * called indirectly by JUnit |
| */ |
| public static void deleteEntity() { |
| String uri = getTestDataValue(TESTDATA_RESOURCE_URI) + "/" + getTestDataValue(TESTDATA_ENTITY_ID); |
| |
| LOGGER.debug(getContextClass().getSimpleName() + ".delete() sending DELETE to " + uri); |
| |
| ExtractableResponse<Response> response = given().delete(uri).then().log().ifError() |
| .body("data.first().name", equalTo(getTestDataValue(TESTDATA_ENTITY_NAME))) |
| .body("data.first().type", equalTo(getTestDataValue(TESTDATA_ENTITY_TYPE))).extract(); |
| |
| LOGGER.debug(getContextClass().getSimpleName() + " deleted " + response.asString()); |
| |
| removeTestDataValue(TESTDATA_ENTITY_ID); |
| } |
| |
| /** |
| * Gets the logger |
| * |
| * @return logger configured to current context class |
| */ |
| public static Logger getLogger() { |
| return LOGGER; |
| } |
| } |