SEBSERV-351 unit tests and fixes
This commit is contained in:
parent
2af314b135
commit
c2a22b68a5
5 changed files with 200 additions and 25 deletions
|
@ -79,7 +79,7 @@ public class OlatLmsAPITemplate extends AbstractCachedCourseAccess implements Lm
|
|||
|
||||
private OlatLmsRestTemplate cachedRestTemplate;
|
||||
|
||||
protected OlatLmsAPITemplate(
|
||||
public OlatLmsAPITemplate(
|
||||
final ClientHttpRequestFactoryService clientHttpRequestFactoryService,
|
||||
final ClientCredentialService clientCredentialService,
|
||||
final APITemplateDataSupplier apiTemplateDataSupplier,
|
||||
|
@ -344,8 +344,8 @@ public class OlatLmsAPITemplate extends AbstractCachedCourseAccess implements Lm
|
|||
final RestrictionDataPost post = new RestrictionDataPost();
|
||||
post.browserExamKeys = new ArrayList<>(restriction.browserExamKeys);
|
||||
post.configKeys = new ArrayList<>(restriction.configKeys);
|
||||
post.quitLink = restriction.getAdditionalProperties().getOrDefault(ADDITIONAL_ATTR_QUIT_LINK, null);
|
||||
post.quitSecret = restriction.getAdditionalProperties().getOrDefault(ADDITIONAL_ATTR_QUIT_SECRET, null);
|
||||
post.quitLink = this.getQuitLink(restriction.examId);
|
||||
post.quitSecret = this.getQuitSecret(restriction.examId);
|
||||
final RestrictionData r =
|
||||
this.apiPost(restTemplate, url, post, RestrictionDataPost.class, RestrictionData.class);
|
||||
return new SEBRestriction(Long.valueOf(id), r.configKeys, r.browserExamKeys, new HashMap<String, String>());
|
||||
|
@ -370,7 +370,6 @@ public class OlatLmsAPITemplate extends AbstractCachedCourseAccess implements Lm
|
|||
final Exam exam,
|
||||
final SEBRestriction sebRestrictionData) {
|
||||
|
||||
populateWithQuitLinkAndSecret(exam, sebRestrictionData);
|
||||
return getRestTemplate()
|
||||
.map(t -> this.setRestrictionForAssignmentId(t, exam.externalId, sebRestrictionData));
|
||||
}
|
||||
|
@ -403,8 +402,13 @@ public class OlatLmsAPITemplate extends AbstractCachedCourseAccess implements Lm
|
|||
return res.getBody();
|
||||
}
|
||||
|
||||
private <P, R> R apiPost(final RestTemplate restTemplate, final String url, final P post, final Class<P> postType,
|
||||
private <P, R> R apiPost(
|
||||
final RestTemplate restTemplate,
|
||||
final String url,
|
||||
final P post,
|
||||
final Class<P> postType,
|
||||
final Class<R> responseType) {
|
||||
|
||||
final LmsSetup lmsSetup = this.apiTemplateDataSupplier.getLmsSetup();
|
||||
final HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.set("content-type", "application/json");
|
||||
|
@ -459,36 +463,42 @@ public class OlatLmsAPITemplate extends AbstractCachedCourseAccess implements Lm
|
|||
});
|
||||
}
|
||||
|
||||
private void populateWithQuitLinkAndSecret(final Exam exam, final SEBRestriction sebRestrictionData) {
|
||||
private String getQuitSecret(final Long examId) {
|
||||
try {
|
||||
|
||||
final String quitLink = this.examConfigurationValueService.getMappedDefaultConfigAttributeValue(
|
||||
exam.id,
|
||||
CONFIG_ATTR_NAME_QUIT_LINK);
|
||||
|
||||
final String quitSecret = this.examConfigurationValueService.getMappedDefaultConfigAttributeValue(
|
||||
exam.id,
|
||||
final String quitSecretEncrypted = this.examConfigurationValueService.getMappedDefaultConfigAttributeValue(
|
||||
examId,
|
||||
CONFIG_ATTR_NAME_QUIT_SECRET);
|
||||
|
||||
if (StringUtils.isNotEmpty(quitLink)) {
|
||||
sebRestrictionData.additionalProperties.put(ADDITIONAL_ATTR_QUIT_LINK, quitLink);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(quitSecret)) {
|
||||
if (StringUtils.isNotEmpty(quitSecretEncrypted)) {
|
||||
try {
|
||||
final String decryptedSecret = this.cryptor
|
||||
.encrypt(quitSecret)
|
||||
|
||||
return this.cryptor
|
||||
.decrypt(quitSecretEncrypted)
|
||||
.getOrThrow()
|
||||
.toString();
|
||||
|
||||
sebRestrictionData.additionalProperties.put(ADDITIONAL_ATTR_QUIT_SECRET, decryptedSecret);
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to decrypt quitSecret: ", e);
|
||||
}
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to get SEB restriction with quit secret: ", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getQuitLink(final Long examId) {
|
||||
try {
|
||||
|
||||
return this.examConfigurationValueService.getMappedDefaultConfigAttributeValue(
|
||||
examId,
|
||||
CONFIG_ATTR_NAME_QUIT_LINK);
|
||||
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to populate SEB restriction with quit link and quit secret: ", e);
|
||||
log.error("Failed to get SEB restriction with quit link: ", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ public final class OlatLmsData {
|
|||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
static final class RestrictionData {
|
||||
public static final class RestrictionData {
|
||||
/*
|
||||
* OLAT API example:
|
||||
* {
|
||||
|
@ -74,7 +74,7 @@ public final class OlatLmsData {
|
|||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
static final class RestrictionDataPost {
|
||||
public static final class RestrictionDataPost {
|
||||
/*
|
||||
* OLAT API example:
|
||||
* {
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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.integration.api.admin;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.util.Cryptor;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamConfigurationValueService;
|
||||
|
||||
@Sql(scripts = { "classpath:schema-test.sql", "classpath:data-test.sql", "classpath:data-test-additional.sql" })
|
||||
public class ExamConfigurationValueServiceTest extends AdministrationAPIIntegrationTester {
|
||||
|
||||
@Autowired
|
||||
private ExamConfigurationValueService examConfigurationValueService;
|
||||
@Autowired
|
||||
private Cryptor cryptor;
|
||||
|
||||
@Test
|
||||
public void testGetConfigValues() {
|
||||
final String allowQuit = this.examConfigurationValueService
|
||||
.getMappedDefaultConfigAttributeValue(2L, "allowQuit");
|
||||
|
||||
assertNotNull(allowQuit);
|
||||
assertEquals("true", allowQuit);
|
||||
|
||||
final String hashedQuitPassword = this.examConfigurationValueService
|
||||
.getMappedDefaultConfigAttributeValue(2L, "hashedQuitPassword");
|
||||
|
||||
assertNotNull(hashedQuitPassword);
|
||||
assertEquals(
|
||||
"e6494b842987b4e039a101f14d4a76acc338d33205336f2562c7d8071e3ed65886edbbe3b71a4a33cc09c6",
|
||||
hashedQuitPassword);
|
||||
|
||||
final CharSequence plainQuitPassword = this.cryptor.decrypt(hashedQuitPassword).getOrThrow();
|
||||
assertEquals("123", plainQuitPassword);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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.integration.api.admin;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamStatus;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBRestriction;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Cryptor;
|
||||
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.olat.OlatLmsAPITemplate;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.olat.OlatLmsData.RestrictionDataPost;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.olat.OlatLmsRestTemplate;
|
||||
|
||||
@Sql(scripts = { "classpath:schema-test.sql", "classpath:data-test.sql", "classpath:data-test-additional.sql" })
|
||||
public class OlatLmsAPITemplateTest extends AdministrationAPIIntegrationTester {
|
||||
|
||||
@Autowired
|
||||
private ExamConfigurationValueService examConfigurationValueService;
|
||||
@Autowired
|
||||
private Cryptor cryptor;
|
||||
@Autowired
|
||||
private CacheManager cacheManager;
|
||||
|
||||
@Test
|
||||
public void testSetRestriction() throws Exception {
|
||||
|
||||
final OlatLmsRestTemplate restTemplateMock = Mockito.mock(OlatLmsRestTemplate.class);
|
||||
final APITemplateDataSupplier apiTemplateDataSupplier = Mockito.mock(APITemplateDataSupplier.class);
|
||||
Mockito.when(apiTemplateDataSupplier.getLmsSetup()).thenReturn(new LmsSetup(
|
||||
1L, 1L, null, null, null, null, null, null, null, null, null, null, false, null));
|
||||
|
||||
final OlatLmsAPITemplate olatLmsAPITemplate = new OlatLmsAPITemplate(
|
||||
null,
|
||||
null,
|
||||
apiTemplateDataSupplier,
|
||||
this.examConfigurationValueService,
|
||||
this.cryptor,
|
||||
this.cacheManager);
|
||||
|
||||
Mockito.when(restTemplateMock.exchange(Mockito.any(), Mockito.any(), Mockito.any(),
|
||||
(Class) Mockito.any(), (Object[]) Mockito.any())).then(new Answer() {
|
||||
|
||||
@Override
|
||||
public Object answer(final InvocationOnMock invocation) throws Throwable {
|
||||
final HttpEntity<RestrictionDataPost> argument2 = invocation.getArgument(2, HttpEntity.class);
|
||||
assertNotNull(argument2);
|
||||
final RestrictionDataPost body = argument2.getBody();
|
||||
assertNotNull(body);
|
||||
assertEquals("seb://quitlink.seb", body.quitLink);
|
||||
assertEquals("123", body.quitSecret);
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
final Field field = OlatLmsAPITemplate.class.getDeclaredField("cachedRestTemplate");
|
||||
field.setAccessible(true);
|
||||
field.set(olatLmsAPITemplate, restTemplateMock);
|
||||
|
||||
final Exam exam = new Exam(
|
||||
2L,
|
||||
1L,
|
||||
1L,
|
||||
Constants.EMPTY_NOTE,
|
||||
false,
|
||||
Constants.EMPTY_NOTE,
|
||||
null,
|
||||
null,
|
||||
ExamType.UNDEFINED,
|
||||
null,
|
||||
null,
|
||||
ExamStatus.FINISHED,
|
||||
Boolean.FALSE,
|
||||
null,
|
||||
Boolean.FALSE,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
|
||||
final SEBRestriction sebRestriction = new SEBRestriction(
|
||||
2L,
|
||||
Arrays.asList("configKey1", "configKey2"),
|
||||
Arrays.asList("browserKey1", "browserKey2"),
|
||||
null);
|
||||
|
||||
olatLmsAPITemplate.applySEBClientRestriction(exam, sebRestriction);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -539,7 +539,7 @@ INSERT IGNORE INTO configuration_value VALUES
|
|||
(1,1,1,1,0,NULL),
|
||||
(2,1,1,2,0,'true'),
|
||||
(3,1,1,3,0,'false'),
|
||||
(4,1,1,4,0,NULL),
|
||||
(4,1,1,4,0,'e6494b842987b4e039a101f14d4a76acc338d33205336f2562c7d8071e3ed65886edbbe3b71a4a33cc09c6'),
|
||||
(5,1,1,5,0,'2'),
|
||||
(6,1,1,6,0,'10'),
|
||||
(7,1,1,7,0,'5'),
|
||||
|
@ -602,7 +602,7 @@ INSERT IGNORE INTO configuration_value VALUES
|
|||
(64,1,1,64,0,'true'),
|
||||
(65,1,1,65,0,'true'),
|
||||
(66,1,1,66,0,'true'),
|
||||
(67,1,1,67,0,NULL),
|
||||
(67,1,1,67,0,'seb://quitlink.seb'),
|
||||
(68,1,1,68,0,'true'),
|
||||
(69,1,1,69,0,'false'),
|
||||
(70,1,1,70,0,NULL),
|
||||
|
|
Loading…
Reference in a new issue