Skip to content

Commit

Permalink
feat(api-test): add new JUnit5 extension @DBSetting IQSS#8251
Browse files Browse the repository at this point in the history
This extension allows to set and reset database settings within
a target Dataverse instance. It will make sure to reset to
old setting or remove the setting if not set before the test.

This was introduced for three reasons:
1. Don't execute a test if the setting did not go through
2. Don't forget to reset or remove to keep a consistent state after a
   test execution
3. Make the code more readable, as setting the setting has been part of
   the test before (which is bad design and might go booboo, see 2)
  • Loading branch information
poikilotherm committed Nov 22, 2021
1 parent 414f8e0 commit 45ae750
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -1780,17 +1780,17 @@ static Response enableSetting(SettingsServiceBean.Key settingKey) {
return response;
}

static Response deleteSetting(SettingsServiceBean.Key settingKey) {
public static Response deleteSetting(SettingsServiceBean.Key settingKey) {
Response response = given().when().delete("/api/admin/settings/" + settingKey);
return response;
}

static Response getSetting(SettingsServiceBean.Key settingKey) {
public static Response getSetting(SettingsServiceBean.Key settingKey) {
Response response = given().when().get("/api/admin/settings/" + settingKey);
return response;
}

static Response setSetting(SettingsServiceBean.Key settingKey, String value) {
public static Response setSetting(SettingsServiceBean.Key settingKey, String value) {
Response response = given().body(value).when().put("/api/admin/settings/" + settingKey);
return response;
}
Expand Down
19 changes: 19 additions & 0 deletions src/test/java/edu/harvard/iq/dataverse/api/helpers/DBSetting.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package edu.harvard.iq.dataverse.api.helpers;

import edu.harvard.iq.dataverse.settings.SettingsServiceBean;
import org.junit.jupiter.api.extension.ExtendWith;

import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.TYPE})
@Repeatable(value = DBSettings.class)
@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(DBSettingExtension.class)
public @interface DBSetting {
SettingsServiceBean.Key name();
String value();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package edu.harvard.iq.dataverse.api.helpers;

import com.jayway.restassured.response.Response;
import edu.harvard.iq.dataverse.api.UtilIT;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ExtensionContext.Store;
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;

import javax.servlet.http.HttpServletResponse;
import java.util.logging.Logger;

public class DBSettingExtension implements BeforeTestExecutionCallback, AfterTestExecutionCallback {

private static final Logger logger = Logger.getLogger(DBSettingExtension.class.getCanonicalName());

private Store getStore(ExtensionContext context) {
return context.getStore(Namespace.create(getClass(), context.getRequiredTestClass(), context.getRequiredTestMethod()));
}

@Override
public void beforeTestExecution(ExtensionContext extensionContext) throws Exception {
extensionContext.getTestMethod().ifPresent(method -> {
DBSetting[] settings = method.getAnnotationsByType(DBSetting.class);
for (DBSetting setting : settings) {
// get the setting ...
Response getSetting = UtilIT.getSetting(setting.name());
if (getSetting.getStatusCode() == HttpServletResponse.SC_OK) {
String oldSetting = getSetting.getBody().jsonPath().getString("data.message");
logger.fine("Found former value \""+oldSetting+"\" for "+setting.name()+".");
// ... and store in context to restore later
getStore(extensionContext).put(setting.name(), oldSetting);
} else if (getSetting.getStatusCode() == HttpServletResponse.SC_NOT_FOUND) {
logger.fine("No former value for "+setting.name()+" present.");
// do nothing - will delete setting later
} else {
Assumptions.assumeTrue(
getSetting.getStatusCode() == HttpServletResponse.SC_OK ||
getSetting.getStatusCode() == HttpServletResponse.SC_NOT_FOUND,
() -> "Aborting test: requesting setting \""+setting.name()+"\" failed with status "+getSetting.getStatusCode());
}

// set to new value
Response setSetting = UtilIT.setSetting(setting.name(), setting.value());

// assume set or abort
Assumptions.assumeTrue(setSetting.getStatusCode() == HttpServletResponse.SC_OK,
() -> "Aborting test: setting failed for \""+setting.name()+"\" with status "+setSetting.getStatusCode());

logger.fine("Set "+setting.name()+" to \""+setting.value()+"\".");
}
});
}

@Override
public void afterTestExecution(ExtensionContext extensionContext) throws Exception {
extensionContext.getTestMethod().ifPresent(method -> {
DBSetting[] settings = method.getAnnotationsByType(DBSetting.class);
for (DBSetting setting : settings) {
// get a stored setting from context
String oldSetting = getStore(extensionContext).remove(setting.name(), String.class);
// if present before, restore
if (oldSetting != null) {
logger.fine("Restoring setting "+setting.name()+" during cleanup to value \""+oldSetting+"\".");
Response restoreSetting = UtilIT.setSetting(setting.name(), oldSetting);
restoreSetting.then().assertThat().statusCode(HttpServletResponse.SC_OK);
// if NOT present before, delete
} else {
logger.fine("Deleting setting "+setting.name()+" during cleanup.");
Response deleteSetting = UtilIT.deleteSetting(setting.name());
deleteSetting.then().assertThat().statusCode(HttpServletResponse.SC_OK);
}
}
});
}
}
15 changes: 15 additions & 0 deletions src/test/java/edu/harvard/iq/dataverse/api/helpers/DBSettings.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package edu.harvard.iq.dataverse.api.helpers;

import org.junit.jupiter.api.extension.ExtendWith;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(DBSettingExtension.class)
public @interface DBSettings {
DBSetting[] value() default {};
}

0 comments on commit 45ae750

Please sign in to comment.