SEBSERV-148 refactoring and backend

This commit is contained in:
anhefti 2021-02-24 16:38:30 +01:00
parent 2f2a318f9d
commit 3dddaf9051
12 changed files with 195 additions and 55 deletions

View file

@ -52,7 +52,9 @@ public class APIMessage implements Serializable {
EXAM_CONSISTENCY_VALIDATION_CONFIG("1401", HttpStatus.OK, "No SEB Exam Configuration defined for the Exam"), EXAM_CONSISTENCY_VALIDATION_CONFIG("1401", HttpStatus.OK, "No SEB Exam Configuration defined for the Exam"),
EXAM_CONSISTENCY_VALIDATION_SEB_RESTRICTION("1402", HttpStatus.OK, EXAM_CONSISTENCY_VALIDATION_SEB_RESTRICTION("1402", HttpStatus.OK,
"SEB restriction API available but Exam not restricted on LMS side yet"), "SEB restriction API available but Exam not restricted on LMS side yet"),
EXAM_CONSISTENCY_VALIDATION_INDICATOR("1403", HttpStatus.OK, "No Indicator defined for the Exam"); EXAM_CONSISTENCY_VALIDATION_INDICATOR("1403", HttpStatus.OK, "No Indicator defined for the Exam"),
BINDING_ERROR("1500", HttpStatus.BAD_REQUEST, "External binding error");
public final String messageCode; public final String messageCode;
public final HttpStatus httpStatus; public final HttpStatus httpStatus;

View file

@ -25,7 +25,8 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.validation.ValidProctoringS
public class ProctoringServiceSettings implements Entity { public class ProctoringServiceSettings implements Entity {
public enum ProctoringServerType { public enum ProctoringServerType {
JITSI_MEET JITSI_MEET,
ZOOM
} }
public static final String ATTR_ENABLE_PROCTORING = "enableProctoring"; public static final String ATTR_ENABLE_PROCTORING = "enableProctoring";

View file

@ -35,7 +35,7 @@ public class ProctoringServlet extends HttpServlet {
private static final long serialVersionUID = 3475978419653411800L; private static final long serialVersionUID = 3475978419653411800L;
// @formatter:off // @formatter:off
private static final String HTML = private static final String JITSI_WINDOW_HTML =
"<!DOCTYPE html>" + "<!DOCTYPE html>" +
"<html>" + "<html>" +
"<head>" + "<head>" +
@ -103,15 +103,22 @@ public class ProctoringServlet extends HttpServlet {
(ProctoringWindowData) httpSession (ProctoringWindowData) httpSession
.getAttribute(ProctoringGUIService.SESSION_ATTR_PROCTORING_DATA); .getAttribute(ProctoringGUIService.SESSION_ATTR_PROCTORING_DATA);
final String script = String.format( switch (proctoringData.connectionData.proctoringServerType) {
HTML, case JITSI_MEET: {
proctoringData.connectionData.serverHost, final String script = String.format(
proctoringData.connectionData.roomName, JITSI_WINDOW_HTML,
proctoringData.connectionData.accessToken, proctoringData.connectionData.serverHost,
proctoringData.connectionData.serverHost, proctoringData.connectionData.roomName,
proctoringData.connectionData.subject); proctoringData.connectionData.accessToken,
resp.getOutputStream().println(script); proctoringData.connectionData.serverHost,
proctoringData.connectionData.subject);
resp.getOutputStream().println(script);
break;
}
default:
throw new RuntimeException(
"Unsupported proctoring server type: " + proctoringData.connectionData.proctoringServerType);
}
} }
private boolean isAuthenticated( private boolean isAuthenticated(

View file

@ -8,13 +8,13 @@
package ch.ethz.seb.sebserver.gui.form; package ch.ethz.seb.sebserver.gui.form;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.slf4j.Logger; import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;
import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.api.API; import ch.ethz.seb.sebserver.gbl.api.API;
import ch.ethz.seb.sebserver.gbl.api.APIMessage; import ch.ethz.seb.sebserver.gbl.api.APIMessage;
import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.api.EntityType;
@ -35,8 +35,6 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCallError;
public class FormHandle<T extends Entity> { public class FormHandle<T extends Entity> {
private static final Logger log = LoggerFactory.getLogger(FormHandle.class);
public static final String FIELD_VALIDATION_LOCTEXT_PREFIX = "sebserver.form.validation.fieldError."; public static final String FIELD_VALIDATION_LOCTEXT_PREFIX = "sebserver.form.validation.fieldError.";
private final PageService pageService; private final PageService pageService;
@ -137,30 +135,49 @@ public class FormHandle<T extends Entity> {
public boolean handleError(final Exception error) { public boolean handleError(final Exception error) {
if (error instanceof RestCallError) { if (error instanceof RestCallError) {
((RestCallError) error)
final List<APIMessage> fieldValidationErrors = ((RestCallError) error)
.getErrorMessages() .getErrorMessages()
.stream() .stream()
.filter(APIMessage.ErrorMessage.FIELD_VALIDATION::isOf) .filter(APIMessage.ErrorMessage.FIELD_VALIDATION::isOf)
.collect(Collectors.toList());
final List<APIMessage> noneFieldValidationErrors = ((RestCallError) error)
.getErrorMessages()
.stream()
.filter(message -> !APIMessage.ErrorMessage.FIELD_VALIDATION.isOf(message))
.collect(Collectors.toList());
fieldValidationErrors
.stream()
.map(FieldValidationError::new) .map(FieldValidationError::new)
.forEach(fve -> this.form.process( .forEach(fve -> this.form.process(
name -> name.equals(fve.fieldName), name -> name.equals(fve.fieldName),
fieldAccessor -> showValidationError(fieldAccessor, fve))); fieldAccessor -> showValidationError(fieldAccessor, fve)));
if (!noneFieldValidationErrors.isEmpty()) {
handleUnexpectedError(new RestCallError(
PageContext.GENERIC_SAVE_ERROR_TEXT_KEY,
noneFieldValidationErrors));
return false;
}
return true; return true;
} else { } else {
log.error("Unexpected error while trying to post form: {}", error.getMessage()); handleUnexpectedError(error);
final EntityType resultType = this.post.getEntityType();
if (resultType != null) {
this.pageContext.notifySaveError(resultType, error);
} else {
this.pageContext.notifyError(
new LocTextKey(PageContext.GENERIC_SAVE_ERROR_TEXT_KEY, Constants.EMPTY_NOTE),
error);
}
return false; return false;
} }
} }
private void handleUnexpectedError(final Exception error) {
if (this.post != null && this.post.getEntityType() != null) {
this.pageContext.notifySaveError(this.post.getEntityType(), error);
} else {
this.pageContext.notifyError(
new LocTextKey(PageContext.GENERIC_SAVE_ERROR_TEXT_KEY, StringUtils.EMPTY),
error);
}
}
public boolean hasAnyError() { public boolean hasAnyError() {
return this.form.hasAnyError(); return this.form.hasAnyError();
} }

View file

@ -61,11 +61,11 @@ public interface ExamAdminService {
/** Save the given proctoring service settings for an existing Exam. /** Save the given proctoring service settings for an existing Exam.
* *
* @param examId the exam identifier * @param examId the exam identifier
* @param examProctoring The proctoring service settings to save for the exam * @param proctoringServiceSettings The proctoring service settings to save for the exam
* @return Result refer to saved proctoring service settings or to an error when happened. */ * @return Result refer to saved proctoring service settings or to an error when happened. */
Result<ProctoringServiceSettings> saveProctoringServiceSettings( Result<ProctoringServiceSettings> saveProctoringServiceSettings(
Long examId, Long examId,
ProctoringServiceSettings examProctoring); ProctoringServiceSettings proctoringServiceSettings);
/** This indicates if proctoring is set and enabled for a certain exam. /** This indicates if proctoring is set and enabled for a certain exam.
* *

View file

@ -206,47 +206,49 @@ public class ExamAdminServiceImpl implements ExamAdminService {
@Override @Override
@Transactional @Transactional
public Result<ProctoringServiceSettings> saveProctoringServiceSettings(final Long examId, public Result<ProctoringServiceSettings> saveProctoringServiceSettings(
final ProctoringServiceSettings examProctoring) { final Long examId,
final ProctoringServiceSettings proctoringServiceSettings) {
return Result.tryCatch(() -> { return Result.tryCatch(() -> {
this.additionalAttributesDAO.saveAdditionalAttribute( this.additionalAttributesDAO.saveAdditionalAttribute(
EntityType.EXAM, EntityType.EXAM,
examId, examId,
ProctoringServiceSettings.ATTR_ENABLE_PROCTORING, ProctoringServiceSettings.ATTR_ENABLE_PROCTORING,
String.valueOf(examProctoring.enableProctoring)); String.valueOf(proctoringServiceSettings.enableProctoring));
this.additionalAttributesDAO.saveAdditionalAttribute( this.additionalAttributesDAO.saveAdditionalAttribute(
EntityType.EXAM, EntityType.EXAM,
examId, examId,
ProctoringServiceSettings.ATTR_SERVER_TYPE, ProctoringServiceSettings.ATTR_SERVER_TYPE,
examProctoring.serverType.name()); proctoringServiceSettings.serverType.name());
this.additionalAttributesDAO.saveAdditionalAttribute( this.additionalAttributesDAO.saveAdditionalAttribute(
EntityType.EXAM, EntityType.EXAM,
examId, examId,
ProctoringServiceSettings.ATTR_SERVER_URL, ProctoringServiceSettings.ATTR_SERVER_URL,
examProctoring.serverURL); proctoringServiceSettings.serverURL);
this.additionalAttributesDAO.saveAdditionalAttribute( this.additionalAttributesDAO.saveAdditionalAttribute(
EntityType.EXAM, EntityType.EXAM,
examId, examId,
ProctoringServiceSettings.ATTR_COLLECTING_ROOM_SIZE, ProctoringServiceSettings.ATTR_COLLECTING_ROOM_SIZE,
String.valueOf(examProctoring.collectingRoomSize)); String.valueOf(proctoringServiceSettings.collectingRoomSize));
this.additionalAttributesDAO.saveAdditionalAttribute( this.additionalAttributesDAO.saveAdditionalAttribute(
EntityType.EXAM, EntityType.EXAM,
examId, examId,
ProctoringServiceSettings.ATTR_APP_KEY, ProctoringServiceSettings.ATTR_APP_KEY,
examProctoring.appKey); proctoringServiceSettings.appKey);
this.additionalAttributesDAO.saveAdditionalAttribute( this.additionalAttributesDAO.saveAdditionalAttribute(
EntityType.EXAM, EntityType.EXAM,
examId, examId,
ProctoringServiceSettings.ATTR_APP_SECRET, ProctoringServiceSettings.ATTR_APP_SECRET,
this.cryptor.encrypt(examProctoring.appSecret).toString()); this.cryptor.encrypt(proctoringServiceSettings.appSecret).toString());
return examProctoring; return proctoringServiceSettings;
}); });
} }

View file

@ -26,9 +26,9 @@ public interface ExamProctoringService {
/** Use this to test the proctoring service settings against the remote proctoring server. /** Use this to test the proctoring service settings against the remote proctoring server.
* *
* @param examProctoring the settings to test * @param proctoringSettings the settings to test
* @return Result refer to true if the settings are correct and the proctoring server can be accessed. */ * @return Result refer to true if the settings are correct and the proctoring server can be accessed. */
Result<Boolean> testExamProctoring(final ProctoringServiceSettings examProctoring); Result<Boolean> testExamProctoring(final ProctoringServiceSettings proctoringSettings);
/** Gets the room connection data for a certain room for the proctor. /** Gets the room connection data for a certain room for the proctor.
* *

View file

@ -24,14 +24,22 @@ import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
import ch.ethz.seb.sebserver.ClientHttpRequestFactoryService;
import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
import ch.ethz.seb.sebserver.gbl.api.APIMessage.APIMessageException;
import ch.ethz.seb.sebserver.gbl.api.APIMessage.FieldValidationException;
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.ProctoringRoomConnection;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings; import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType; import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringRoomConnection;
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData; import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction; import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction;
import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction.InstructionType; import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction.InstructionType;
@ -50,6 +58,10 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.session.SEBClientInstructio
@WebServiceProfile @WebServiceProfile
public class ExamJITSIProctoringService implements ExamProctoringService { public class ExamJITSIProctoringService implements ExamProctoringService {
private static final String SEB_SERVER_KEY = "seb-server";
private static final String SEB_CLIENT_KEY = "seb-client";
private static final Logger log = LoggerFactory.getLogger(ExamJITSIProctoringService.class); private static final Logger log = LoggerFactory.getLogger(ExamJITSIProctoringService.class);
private static final String JITSI_ACCESS_TOKEN_HEADER = private static final String JITSI_ACCESS_TOKEN_HEADER =
@ -63,19 +75,22 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
private final ExamSessionService examSessionService; private final ExamSessionService examSessionService;
private final SEBClientInstructionService sebClientInstructionService; private final SEBClientInstructionService sebClientInstructionService;
private final Cryptor cryptor; private final Cryptor cryptor;
private final ClientHttpRequestFactoryService clientHttpRequestFactoryService;
protected ExamJITSIProctoringService( protected ExamJITSIProctoringService(
final RemoteProctoringRoomDAO remoteProctoringRoomDAO, final RemoteProctoringRoomDAO remoteProctoringRoomDAO,
final AuthorizationService authorizationService, final AuthorizationService authorizationService,
final ExamSessionService examSessionService, final ExamSessionService examSessionService,
final SEBClientInstructionService sebClientInstructionService, final SEBClientInstructionService sebClientInstructionService,
final Cryptor cryptor) { final Cryptor cryptor,
final ClientHttpRequestFactoryService clientHttpRequestFactoryService) {
this.remoteProctoringRoomDAO = remoteProctoringRoomDAO; this.remoteProctoringRoomDAO = remoteProctoringRoomDAO;
this.authorizationService = authorizationService; this.authorizationService = authorizationService;
this.examSessionService = examSessionService; this.examSessionService = examSessionService;
this.sebClientInstructionService = sebClientInstructionService; this.sebClientInstructionService = sebClientInstructionService;
this.cryptor = cryptor; this.cryptor = cryptor;
this.clientHttpRequestFactoryService = clientHttpRequestFactoryService;
} }
@Override @Override
@ -84,9 +99,31 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
} }
@Override @Override
public Result<Boolean> testExamProctoring(final ProctoringServiceSettings examProctoring) { public Result<Boolean> testExamProctoring(final ProctoringServiceSettings proctoringSettings) {
// TODO Auto-generated method stub return Result.tryCatch(() -> {
return null; if (proctoringSettings.serverURL != null && proctoringSettings.serverURL.contains("?")) {
throw new FieldValidationException(
"serverURL",
"proctoringSettings:serverURL:invalidURL");
}
final ClientHttpRequestFactory clientHttpRequestFactory = this.clientHttpRequestFactoryService
.getClientHttpRequestFactory()
.getOrThrow();
try {
final RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
final ResponseEntity<String> result =
restTemplate.getForEntity(proctoringSettings.serverURL, String.class);
if (result.getStatusCode() != HttpStatus.OK) {
throw new APIMessageException(APIMessage.ErrorMessage.BINDING_ERROR);
}
} catch (final Exception e) {
throw new APIMessageException(APIMessage.ErrorMessage.BINDING_ERROR, e.getMessage());
}
return true;
});
} }
@Override @Override
@ -220,7 +257,7 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
proctoringSettings.appKey, proctoringSettings.appKey,
proctoringSettings.getAppSecret(), proctoringSettings.getAppSecret(),
this.authorizationService.getUserService().getCurrentUser().getUsername(), this.authorizationService.getUserService().getCurrentUser().getUsername(),
"seb-server", SEB_SERVER_KEY,
roomName, roomName,
subject, subject,
forExam(proctoringSettings), forExam(proctoringSettings),
@ -247,7 +284,7 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
proctoringSettings.appKey, proctoringSettings.appKey,
proctoringSettings.getAppSecret(), proctoringSettings.getAppSecret(),
clientConnection.clientConnection.userSessionId, clientConnection.clientConnection.userSessionId,
"seb-client", SEB_CLIENT_KEY,
roomName, roomName,
subject, subject,
forExam(proctoringSettings), forExam(proctoringSettings),
@ -276,7 +313,7 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
proctoringSettings.appKey, proctoringSettings.appKey,
proctoringSettings.getAppSecret(), proctoringSettings.getAppSecret(),
connectionData.clientConnection.userSessionId, connectionData.clientConnection.userSessionId,
"seb-client", SEB_CLIENT_KEY,
roomName, roomName,
subject, subject,
expTime, expTime,

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2021 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl;
import java.util.Collection;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringRoomConnection;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamProctoringService;
@Lazy
@Service
@WebServiceProfile
public class ExamZOOMProctoringService implements ExamProctoringService {
@Override
public ProctoringServerType getType() {
return ProctoringServerType.ZOOM;
}
@Override
public Result<Boolean> testExamProctoring(final ProctoringServiceSettings examProctoring) {
// TODO Auto-generated method stub
return null;
}
@Override
public Result<ProctoringRoomConnection> getProctorRoomConnection(
final ProctoringServiceSettings proctoringSettings,
final String roomName,
final String subject) {
// TODO Auto-generated method stub
return null;
}
@Override
public Result<ProctoringRoomConnection> sendJoinRoomToClients(
final ProctoringServiceSettings proctoringSettings,
final Collection<String> clientConnectionTokens,
final String roomName, final String subject) {
// TODO Auto-generated method stub
return null;
}
@Override
public Result<Void> sendJoinCollectingRoomToClients(
final ProctoringServiceSettings proctoringSettings,
final Collection<String> clientConnectionTokens) {
// TODO Auto-generated method stub
return null;
}
}

View file

@ -411,13 +411,16 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
required = true, required = true,
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId, defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
@PathVariable(API.PARAM_MODEL_ID) final Long examId, @PathVariable(API.PARAM_MODEL_ID) final Long examId,
@Valid @RequestBody final ProctoringServiceSettings examProctoring) { @Valid @RequestBody final ProctoringServiceSettings proctoringServiceSettings) {
checkModifyPrivilege(institutionId); checkModifyPrivilege(institutionId);
return this.entityDAO.byPK(examId) return this.entityDAO.byPK(examId)
.flatMap(this.authorization::checkModify) .flatMap(this.authorization::checkModify)
.map(exam -> { .map(exam -> {
this.examAdminService.saveProctoringServiceSettings(examId, examProctoring); this.examAdminService.getExamProctoringService(proctoringServiceSettings.serverType)
.flatMap(service -> service.testExamProctoring(proctoringServiceSettings))
.getOrThrow();
this.examAdminService.saveProctoringServiceSettings(examId, proctoringServiceSettings);
return exam; return exam;
}) })
.flatMap(this.userActivityLogDAO::logModify) .flatMap(this.userActivityLogDAO::logModify)

View file

@ -653,7 +653,10 @@ sebserver.exam.proctoring.form.secret=Secret
sebserver.exam.proctoring.form.secret.tooltip=The secret used to access the proctoring service sebserver.exam.proctoring.form.secret.tooltip=The secret used to access the proctoring service
sebserver.exam.proctoring.type.servertype.JITSI_MEET=Jitsi Meet Server sebserver.exam.proctoring.type.servertype.JITSI_MEET=Jitsi Meet Server
sebserver.exam.proctoring.type.servertype.JITSI_MEET.tooltip=Use a Jitsi Meet Server for proctoring sebserver.exam.proctoring.type.servertype.JITSI_MEET.tooltip=Use a Jitsi Meet server for proctoring
sebserver.exam.proctoring.type.servertype.ZOOM=Zoom Server
sebserver.exam.proctoring.type.servertype.ZOOM.tooltip=Use a Zoom meeting server for proctoring
################################ ################################
# Connection Configuration # Connection Configuration

View file

@ -17,8 +17,8 @@ import java.security.NoSuchAlgorithmException;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringRoomConnection; import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringRoomConnection;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.util.Cryptor; import ch.ethz.seb.sebserver.gbl.util.Cryptor;
public class ExamJITSIProctoringServiceTest { public class ExamJITSIProctoringServiceTest {
@ -28,7 +28,7 @@ public class ExamJITSIProctoringServiceTest {
final Cryptor cryptorMock = Mockito.mock(Cryptor.class); final Cryptor cryptorMock = Mockito.mock(Cryptor.class);
Mockito.when(cryptorMock.decrypt(Mockito.any())).thenReturn("fbvgeghergrgrthrehreg123"); Mockito.when(cryptorMock.decrypt(Mockito.any())).thenReturn("fbvgeghergrgrthrehreg123");
final ExamJITSIProctoringService examJITSIProctoringService = final ExamJITSIProctoringService examJITSIProctoringService =
new ExamJITSIProctoringService(null, null, null, null, cryptorMock); new ExamJITSIProctoringService(null, null, null, null, cryptorMock, null);
String accessToken = examJITSIProctoringService.createPayload( String accessToken = examJITSIProctoringService.createPayload(
"test-app", "test-app",
@ -62,7 +62,7 @@ public class ExamJITSIProctoringServiceTest {
final Cryptor cryptorMock = Mockito.mock(Cryptor.class); final Cryptor cryptorMock = Mockito.mock(Cryptor.class);
Mockito.when(cryptorMock.decrypt(Mockito.any())).thenReturn("fbvgeghergrgrthrehreg123"); Mockito.when(cryptorMock.decrypt(Mockito.any())).thenReturn("fbvgeghergrgrthrehreg123");
final ExamJITSIProctoringService examJITSIProctoringService = final ExamJITSIProctoringService examJITSIProctoringService =
new ExamJITSIProctoringService(null, null, null, null, cryptorMock); new ExamJITSIProctoringService(null, null, null, null, cryptorMock, null);
final ProctoringRoomConnection data = examJITSIProctoringService.createProctoringConnection( final ProctoringRoomConnection data = examJITSIProctoringService.createProctoringConnection(
ProctoringServerType.JITSI_MEET, ProctoringServerType.JITSI_MEET,
"connectionToken", "connectionToken",