diff --git a/findbugs-excludes.xml b/findbugs-excludes.xml
index 6880981a..13ddcdd9 100644
--- a/findbugs-excludes.xml
+++ b/findbugs-excludes.xml
@@ -24,7 +24,7 @@
-
+
diff --git a/src/main/java/ch/ethz/seb/sebserver/WebSecurityConfig.java b/src/main/java/ch/ethz/seb/sebserver/WebSecurityConfig.java
index 9c595304..9c76f1a8 100644
--- a/src/main/java/ch/ethz/seb/sebserver/WebSecurityConfig.java
+++ b/src/main/java/ch/ethz/seb/sebserver/WebSecurityConfig.java
@@ -105,8 +105,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements E
.ignoring()
.antMatchers("/error")
.antMatchers(this.examAPIDiscoveryEndpoint)
- .antMatchers(this.adminAPIEndpoint + API.INFO_ENDPOINT + API.LOGO_PATH_SEGMENT + "/**")
- .and();
+ .antMatchers(this.adminAPIEndpoint + API.INFO_ENDPOINT + API.LOGO_PATH_SEGMENT + "/**");
}
@RequestMapping("/error")
diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/Constants.java b/src/main/java/ch/ethz/seb/sebserver/gbl/Constants.java
index 0f3f45e6..065c4903 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/Constants.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/Constants.java
@@ -30,6 +30,9 @@ public final class Constants {
public static final String EMPTY_NOTE = "--";
public static final String FORM_URL_ENCODED_SEPARATOR = "&";
public static final String FORM_URL_ENCODED_NAME_VALUE_SEPARATOR = "=";
+ public static final String URL_PORT_SEPARATOR = ":";
+ public static final String URL_ADDRESS_SEPARATOR = "://";
+ public static final String URL_PATH_SEPARATOR = "/";
public static final String PERCENTAGE = "%";
diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/EntityName.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/EntityName.java
index 913d6e0b..16194eb7 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/EntityName.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/EntityName.java
@@ -60,6 +60,16 @@ public class EntityName extends EntityKey {
return new EntityKey(getModelId(), getEntityType());
}
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return super.equals(obj);
+ }
+
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/Orientation.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/Orientation.java
index 783e09b2..3b810a1a 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/Orientation.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/Orientation.java
@@ -136,11 +136,11 @@ public final class Orientation implements Entity {
return this.groupId;
}
- public Integer getXPosition() {
+ public Integer getxPosition() {
return this.xPosition;
}
- public Integer getYPosition() {
+ public Integer getyPosition() {
return this.yPosition;
}
diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/session/ClientConnectionData.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/session/ClientConnectionData.java
index 3f044511..98e5e2cc 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/session/ClientConnectionData.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/session/ClientConnectionData.java
@@ -69,7 +69,7 @@ public class ClientConnectionData {
while (i1.hasNext()) {
final IndicatorValue iv1 = i1.next();
final IndicatorValue iv2 = i2.next();
- if (iv1.getType() != iv2.getType() || iv1.getValue() != iv2.getValue()) {
+ if (iv1.getType() != iv2.getType() || Math.round(iv1.getValue() - iv2.getValue()) < .0001) {
return false;
}
}
diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/ModalInputDialog.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/ModalInputDialog.java
index cddfb5ea..48aa1a2d 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/ModalInputDialog.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/ModalInputDialog.java
@@ -41,7 +41,7 @@ public class ModalInputDialog extends Dialog {
private final WidgetFactory widgetFactory;
private int dialogWidth = 400;
private int dialogHeight = 600;
- private final int buttonWidth = 100;
+ private int buttonWidth = 100;
public ModalInputDialog(
final Shell parent,
@@ -62,6 +62,11 @@ public class ModalInputDialog extends Dialog {
return this;
}
+ public ModalInputDialog setButtonWidth(final int buttonWidth) {
+ this.buttonWidth = buttonWidth;
+ return this;
+ }
+
public void open(
final LocTextKey title,
final Consumer callback,
diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/OpenEdxLmsAPITemplate.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/OpenEdxLmsAPITemplate.java
index 258ce25a..128afb85 100644
--- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/OpenEdxLmsAPITemplate.java
+++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/OpenEdxLmsAPITemplate.java
@@ -267,11 +267,11 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate {
final URL url = new URL(lmsSetup.lmsApiUrl);
final int port = url.getPort();
_externalStartURI = this.webserviceInfo.getHttpScheme() +
- "://" + externalAddressAlias +
+ Constants.URL_ADDRESS_SEPARATOR + externalAddressAlias +
((port >= 0)
- ? ":" + port
- : "")
- + "/";
+ ? Constants.URL_PORT_SEPARATOR + port
+ : StringUtils.EMPTY)
+ + Constants.URL_PATH_SEPARATOR;
log.info("Use external address for course access: {}", _externalStartURI);
} catch (final Exception e) {
diff --git a/src/test/java/ch/ethz/seb/sebserver/gui/integration/UseCasesIntegrationTest.java b/src/test/java/ch/ethz/seb/sebserver/gui/integration/UseCasesIntegrationTest.java
index e2fce5b9..d709dab1 100644
--- a/src/test/java/ch/ethz/seb/sebserver/gui/integration/UseCasesIntegrationTest.java
+++ b/src/test/java/ch/ethz/seb/sebserver/gui/integration/UseCasesIntegrationTest.java
@@ -26,6 +26,8 @@ import ch.ethz.seb.sebserver.gbl.model.Domain;
import ch.ethz.seb.sebserver.gbl.model.EntityName;
import ch.ethz.seb.sebserver.gbl.model.EntityProcessingReport;
import ch.ethz.seb.sebserver.gbl.model.Page;
+import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
+import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamType;
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;
@@ -34,8 +36,12 @@ 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;
import ch.ethz.seb.sebserver.gbl.util.Result;
+import ch.ethz.seb.sebserver.gbl.util.Utils;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCallError;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestServiceImpl;
+import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExam;
+import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamPage;
+import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.SaveExam;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.ActivateInstitution;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitutionNames;
@@ -46,7 +52,9 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.GetLmsSe
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.GetLmsSetupNames;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.NewLmsSetup;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.SaveLmsSetup;
+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.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;
@@ -301,7 +309,8 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
"TestInstAdmin",
"987654321",
new GetInstitutionNames(),
- new NewUserAccount());
+ new NewUserAccount(),
+ new ActivateUserAccount());
final String instId = restService.getBuilder(GetInstitutionNames.class)
.call()
@@ -328,6 +337,12 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
assertNotNull(result);
assertFalse(result.hasError());
+ Result activation = restService.getBuilder(ActivateUserAccount.class)
+ .withURIVariable(API.PARAM_MODEL_ID, result.get().uuid)
+ .call();
+ assertNotNull(activation);
+ assertFalse(activation.hasError());
+
result = restService.getBuilder(NewUserAccount.class)
.withFormParam(Domain.USER.ATTR_INSTITUTION_ID, instId)
.withFormParam(Domain.USER.ATTR_NAME, "examSupport2")
@@ -343,6 +358,12 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
assertNotNull(result);
assertFalse(result.hasError());
+ activation = restService.getBuilder(ActivateUserAccount.class)
+ .withURIVariable(API.PARAM_MODEL_ID, result.get().uuid)
+ .call();
+ assertNotNull(activation);
+ assertFalse(activation.hasError());
+
result = restService.getBuilder(NewUserAccount.class)
.withFormParam(Domain.USER.ATTR_INSTITUTION_ID, instId)
.withFormParam(Domain.USER.ATTR_NAME, "examSupport1")
@@ -358,6 +379,12 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
assertNotNull(result);
assertFalse(result.hasError());
+ activation = restService.getBuilder(ActivateUserAccount.class)
+ .withURIVariable(API.PARAM_MODEL_ID, result.get().uuid)
+ .call();
+ assertNotNull(activation);
+ assertFalse(activation.hasError());
+
}
@Test
@@ -544,4 +571,96 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
.call();
}
+ @Test
+ @Order(6)
+ // *************************************
+ // Use Case 6: Login as examAdmin2
+ // - Check if there are some quizzes form previous LMS Setup
+ // - Import a quiz as Exam
+ // - get exam page and check the exam is there
+ // - edit exam property and save again
+ public void testUsecase6() {
+ final RestServiceImpl restService = createRestServiceForUser(
+ "examAdmin2",
+ "examAdmin2",
+ new GetUserAccountNames(),
+ new NewLmsSetup(),
+ new GetQuizPage(),
+ new GetQuizData(),
+ new ImportAsExam(),
+ new SaveExam(),
+ new GetExam(),
+ new GetExamPage());
+
+ final Result> userNamesResult = restService
+ .getBuilder(GetUserAccountNames.class)
+ .call();
+
+ assertNotNull(userNamesResult);
+ assertFalse(userNamesResult.hasError());
+
+ final String userId = userNamesResult.get()
+ .stream()
+ .filter(userName -> "examSupport2".equals(userName.name))
+ .findFirst()
+ .map(EntityName::getModelId)
+ .orElse(null);
+
+ // check quizzes are defines
+ final Result> quizPageCall = restService
+ .getBuilder(GetQuizPage.class)
+ .call();
+
+ assertNotNull(quizPageCall);
+ assertFalse(quizPageCall.hasError());
+ final Page quizzes = quizPageCall.get();
+ assertFalse(quizzes.isEmpty());
+ final QuizData quizData = quizzes.content.get(0);
+ assertNotNull(quizData);
+ assertEquals("Demo Quiz 1", quizData.name);
+
+ // import quiz as exam
+ final Result newExamResult = restService
+ .getBuilder(ImportAsExam.class)
+ .withFormParam(QuizData.QUIZ_ATTR_LMS_SETUP_ID, String.valueOf(quizData.lmsSetupId))
+ .withFormParam(QuizData.QUIZ_ATTR_ID, quizData.id)
+ .call();
+
+ assertNotNull(newExamResult);
+ assertFalse(newExamResult.hasError());
+ final Exam newExam = newExamResult.get();
+
+ assertEquals("Demo Quiz 1", newExam.name);
+ assertEquals(ExamType.UNDEFINED, newExam.type);
+ assertTrue(newExam.supporter.isEmpty());
+
+ // create Exam with type and supporter examSupport2
+ final Exam examForSave = new Exam(
+ newExam.id,
+ newExam.institutionId,
+ newExam.lmsSetupId,
+ newExam.externalId,
+ newExam.name,
+ newExam.description,
+ newExam.startTime,
+ newExam.endTime,
+ newExam.startURL,
+ ExamType.MANAGED,
+ null, null, null,
+ Utils.immutableCollectionOf(userId),
+ true);
+
+ final Result savedExamResult = restService
+ .getBuilder(SaveExam.class)
+ .withBody(examForSave)
+ .call();
+
+ assertNotNull(savedExamResult);
+ assertFalse(savedExamResult.hasError());
+ final Exam savedExam = savedExamResult.get();
+
+ assertEquals(ExamType.MANAGED, savedExam.type);
+ assertFalse(savedExam.supporter.isEmpty());
+ }
+
}