more tests and find-bugs fixes

This commit is contained in:
anhefti 2019-09-10 12:09:43 +02:00
parent 71635c85f6
commit 958a97b556
16 changed files with 200 additions and 53 deletions

View file

@ -31,6 +31,10 @@
<Package name="ch.ethz.seb.sebserver.gui.content.*" />
<Bug pattern="RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT" />
</Match>
<Match>
<Package name="ch.ethz.seb.sebserver.gui.service.page.FieldValidationError" />
<Bug pattern="URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD" />
</Match>

View file

@ -255,7 +255,9 @@ public final class Result<T> {
* @param value resulting value
* @return Result instance contains a resulting value and no error */
public static <T> Result<T> of(final T value) {
assert value != null : "value has null reference";
if (value == null) {
throw new IllegalArgumentException("value has null reference");
}
return new Result<>(value);
}

View file

@ -173,6 +173,9 @@ public class SebExamConfigSettingsForm implements TemplateComposer {
;
} catch (final RuntimeException e) {
log.error("Unexpected error while trying to fetch exam configuration data and create views", e);
throw e;
} catch (final Exception e) {
log.error("Unexpected error while trying to fetch exam configuration data and create views", e);
pageContext.notifyError(e);

View file

@ -28,11 +28,12 @@ public enum ActionCategory {
VARIA(new LocTextKey("sebserver.overall.action.category.varia"), 100),
;
public final LocTextKey title;
public final int slotPosition;
private ActionCategory(final LocTextKey title, final int slotPosition) {
this.title = title;
this.slotPosition = slotPosition;
}
public final LocTextKey title;
public final int slotPosition;
}

View file

@ -157,7 +157,9 @@ public class ActivitiesPane implements TemplateComposer {
.create());
}
sebadmin.setExpanded(true);
if (this.currentUser.get().hasAnyRole(UserRole.SEB_SERVER_ADMIN, UserRole.INSTITUTIONAL_ADMIN)) {
sebadmin.setExpanded(true);
}
// ---- SEB ADMIN ----------------------------------------------------------------------
//--------------------------------------------------------------------------------------
@ -176,17 +178,12 @@ public class ActivitiesPane implements TemplateComposer {
final TreeItem sebConfigs = this.widgetFactory.treeItemLocalized(
navigation,
ActivityDefinition.SEB_CONFIGURATION.displayName);
//sebConfigs.setData(RWT.CUSTOM_VARIANT, CustomVariant.ACTIVITY_TREE_SECTION.key);
// SEB Client Config
if (clientConfigRead) {
final TreeItem clientConfig = (sebConfigs != null)
? this.widgetFactory.treeItemLocalized(
sebConfigs,
ActivityDefinition.SEB_CLIENT_CONFIG.displayName)
: this.widgetFactory.treeItemLocalized(
navigation,
ActivityDefinition.SEB_CLIENT_CONFIG.displayName);
final TreeItem clientConfig = this.widgetFactory.treeItemLocalized(
sebConfigs,
ActivityDefinition.SEB_CLIENT_CONFIG.displayName);
injectActivitySelection(
clientConfig,
actionBuilder
@ -196,20 +193,19 @@ public class ActivitiesPane implements TemplateComposer {
// SEB Exam Config
if (examConfigRead) {
final TreeItem examConfig = (sebConfigs != null)
? this.widgetFactory.treeItemLocalized(
sebConfigs,
ActivityDefinition.SEB_EXAM_CONFIG.displayName)
: this.widgetFactory.treeItemLocalized(
navigation,
ActivityDefinition.SEB_EXAM_CONFIG.displayName);
final TreeItem examConfig = this.widgetFactory.treeItemLocalized(
sebConfigs,
ActivityDefinition.SEB_EXAM_CONFIG.displayName);
injectActivitySelection(
examConfig,
actionBuilder
.newAction(ActionDefinition.SEB_EXAM_CONFIG_LIST)
.create());
}
sebConfigs.setExpanded(true);
if (this.currentUser.get().hasAnyRole(UserRole.EXAM_ADMIN)) {
sebConfigs.setExpanded(true);
}
}
// ---- SEB CONFIGURATION --------------------------------------------------------------
@ -264,7 +260,9 @@ public class ActivitiesPane implements TemplateComposer {
.create());
}
examadmin.setExpanded(true);
if (this.currentUser.get().hasAnyRole(UserRole.EXAM_ADMIN)) {
examadmin.setExpanded(true);
}
}
// ---- EXAM ADMINISTRATION ------------------------------------------------------------
@ -313,7 +311,9 @@ public class ActivitiesPane implements TemplateComposer {
.create());
}
monitoring.setExpanded(true);
if (this.currentUser.get().hasAnyRole(UserRole.EXAM_SUPPORTER)) {
monitoring.setExpanded(true);
}
}
// ---- MONITORING ---------------------------------------------------------------------
@ -349,7 +349,7 @@ public class ActivitiesPane implements TemplateComposer {
// page-selection on (re)load
final PageState state = this.pageService.getCurrentState();
if (state == null) {
final TreeItem item = navigation.getItem(0);
final TreeItem item = getDefaultSelectionFor(navigation, this.currentUser);
final TreeItem actionItem = getActionItem(item);
final PageAction activityAction = getActivitySelection(actionItem);
this.pageService.executePageAction(activityAction);
@ -366,6 +366,22 @@ public class ActivitiesPane implements TemplateComposer {
}
}
private TreeItem getDefaultSelectionFor(final Tree navigation, final CurrentUser currentUser2) {
if (this.currentUser.get().hasAnyRole(UserRole.SEB_SERVER_ADMIN, UserRole.INSTITUTIONAL_ADMIN)) {
return navigation.getItem(0);
} else if (this.currentUser.get().hasAnyRole(UserRole.EXAM_ADMIN)) {
return findItemByActionDefinition(
navigation.getItems(),
ActivityDefinition.SEB_CONFIGURATION);
} else if (this.currentUser.get().hasAnyRole(UserRole.EXAM_SUPPORTER)) {
return findItemByActionDefinition(
navigation.getItems(),
ActivityDefinition.MONITORING_EXAMS);
} else {
return navigation.getItem(0);
}
}
private void selectCurrentItem(final Tree navigation, final TreeItem item) {
final PageState currentState = this.pageService.getCurrentState();
final TreeItem currentItem = findItemByActionDefinition(
@ -516,7 +532,7 @@ public class ActivitiesPane implements TemplateComposer {
item.setData(ATTR_ACTIVITY_SELECTION, action);
}
private final class ActivitiesActionEventListener implements ActionEventListener {
private static final class ActivitiesActionEventListener implements ActionEventListener {
private final Tree navigation;
private ActivitiesActionEventListener(final Tree navigation) {

View file

@ -21,7 +21,6 @@ public abstract class FieldBuilder<T> {
boolean readonly = false;
boolean visible = true;
String defaultLabel = null;
boolean centeredInput = false;
final String name;
final LocTextKey label;
@ -33,11 +32,6 @@ public abstract class FieldBuilder<T> {
this.value = value;
}
public FieldBuilder<T> withCenteredInput() {
this.centeredInput = true;
return this;
}
public FieldBuilder<T> withDefaultLabel(final String defaultLabel) {
this.defaultLabel = defaultLabel;
return this;

View file

@ -275,7 +275,7 @@ public class FormBuilder {
final Label label = new Label(parent, SWT.NONE);
label.setText((StringUtils.isNotBlank(value)) ? value : Constants.EMPTY_NOTE);
final GridData gridData = new GridData(
(centered) ? SWT.FILL : SWT.FILL,
SWT.FILL,
(centered) ? SWT.CENTER : SWT.TOP,
true, false,
hspan, 1);
@ -285,7 +285,6 @@ public class FormBuilder {
label.setData(RWT.CUSTOM_VARIANT, CustomVariant.FORM_CENTER.key);
}
// gridData.heightHint = FORM_ROW_HEIGHT;
label.setLayoutData(gridData);
return label;
}

View file

@ -63,7 +63,7 @@ public class SliderFieldBuilder implements InputFieldBuilder {
slider.setMinimum(Integer.parseInt(split[0]));
slider.setMaximum(Integer.parseInt(split[1]));
} catch (final Exception e) {
} catch (final NumberFormatException e) {
slider.setMinimum(0);
slider.setMaximum(100);
}

View file

@ -64,6 +64,10 @@ public class BrowserViewModeRule implements ValueChangeRule {
context.disableGroup(KEY_MAIN_WINDOW_GROUP);
break;
}
default: {
context.disable(KEY_TOUCH_EXIT);
break;
}
}
} catch (final Exception e) {
log.warn("Failed to apply rule: ", e);

View file

@ -8,9 +8,12 @@
package ch.ethz.seb.sebserver.gui.service.i18n;
import java.io.Serializable;
import java.util.Arrays;
public class LocTextKey {
public class LocTextKey implements Serializable {
private static final long serialVersionUID = 3042143924223909281L;
public final String name;
public final Object[] args;

View file

@ -91,8 +91,7 @@ public class ClientConnectionDetails {
.addField(FormBuilder.text(
Domain.CLIENT_CONNECTION.ATTR_STATUS,
CONNECTION_STATUS_TEXT_KEY,
Constants.EMPTY_NOTE)
.withCenteredInput())
Constants.EMPTY_NOTE))
.addEmptyCell();
this.indicatorMapping
@ -103,8 +102,7 @@ public class ClientConnectionDetails {
indData.indicator.name,
new LocTextKey(indData.indicator.name),
Constants.EMPTY_NOTE)
.withDefaultLabel(indData.indicator.name)
.withCenteredInput())
.withDefaultLabel(indData.indicator.name))
.addEmptyCell();
});

View file

@ -151,7 +151,7 @@ public class SebClientConfigServiceImpl implements SebClientConfigService {
final CharSequence encryptionPassword = this.sebClientConfigDAO
.getConfigPasswortCipher(config.getModelId())
.getOrThrow();
.getOr(null);
final String plainTextConfig = getPlainXMLConfig(config);

View file

@ -447,15 +447,10 @@ public class SebClientConnectionServiceImpl implements SebClientConnectionServic
final String requestClientAddress,
final String existingClientAddress) {
if (examId == null) {
return null;
}
if (requestClientAddress.equals(existingClientAddress)) {
return null;
}
if (!isVDI(examId)) {
if (examId == null ||
requestClientAddress == null ||
requestClientAddress.equals(existingClientAddress) ||
!isVDI(examId)) {
return null;
}

View file

@ -236,14 +236,27 @@ public class ExamAPI_V1_Controller {
final HttpServletRequest request,
final HttpServletResponse response) throws IOException {
// if an examId is provided with the request, update the connection first
if (formParams != null && formParams.containsKey(API.EXAM_API_PARAM_EXAM_ID)) {
final String examId = formParams.getFirst(API.EXAM_API_PARAM_EXAM_ID);
final Long institutionId = getInstitutionId(principal);
final ClientConnection connection = this.sebClientConnectionService.updateClientConnection(
connectionToken,
institutionId,
Long.valueOf(examId),
null,
null)
.getOrThrow();
if (log.isDebugEnabled()) {
log.debug("Updated connection: {}", connection);
}
//handshakeUpdate(connectionToken, Long.valueOf(examId), null, principal, request);
}
final ServletOutputStream outputStream = response.getOutputStream();
try {
// if an examId is provided with the request, update the connection first
if (formParams != null && formParams.containsKey(API.EXAM_API_PARAM_EXAM_ID)) {
final String examId = formParams.getFirst(API.EXAM_API_PARAM_EXAM_ID);
handshakeUpdate(connectionToken, Long.valueOf(examId), null, principal, request);
}
final ClientConnectionData connection = this.examSessionService
.getConnectionData(connectionToken)

View file

@ -10,12 +10,15 @@ package ch.ethz.seb.sebserver.gui.integration;
import static org.junit.Assert.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import org.apache.commons.io.IOUtils;
import org.joda.time.DateTimeZone;
import org.junit.Test;
import org.junit.jupiter.api.AfterAll;
@ -25,6 +28,7 @@ import org.springframework.test.context.jdbc.Sql;
import ch.ethz.seb.sebserver.gbl.api.API;
import ch.ethz.seb.sebserver.gbl.model.Domain;
import ch.ethz.seb.sebserver.gbl.model.Domain.SEB_CLIENT_CONFIGURATION;
import ch.ethz.seb.sebserver.gbl.model.EntityName;
import ch.ethz.seb.sebserver.gbl.model.EntityProcessingReport;
import ch.ethz.seb.sebserver.gbl.model.Page;
@ -37,6 +41,7 @@ import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType;
import ch.ethz.seb.sebserver.gbl.model.sebconfig.SebClientConfig;
import ch.ethz.seb.sebserver.gbl.model.user.PasswordChange;
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
@ -65,6 +70,13 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.SaveLmsS
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.quiz.GetQuizData;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.quiz.GetQuizPage;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.quiz.ImportAsExam;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.ActivateClientConfig;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.DeactivateClientConfig;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.ExportClientConfig;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.GetClientConfig;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.GetClientConfigPage;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.NewClientConfig;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.SaveClientConfig;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.ActivateUserAccount;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.ChangePassword;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccount;
@ -757,4 +769,101 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
assertEquals("001111", t2.color);
}
@Test
@Order(8)
// *************************************
// Use Case 8: Login as TestInstAdmin and create a SEB Client Configuration
// - create one with and one without password
// - activate one config
// - export both configurations
public void testUsecase8() throws IOException {
final RestServiceImpl restService = createRestServiceForUser(
"TestInstAdmin",
"987654321",
new GetClientConfig(),
new GetClientConfigPage(),
new NewClientConfig(),
new SaveClientConfig(),
new ActivateClientConfig(),
new DeactivateClientConfig(),
new ExportClientConfig());
// create SEB Client Config without password protection
final Result<SebClientConfig> newConfigResponse = restService
.getBuilder(NewClientConfig.class)
.withFormParam(Domain.SEB_CLIENT_CONFIGURATION.ATTR_NAME, "No Password Protection")
.withFormParam(SebClientConfig.ATTR_FALLBACK_START_URL, "http://fallback.com/fallback")
.call();
assertNotNull(newConfigResponse);
assertFalse(newConfigResponse.hasError());
final SebClientConfig sebClientConfig = newConfigResponse.get();
assertEquals("No Password Protection", sebClientConfig.name);
assertFalse(sebClientConfig.isActive());
assertEquals("http://fallback.com/fallback", sebClientConfig.fallbackStartURL);
// activate the new Client Configuration
final Result<EntityProcessingReport> activationResponse = restService
.getBuilder(ActivateClientConfig.class)
.withURIVariable(API.PARAM_MODEL_ID, sebClientConfig.getModelId())
.call();
assertNotNull(activationResponse);
assertFalse(activationResponse.hasError());
final Result<SebClientConfig> getConfigResponse = restService
.getBuilder(GetClientConfig.class)
.withURIVariable(API.PARAM_MODEL_ID, sebClientConfig.getModelId())
.call();
assertNotNull(getConfigResponse);
assertFalse(getConfigResponse.hasError());
final SebClientConfig activeConfig = getConfigResponse.get();
assertTrue(activeConfig.isActive());
// create a config with password protection
final Result<SebClientConfig> configWithPasswordResponse = restService
.getBuilder(NewClientConfig.class)
.withFormParam(Domain.SEB_CLIENT_CONFIGURATION.ATTR_NAME, "With Password Protection")
.withFormParam(SebClientConfig.ATTR_FALLBACK_START_URL, "http://fallback.com/fallback")
.withFormParam(SEB_CLIENT_CONFIGURATION.ATTR_ENCRYPT_SECRET, "123")
.withFormParam(SebClientConfig.ATTR_CONFIRM_ENCRYPT_SECRET, "123")
.call();
assertNotNull(configWithPasswordResponse);
assertFalse(configWithPasswordResponse.hasError());
final SebClientConfig configWithPassword = configWithPasswordResponse.get();
assertEquals("With Password Protection", configWithPassword.name);
assertFalse(configWithPassword.isActive());
assertEquals("http://fallback.com/fallback", configWithPassword.fallbackStartURL);
// export client config No Password Protection
Result<InputStream> exportResponse = restService
.getBuilder(ExportClientConfig.class)
.withURIVariable(API.PARAM_MODEL_ID, sebClientConfig.getModelId())
.call();
assertNotNull(exportResponse);
assertFalse(exportResponse.hasError());
List<String> readLines = IOUtils.readLines(exportResponse.get(), "UTF-8");
assertNotNull(readLines);
assertFalse(readLines.isEmpty());
assertTrue(readLines.get(0).startsWith("plnd"));
// export client config With Password Protection
exportResponse = restService
.getBuilder(ExportClientConfig.class)
.withURIVariable(API.PARAM_MODEL_ID, configWithPassword.getModelId())
.call();
assertNotNull(exportResponse);
assertFalse(exportResponse.hasError());
readLines = IOUtils.readLines(exportResponse.get(), "UTF-8");
assertNotNull(readLines);
assertFalse(readLines.isEmpty());
assertTrue(readLines.get(0).startsWith("pswd"));
}
}

View file

@ -172,6 +172,12 @@ public class SebExamConfigurationRequestTest extends ExamAPIIntegrationTester {
.getCache(ExamSessionCacheService.CACHE_NAME_SEB_CONFIG_EXAM);
final ValueWrapper config = cache.get(EXAM_ID);
assertNotNull(config);
// check connection has examId
final MockHttpServletResponse establishConnectionResponse = super.establishConnection(
accessToken, connectionToken, null, "test");
assertTrue(HttpStatus.OK.value() == establishConnectionResponse.getStatus());
}
@Test