SEBSERV-139 TestBot integration and testing and fixes

This commit is contained in:
anhefti 2020-08-11 16:01:47 +02:00
parent 65cdb1dc52
commit 6980715e2f
7 changed files with 40 additions and 23 deletions

View file

@ -569,7 +569,7 @@ public final class Utils {
return (hexString.length() < 2) ? "0" + hexString : hexString; return (hexString.length() < 2) ? "0" + hexString : hexString;
} }
public static String toJsonArrayValue(final Map<String, String> attributes) { public static String toJsonObject(final Map<String, String> attributes) {
if (attributes == null || attributes.isEmpty()) { if (attributes == null || attributes.isEmpty()) {
return StringUtils.EMPTY; return StringUtils.EMPTY;
} }
@ -578,7 +578,7 @@ public final class Utils {
.entrySet() .entrySet()
.stream() .stream()
.reduce( .reduce(
new StringBuilder(), new StringBuilder(Constants.CURLY_BRACE_OPEN),
(sb, entry) -> sb (sb, entry) -> sb
.append(Constants.DOUBLE_QUOTE) .append(Constants.DOUBLE_QUOTE)
.append(entry.getKey()) .append(entry.getKey())
@ -588,7 +588,8 @@ public final class Utils {
.append(entry.getValue()) .append(entry.getValue())
.append(Constants.DOUBLE_QUOTE) .append(Constants.DOUBLE_QUOTE)
.append(Constants.COMMA), .append(Constants.COMMA),
StringBuilder::append); StringBuilder::append)
.append(Constants.CURLY_BRACE_CLOSE);
if (builder.length() > 0) { if (builder.length() > 0) {
return builder return builder

View file

@ -19,6 +19,10 @@ import ch.ethz.seb.sebserver.gbl.model.Page;
import ch.ethz.seb.sebserver.gbl.model.PageSortOrder; import ch.ethz.seb.sebserver.gbl.model.PageSortOrder;
import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.gbl.util.Result;
/** This implements a page supplier within a static list.
* Currently ordering and filtering is not possible and must be implemented.
*
* @param <T> the type of the list/page elements */
public class StaticListPageSupplier<T> implements PageSupplier<T> { public class StaticListPageSupplier<T> implements PageSupplier<T> {
private final EntityType entityType; private final EntityType entityType;
@ -45,6 +49,7 @@ public class StaticListPageSupplier<T> implements PageSupplier<T> {
private int pageNumber; private int pageNumber;
private int pageSize; private int pageSize;
private String column; private String column;
@SuppressWarnings("unused")
private PageSortOrder order; private PageSortOrder order;
private StaticListTableBuilderAdapter(final List<T> list) { private StaticListTableBuilderAdapter(final List<T> list) {

View file

@ -315,7 +315,7 @@ public class ClientConnectionDAOImpl implements ClientConnectionDAO {
.build() .build()
.execute() .execute()
.stream() .stream()
.filter(cc -> ConnectionStatus.ACTIVE.name() == cc.getStatus()) .filter(cc -> ConnectionStatus.ACTIVE.name().equals(cc.getStatus()))
.map(ClientConnectionRecord::getConnectionToken) .map(ClientConnectionRecord::getConnectionToken)
.collect(Collectors.toSet())); .collect(Collectors.toSet()));
} }

View file

@ -28,11 +28,11 @@ import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.api.JSONMapper; import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
import ch.ethz.seb.sebserver.gbl.model.exam.Exam; import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ServerType;
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator; import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.IndicatorType; import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.IndicatorType;
import ch.ethz.seb.sebserver.gbl.model.exam.OpenEdxSEBRestriction; import ch.ethz.seb.sebserver.gbl.model.exam.OpenEdxSEBRestriction;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ServerType;
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup; 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.institution.LmsSetup.LmsType;
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
@ -214,11 +214,15 @@ public class ExamAdminServiceImpl implements ExamAdminService {
@Override @Override
public Result<Boolean> isExamProctoringEnabled(final Long examId) { public Result<Boolean> isExamProctoringEnabled(final Long examId) {
return this.additionalAttributesDAO.getAdditionalAttribute( final Result<Boolean> result = this.additionalAttributesDAO.getAdditionalAttribute(
EntityType.EXAM, EntityType.EXAM,
examId, examId,
ProctoringSettings.ATTR_ENABLE_PROCTORING) ProctoringSettings.ATTR_ENABLE_PROCTORING)
.map(rec -> rec != null && BooleanUtils.toBoolean(rec.getValue())); .map(rec -> BooleanUtils.toBoolean(rec.getValue()));
if (result.hasError()) {
return Result.of(false);
}
return result;
} }
@Override @Override

View file

@ -400,7 +400,7 @@ public class SEBClientConnectionServiceImpl implements SEBClientConnectionServic
} catch (final Exception e) { } catch (final Exception e) {
log.error( log.error(
"Failed to process proctoring initialization for established SEB client connection: {}", "Failed to process proctoring initialization for established SEB client connection: {}",
clientConnection.connectionToken); clientConnection.connectionToken, e);
} }
} }

View file

@ -25,6 +25,7 @@ import org.springframework.stereotype.Service;
import ch.ethz.seb.sebserver.SEBServerInit; import ch.ethz.seb.sebserver.SEBServerInit;
import ch.ethz.seb.sebserver.SEBServerInitEvent; import ch.ethz.seb.sebserver.SEBServerInitEvent;
import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction.InstructionType; import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction.InstructionType;
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.gbl.util.Result;
@ -96,16 +97,24 @@ public class SEBInstructionServiceImpl implements SEBInstructionService {
final boolean needsConfirm) { final boolean needsConfirm) {
return Result.tryCatch(() -> { return Result.tryCatch(() -> {
final boolean isActive = this.clientConnectionDAO final boolean isActive = this.clientConnectionDAO
.isActiveConnection(examId, connectionToken) .isActiveConnection(examId, connectionToken)
.getOr(false); .getOr(false);
if (isActive) { if (isActive) {
final String attributesString = Utils.toJsonArrayValue(attributes); try {
this.clientInstructionDAO final String attributesString = new JSONMapper().writeValueAsString(attributes);
.insert(examId, type, attributesString, connectionToken, needsConfirm) this.clientInstructionDAO
.map(inst -> this.instructions.putIfAbsent(inst.getConnectionToken(), inst)) .insert(examId, type, attributesString, connectionToken, needsConfirm)
.onError(error -> log.error("Failed to put instruction: ", error)) .map(inst -> {
.getOrThrow(); this.instructions.putIfAbsent(inst.getConnectionToken(), inst);
return inst;
})
.onError(error -> log.error("Failed to put instruction: ", error))
.getOrThrow();
} catch (final Exception e) {
throw new RuntimeException("Unexpected: ", e);
}
} }
}); });
} }
@ -120,7 +129,7 @@ public class SEBInstructionServiceImpl implements SEBInstructionService {
return Result.tryCatch(() -> { return Result.tryCatch(() -> {
final String attributesString = Utils.toJsonArrayValue(attributes); final String attributesString = Utils.toJsonObject(attributes);
final Set<String> activeConnections = this.clientConnectionDAO final Set<String> activeConnections = this.clientConnectionDAO
.filterActive(examId, connectionTokens) .filterActive(examId, connectionTokens)
.getOrElse(Collections::emptySet); .getOrElse(Collections::emptySet);
@ -177,9 +186,7 @@ public class SEBInstructionServiceImpl implements SEBInstructionService {
.append(JSON_ATTR) .append(JSON_ATTR)
.append(Constants.DOUBLE_QUOTE) .append(Constants.DOUBLE_QUOTE)
.append(Constants.COLON) .append(Constants.COLON)
.append(Constants.CURLY_BRACE_OPEN) .append(attributes);
.append(attributes)
.append(Constants.CURLY_BRACE_CLOSE);
} }
return sBuilder return sBuilder

View file

@ -282,16 +282,16 @@ public class ExamAPI_V1_Controller {
final String pingNumString = request.getParameter(API.EXAM_API_PING_NUMBER); final String pingNumString = request.getParameter(API.EXAM_API_PING_NUMBER);
final String instructionConfirm = request.getParameter(API.EXAM_API_PING_INSTRUCTION_CONFIRM); final String instructionConfirm = request.getParameter(API.EXAM_API_PING_INSTRUCTION_CONFIRM);
if (instructionConfirm != null) {
this.sebClientConnectionService.confirmInstructionDone(connectionToken, instructionConfirm);
}
final String instruction = this.sebClientConnectionService final String instruction = this.sebClientConnectionService
.notifyPing( .notifyPing(
connectionToken, connectionToken,
Long.parseLong(timeStampString), Long.parseLong(timeStampString),
pingNumString != null ? Integer.parseInt(pingNumString) : -1); pingNumString != null ? Integer.parseInt(pingNumString) : -1);
if (instructionConfirm != null) {
this.sebClientConnectionService.confirmInstructionDone(connectionToken, instructionConfirm);
}
if (instruction == null) { if (instruction == null) {
response.setStatus(HttpStatus.NO_CONTENT.value()); response.setStatus(HttpStatus.NO_CONTENT.value());
return; return;