blob: d77faef46af0f56806f35cb7e6b638d1376a74c5 [file] [log] [blame]
/********************************************************************************
* Copyright (c) 2015-2018 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 io.restassured.filter.session.SessionFilter;
import io.restassured.http.ContentType;
import io.restassured.response.ExtractableResponse;
import io.restassured.response.Response;
import io.vavr.control.Try;
/**
* 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);
private static final SessionFilter sessionFilter = new SessionFilter();
@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().filter(sessionFilter)
.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().filter(sessionFilter).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().filter(sessionFilter).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().filter(sessionFilter)
.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
@Test
public void test4Patch() {
// only execute if not skipped by implementing test class
Assume.assumeFalse(testsToSkip.get(getContextClass()).get().contains(TestType.PATCH));
patchEntity();
}
/**
* Static method that can be utilised by tests to update a specific entity or is
* called indirectly by JUnit
*/
public static void patchEntity() {
String bodyValue = Try.of(() -> getTestDataValue(TESTDATA_UPDATE_JSON_BODY))
.getOrElse(getTestDataValue(TESTDATA_CREATE_JSON_BODY));
JsonObject json = new JsonParser().parse(bodyValue).getAsJsonObject();
// patch the json that was returned on create()
io.vavr.collection.List.ofAll(json.getAsJsonArray("data").get(0).getAsJsonObject().getAsJsonArray("attributes"))
.filter(attr -> attr.getAsJsonObject().get("name").getAsString().equals("MimeType")).get()
.getAsJsonObject().addProperty("value", "updatedmimetype");
String uri = getTestDataValue(TESTDATA_RESOURCE_URI) + "/" + getTestDataValue(TESTDATA_ENTITY_ID);
LOGGER.debug(
getContextClass().getSimpleName() + ".update() sending PUT to " + uri + " with: " + json.toString());
ExtractableResponse<Response> response = given().filter(sessionFilter).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(json.toString()).post(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().filter(sessionFilter).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;
}
}