SEBSERV-301 more tests

This commit is contained in:
anhefti 2023-01-12 13:01:13 +01:00
parent 76d0fdb64a
commit c03141c619
8 changed files with 290 additions and 32 deletions

View file

@ -261,7 +261,7 @@ public class ExamSEBRestrictionSettings {
.addField(FormBuilder.text(
SEBRestriction.ATTR_BROWSER_KEYS,
(lmsType == lmsType.MOODLE_PLUGIN)
(lmsType == LmsType.MOODLE_PLUGIN)
? SEB_RESTRICTION_FORM_MOODLE_BEK_KEY
: SEB_RESTRICTION_FORM_BROWSER_KEYS,
StringUtils.join(sebRestriction.getBrowserExamKeys(), Constants.CARRIAGE_RETURN))

View file

@ -113,6 +113,13 @@ public abstract class MoodleUtils {
}
}
public static void checkJSONFormat(final String userDetailsJSON) {
if (!userDetailsJSON.startsWith(String.valueOf(Constants.CURLY_BRACE_OPEN)) &&
!userDetailsJSON.startsWith(String.valueOf(Constants.SQUARE_BRACE_OPEN))) {
throw new RuntimeException("Illegal response format detected: " + userDetailsJSON);
}
}
private static final Pattern ACCESS_DENIED_PATTERN_1 =
Pattern.compile(Pattern.quote("No access rights"), Pattern.CASE_INSENSITIVE);
private static final Pattern ACCESS_DENIED_PATTERN_2 =

View file

@ -273,6 +273,8 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme
COURSES_API_FUNCTION_NAME,
attributes);
MoodleUtils.checkJSONFormat(courseJSON);
return this.jsonMapper.readValue(
courseJSON,
Courses.class).courses
@ -312,6 +314,8 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme
throw new RuntimeException("No user details on Moodle API request (access-denied)");
}
MoodleUtils.checkJSONFormat(userDetailsJSON);
final MoodleUserDetails[] userDetails = this.jsonMapper.<MoodleUserDetails[]> readValue(
userDetailsJSON,
new TypeReference<MoodleUserDetails[]>() {
@ -433,6 +437,8 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme
attributes))
.getOrThrow();
MoodleUtils.checkJSONFormat(courseKeyPageJSON);
final CoursesPlugin coursePage = this.jsonMapper.readValue(courseKeyPageJSON, CoursesPlugin.class);
if (coursePage == null) {
@ -525,6 +531,8 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme
COURSES_API_FUNCTION_NAME,
attributes);
MoodleUtils.checkJSONFormat(coursePageJSON);
final CoursesPlugin courses = this.jsonMapper.readValue(
coursePageJSON,
CoursesPlugin.class);

View file

@ -10,6 +10,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -120,7 +121,7 @@ public class MoodlePluginCourseRestriction implements SEBRestrictionAPI {
final Exam exam,
final SEBRestriction sebRestrictionData) {
return Result.tryCatch(() -> {
return getRestTemplate().map(restTemplate -> {
if (log.isDebugEnabled()) {
log.debug("Apply SEB Client restriction on exam: {}", exam);
@ -147,7 +148,7 @@ public class MoodlePluginCourseRestriction implements SEBRestrictionAPI {
queryAttributes.add(ATTRIBUTE_QUIT_URL, quitLink);
queryAttributes.add(ATTRIBUTE_QUIT_SECRET, quitSecret);
final String srJSON = this.restTemplate.callMoodleAPIFunction(
final String srJSON = restTemplate.callMoodleAPIFunction(
RESTRICTION_SET_FUNCTION_NAME,
addQuery,
queryAttributes);
@ -158,7 +159,7 @@ public class MoodlePluginCourseRestriction implements SEBRestrictionAPI {
@Override
public Result<Exam> releaseSEBClientRestriction(final Exam exam) {
return Result.tryCatch(() -> {
return getRestTemplate().map(restTemplate -> {
if (log.isDebugEnabled()) {
log.debug("Release SEB Client restriction on exam: {}", exam);
}
@ -174,7 +175,7 @@ public class MoodlePluginCourseRestriction implements SEBRestrictionAPI {
queryAttributes.add(ATTRIBUTE_QUIT_URL, quitLink);
queryAttributes.add(ATTRIBUTE_QUIT_SECRET, quitSecret);
this.restTemplate.callMoodleAPIFunction(
restTemplate.callMoodleAPIFunction(
RESTRICTION_SET_FUNCTION_NAME,
addQuery,
queryAttributes);
@ -185,6 +186,15 @@ public class MoodlePluginCourseRestriction implements SEBRestrictionAPI {
private SEBRestriction restrictionFromJson(final Exam exam, final String srJSON) {
try {
if (StringUtils.isBlank(srJSON)) {
return new SEBRestriction(
exam.id,
Collections.emptyList(),
Collections.emptyList(),
Collections.emptyMap());
}
// fist try to get from multiple data
final MoodleQuizRestrictions moodleRestrictions = this.jsonMapper.readValue(
srJSON,
@ -224,12 +234,16 @@ public class MoodlePluginCourseRestriction implements SEBRestrictionAPI {
final Exam exam,
final MoodleQuizRestriction moodleRestriction) {
final List<String> configKeys = Arrays.asList(StringUtils.split(
moodleRestriction.configkeys,
Constants.LIST_SEPARATOR));
final List<String> browserExamKeys = new ArrayList<>(Arrays.asList(StringUtils.split(
moodleRestriction.browserkeys,
Constants.LIST_SEPARATOR)));
final List<String> configKeys = StringUtils.isNoneBlank(moodleRestriction.configkeys)
? Arrays.asList(StringUtils.split(
moodleRestriction.configkeys,
Constants.LIST_SEPARATOR))
: Collections.emptyList();
final List<String> browserExamKeys = StringUtils.isNoneBlank(moodleRestriction.browserkeys)
? new ArrayList<>(Arrays.asList(StringUtils.split(
moodleRestriction.browserkeys,
Constants.LIST_SEPARATOR)))
: Collections.emptyList();
final Map<String, String> additionalProperties = new HashMap<>();
additionalProperties.put(ATTRIBUTE_QUIT_URL, moodleRestriction.quitlink);
additionalProperties.put(ATTRIBUTE_QUIT_SECRET, moodleRestriction.quitsecret);
@ -255,4 +269,12 @@ public class MoodlePluginCourseRestriction implements SEBRestrictionAPI {
return Result.of(this.restTemplate);
}
public String toTestString() {
final StringBuilder builder = new StringBuilder();
builder.append("MoodlePluginCourseRestriction [restTemplate=");
builder.append(this.restTemplate);
builder.append("]");
return builder.toString();
}
}

View file

@ -28,7 +28,6 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.lms.APITemplateDataSupplier
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate;
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplateFactory;
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.LmsAPITemplateAdapter;
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodlePluginCheck;
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestTemplateFactory;
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestTemplateFactoryImpl;
@ -37,7 +36,6 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestT
@WebServiceProfile
public class MooldePluginLmsAPITemplateFactory implements LmsAPITemplateFactory {
private final MoodlePluginCheck moodlePluginCheck;
private final JSONMapper jsonMapper;
private final CacheManager cacheManager;
private final AsyncService asyncService;
@ -48,7 +46,6 @@ public class MooldePluginLmsAPITemplateFactory implements LmsAPITemplateFactory
private final String[] alternativeTokenRequestPaths;
protected MooldePluginLmsAPITemplateFactory(
final MoodlePluginCheck moodlePluginCheck,
final JSONMapper jsonMapper,
final CacheManager cacheManager,
final AsyncService asyncService,
@ -58,7 +55,6 @@ public class MooldePluginLmsAPITemplateFactory implements LmsAPITemplateFactory
final ClientHttpRequestFactoryService clientHttpRequestFactoryService,
@Value("${sebserver.webservice.lms.moodle.api.token.request.paths:}") final String alternativeTokenRequestPaths) {
this.moodlePluginCheck = moodlePluginCheck;
this.jsonMapper = jsonMapper;
this.cacheManager = cacheManager;
this.asyncService = asyncService;
@ -87,10 +83,6 @@ public class MooldePluginLmsAPITemplateFactory implements LmsAPITemplateFactory
this.clientHttpRequestFactoryService,
this.alternativeTokenRequestPaths);
// if (!this.moodlePluginCheck.checkPluginAvailable(moodleRestTemplateFactory)) {
// throw new RuntimeException("Unable to detect SEB Server Moodle integration plugin!");
// }
final MoodlePluginCourseAccess moodlePluginCourseAccess = new MoodlePluginCourseAccess(
this.jsonMapper,
this.asyncService,
@ -109,7 +101,6 @@ public class MooldePluginLmsAPITemplateFactory implements LmsAPITemplateFactory
apiTemplateDataSupplier,
moodlePluginCourseAccess,
moodlePluginCourseRestriction);
});
}

View file

@ -19,6 +19,7 @@ import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Arrays;
import org.assertj.core.util.Lists;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
@ -36,6 +37,8 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.gbl.util.Utils;
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.APITemplateDataSupplier;
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleUtils.MoodleQuizRestriction;
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleUtils.MoodleQuizRestrictions;
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleUtils.MoodleUserDetails;
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin.MoodlePluginCourseAccess;
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin.MoodlePluginCourseRestriction;
@ -248,7 +251,6 @@ public class MoodleMockupRestTemplateFactory implements MoodleRestTemplateFactor
final List<String> ids = queryAttributes.get(MoodlePluginCourseAccess.PARAM_COURSE_ID);
final String from = queryAttributes.getFirst(MoodlePluginCourseAccess.PARAM_PAGE_START);
final String size = queryAttributes.getFirst(MoodlePluginCourseAccess.PARAM_PAGE_SIZE);
System.out.println("************* from: " + from);
final List<MockCD> courses;
if (ids != null && !ids.isEmpty()) {
courses = this.courses.stream().filter(c -> ids.contains(c.id)).collect(Collectors.toList());
@ -266,7 +268,6 @@ public class MoodleMockupRestTemplateFactory implements MoodleRestTemplateFactor
response.put("results", courses);
final JSONMapper jsonMapper = new JSONMapper();
final String result = jsonMapper.writeValueAsString(response);
System.out.println("******** courses response: " + result);
return result;
} catch (final JsonProcessingException e) {
e.printStackTrace();
@ -274,7 +275,7 @@ public class MoodleMockupRestTemplateFactory implements MoodleRestTemplateFactor
}
}
private final Map<String, MoodleQuizRestriction> restrcitions = new HashMap<>();
private final Map<String, MoodleQuizRestrictions> restrcitions = new HashMap<>();
private String respondSetRestriction(final String quizId, final MultiValueMap<String, String> queryAttributes) {
final List<String> configKeys = queryAttributes.get(MoodlePluginCourseRestriction.ATTRIBUTE_CONFIG_KEYS);
@ -288,26 +289,27 @@ public class MoodleMockupRestTemplateFactory implements MoodleRestTemplateFactor
StringUtils.join(beks, Constants.LIST_SEPARATOR),
quitURL,
quitSecret);
this.restrcitions.put(quizId, moodleQuizRestriction);
this.restrcitions.put(
quizId,
new MoodleQuizRestrictions(Lists.list(moodleQuizRestriction), null));
final JSONMapper jsonMapper = new JSONMapper();
try {
return jsonMapper.writeValueAsString(moodleQuizRestriction);
} catch (final JsonProcessingException e) {
e.printStackTrace();
return "";
throw new RuntimeException(e);
}
}
private String respondGetRestriction(final String quizId, final MultiValueMap<String, String> queryAttributes) {
final MoodleQuizRestriction moodleQuizRestriction = this.restrcitions.get(quizId);
final MoodleQuizRestrictions moodleQuizRestriction = this.restrcitions.get(quizId);
if (moodleQuizRestriction != null) {
final JSONMapper jsonMapper = new JSONMapper();
try {
return jsonMapper.writeValueAsString(moodleQuizRestriction);
} catch (final JsonProcessingException e) {
e.printStackTrace();
return "";
throw new RuntimeException(e);
}
}
return "";
@ -325,8 +327,28 @@ public class MoodleMockupRestTemplateFactory implements MoodleRestTemplateFactor
}
private String respondUsers(final MultiValueMap<String, String> queryAttributes) {
// TODO
return "";
final String id = queryAttributes.getFirst(MoodlePluginCourseAccess.ATTR_VALUE);
final String field = queryAttributes.getFirst(MoodlePluginCourseAccess.ATTR_FIELD);
if (!field.equals(MoodlePluginCourseAccess.ATTR_ID)) {
return "<error>";
}
if (id.contains("2")) {
final MoodleUserDetails moodleUserDetails = new MoodleUserDetails(
id, "testuser", "test", "user", "test user", "text@user.mail",
null, null, null, null, null, null, null, null, null, null, null, null);
final MoodleUserDetails[] array = new MoodleUserDetails[] { moodleUserDetails };
try {
final JSONMapper jsonMapper = new JSONMapper();
return jsonMapper.writeValueAsString(array);
} catch (final JsonProcessingException e) {
e.printStackTrace();
return "";
}
}
return "<error>";
}
}

View file

@ -33,6 +33,7 @@ import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
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.LmsSetupTestResult;
import ch.ethz.seb.sebserver.gbl.model.user.ExamineeAccountDetails;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.APITemplateDataSupplier;
@ -55,7 +56,6 @@ public class MoodlePluginCourseAccessTest {
final LmsSetupTestResult testCourseAccessAPI = candidate.testCourseAccessAPI();
assertTrue(testCourseAccessAPI.isOk());
assertEquals("MoodlePluginCourseAccess [pageSize=500, maxSize=10000, cutoffTimeOffset=3, "
+ "restTemplate=MockupMoodleRestTemplate [accessToken=MockupMoodleRestTemplate-Test-Token, url=https://test.org/, "
+ "testLog=[testAPIConnection functions: [quizaccess_sebserver_get_exams, core_user_get_users_by_field]], "
@ -237,6 +237,50 @@ public class MoodlePluginCourseAccessTest {
DateTimeUtils.setCurrentMillisSystem();
}
@Test
public void testGetKnownUserDetails() {
final MoodlePluginCourseAccess candidate = crateMockup();
final Result<ExamineeAccountDetails> userDetailsResult = candidate.getExamineeAccountDetails("2");
if (userDetailsResult.hasError()) {
userDetailsResult.getError().printStackTrace();
}
assertFalse(userDetailsResult.hasError());
final ExamineeAccountDetails examineeAccountDetails = userDetailsResult.get();
assertEquals(
"ExamineeAccountDetails [id=2, name=test user, username=testuser, email=text@user.mail, "
+ "additionalAttributes={mailformat=null, firstname=test, auth=null, timezone=null, description=null, firstaccess=null, confirmed=null, suspended=null, lastname=user, lastaccess=null, theme=null, descriptionformat=null, department=null, lang=null}]",
examineeAccountDetails.toString());
assertEquals(
"MoodlePluginCourseAccess [pageSize=500, maxSize=10000, cutoffTimeOffset=3, "
+ "restTemplate=MockupMoodleRestTemplate [accessToken=MockupMoodleRestTemplate-Test-Token, url=https://test.org/, "
+ "testLog=["
+ "callMoodleAPIFunction: core_user_get_users_by_field], "
+ "callLog=["
+ "<field=id&value=2,[Content-Type:\"application/x-www-form-urlencoded\"]>]]]",
candidate.toTestString());
}
@Test
public void testGetUnknownUserDetails() {
final MoodlePluginCourseAccess candidate = crateMockup();
final Result<ExamineeAccountDetails> userDetailsResult = candidate.getExamineeAccountDetails("1");
assertTrue(userDetailsResult.hasError());
assertEquals("Illegal response format detected: <error>", userDetailsResult.getError().getMessage());
assertEquals(
"MoodlePluginCourseAccess [pageSize=500, maxSize=10000, cutoffTimeOffset=3, "
+ "restTemplate=MockupMoodleRestTemplate [accessToken=MockupMoodleRestTemplate-Test-Token, url=https://test.org/, "
+ "testLog=[callMoodleAPIFunction: core_user_get_users_by_field], "
+ "callLog=[<field=id&value=1,[Content-Type:\"application/x-www-form-urlencoded\"]>]]]",
candidate.toTestString());
}
private MoodlePluginCourseAccess crateMockup() {
return crateMockup(Collections.emptyMap());
}

View file

@ -0,0 +1,164 @@
/*
* Copyright (c) 2023 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.lms.impl.moodle.plugin;
import static org.junit.Assert.*;
import java.util.Collections;
import org.assertj.core.util.Lists;
import org.junit.Test;
import org.mockito.Mockito;
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
import ch.ethz.seb.sebserver.gbl.client.ClientCredentials;
import ch.ethz.seb.sebserver.gbl.client.ProxyData;
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
import ch.ethz.seb.sebserver.gbl.model.exam.SEBRestriction;
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.LmsSetupTestResult;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamConfigurationValueService;
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.APITemplateDataSupplier;
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleMockupRestTemplateFactory;
public class MoodlePluginCourseRestrictionTest {
@Test
public void testSetup() {
final MoodlePluginCourseRestriction candidate = crateMockup();
assertEquals("MoodlePluginCourseRestriction [restTemplate=null]", candidate.toTestString());
final LmsSetupTestResult testCourseRestrictionAPI = candidate.testCourseRestrictionAPI();
assertTrue(testCourseRestrictionAPI.isOk());
assertEquals(
"MoodlePluginCourseRestriction [restTemplate=MockupMoodleRestTemplate [accessToken=MockupMoodleRestTemplate-Test-Token, url=https://test.org/, "
+ "testLog=[testAPIConnection functions: [quizaccess_sebserver_get_restriction, quizaccess_sebserver_set_restriction]], "
+ "callLog=[]]]",
candidate.toTestString());
}
@Test
public void getNoneExistingRestriction() {
final MoodlePluginCourseRestriction candidate = crateMockup();
final Exam exam = new Exam(1L, 1L, 1L, "101:1:c1:i1",
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
final Result<SEBRestriction> sebClientRestriction = candidate.getSEBClientRestriction(exam);
assertFalse(sebClientRestriction.hasError());
final SEBRestriction sebRestriction = sebClientRestriction.get();
assertEquals(
"SEBRestriction [examId=1, configKeys=[], browserExamKeys=[], additionalProperties={}]",
sebRestriction.toString());
}
@Test
public void getSetGetRestriction() {
final MoodlePluginCourseRestriction candidate = crateMockup();
final Exam exam = new Exam(1L, 1L, 1L, "101:1:c1:i1",
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
final SEBRestriction restriction = new SEBRestriction(
exam.id,
Lists.list("configKey1"),
Lists.list("BEK1", "BEK2"),
Collections.emptyMap());
assertFalse(candidate.hasSEBClientRestriction(exam));
final Result<SEBRestriction> applySEBClientRestriction = candidate.applySEBClientRestriction(
exam,
restriction);
assertFalse(applySEBClientRestriction.hasError());
SEBRestriction sebRestriction = applySEBClientRestriction.get();
assertEquals(
"SEBRestriction ["
+ "examId=1, "
+ "configKeys=[configKey1], "
+ "browserExamKeys=[BEK1, BEK2], "
+ "additionalProperties={quit_link=quitLink, quit_secret=quitSecret}]",
sebRestriction.toString());
Result<SEBRestriction> sebClientRestriction = candidate.getSEBClientRestriction(exam);
assertFalse(sebClientRestriction.hasError());
sebRestriction = sebClientRestriction.get();
assertEquals(
"SEBRestriction ["
+ "examId=1, "
+ "configKeys=[configKey1], "
+ "browserExamKeys=[BEK1, BEK2], "
+ "additionalProperties={quit_link=quitLink, quit_secret=quitSecret}]",
sebRestriction.toString());
assertTrue(candidate.hasSEBClientRestriction(exam));
candidate.releaseSEBClientRestriction(exam);
assertFalse(candidate.hasSEBClientRestriction(exam));
sebClientRestriction = candidate.getSEBClientRestriction(exam);
if (sebClientRestriction.hasError()) {
sebClientRestriction.getError().printStackTrace();
}
assertFalse(sebClientRestriction.hasError());
sebRestriction = sebClientRestriction.get();
assertEquals(
"SEBRestriction ["
+ "examId=1, "
+ "configKeys=[], "
+ "browserExamKeys=[], "
+ "additionalProperties={quit_link=quitLink, quit_secret=quitSecret}]",
sebRestriction.toString());
}
private MoodlePluginCourseRestriction crateMockup() {
final JSONMapper jsonMapper = new JSONMapper();
final LmsSetup lmsSetup =
new LmsSetup(1L, 1L, "test-Moodle", LmsType.MOODLE_PLUGIN, "lms-user", "lms-user-secret",
"https://test.org/", null, null, null, null, null, null, null);
final APITemplateDataSupplier apiTemplateDataSupplier = new APITemplateDataSupplier() {
@Override
public LmsSetup getLmsSetup() {
return lmsSetup;
}
@Override
public ClientCredentials getLmsClientCredentials() {
return new ClientCredentials("lms-user", "lms-user-secret");
}
@Override
public ProxyData getProxyData() {
return null;
}
};
final MoodleMockupRestTemplateFactory moodleMockupRestTemplateFactory =
new MoodleMockupRestTemplateFactory(apiTemplateDataSupplier);
final ExamConfigurationValueService examConfigurationValueService =
Mockito.mock(ExamConfigurationValueService.class);
Mockito.when(examConfigurationValueService.getQuitLink(Mockito.anyLong())).thenReturn("quitLink");
Mockito.when(examConfigurationValueService.getQuitSecret(Mockito.anyLong())).thenReturn("quitSecret");
return new MoodlePluginCourseRestriction(jsonMapper, moodleMockupRestTemplateFactory,
examConfigurationValueService);
}
}