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; |     private OlatLmsRestTemplate cachedRestTemplate; | ||||||
| 
 | 
 | ||||||
|     protected OlatLmsAPITemplate( |     public OlatLmsAPITemplate( | ||||||
|             final ClientHttpRequestFactoryService clientHttpRequestFactoryService, |             final ClientHttpRequestFactoryService clientHttpRequestFactoryService, | ||||||
|             final ClientCredentialService clientCredentialService, |             final ClientCredentialService clientCredentialService, | ||||||
|             final APITemplateDataSupplier apiTemplateDataSupplier, |             final APITemplateDataSupplier apiTemplateDataSupplier, | ||||||
|  | @ -344,8 +344,8 @@ public class OlatLmsAPITemplate extends AbstractCachedCourseAccess implements Lm | ||||||
|         final RestrictionDataPost post = new RestrictionDataPost(); |         final RestrictionDataPost post = new RestrictionDataPost(); | ||||||
|         post.browserExamKeys = new ArrayList<>(restriction.browserExamKeys); |         post.browserExamKeys = new ArrayList<>(restriction.browserExamKeys); | ||||||
|         post.configKeys = new ArrayList<>(restriction.configKeys); |         post.configKeys = new ArrayList<>(restriction.configKeys); | ||||||
|         post.quitLink = restriction.getAdditionalProperties().getOrDefault(ADDITIONAL_ATTR_QUIT_LINK, null); |         post.quitLink = this.getQuitLink(restriction.examId); | ||||||
|         post.quitSecret = restriction.getAdditionalProperties().getOrDefault(ADDITIONAL_ATTR_QUIT_SECRET, null); |         post.quitSecret = this.getQuitSecret(restriction.examId); | ||||||
|         final RestrictionData r = |         final RestrictionData r = | ||||||
|                 this.apiPost(restTemplate, url, post, RestrictionDataPost.class, RestrictionData.class); |                 this.apiPost(restTemplate, url, post, RestrictionDataPost.class, RestrictionData.class); | ||||||
|         return new SEBRestriction(Long.valueOf(id), r.configKeys, r.browserExamKeys, new HashMap<String, String>()); |         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 Exam exam, | ||||||
|             final SEBRestriction sebRestrictionData) { |             final SEBRestriction sebRestrictionData) { | ||||||
| 
 | 
 | ||||||
|         populateWithQuitLinkAndSecret(exam, sebRestrictionData); |  | ||||||
|         return getRestTemplate() |         return getRestTemplate() | ||||||
|                 .map(t -> this.setRestrictionForAssignmentId(t, exam.externalId, sebRestrictionData)); |                 .map(t -> this.setRestrictionForAssignmentId(t, exam.externalId, sebRestrictionData)); | ||||||
|     } |     } | ||||||
|  | @ -403,8 +402,13 @@ public class OlatLmsAPITemplate extends AbstractCachedCourseAccess implements Lm | ||||||
|         return res.getBody(); |         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 Class<R> responseType) { | ||||||
|  | 
 | ||||||
|         final LmsSetup lmsSetup = this.apiTemplateDataSupplier.getLmsSetup(); |         final LmsSetup lmsSetup = this.apiTemplateDataSupplier.getLmsSetup(); | ||||||
|         final HttpHeaders httpHeaders = new HttpHeaders(); |         final HttpHeaders httpHeaders = new HttpHeaders(); | ||||||
|         httpHeaders.set("content-type", "application/json"); |         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 { |         try { | ||||||
| 
 | 
 | ||||||
|             final String quitLink = this.examConfigurationValueService.getMappedDefaultConfigAttributeValue( |             final String quitSecretEncrypted = this.examConfigurationValueService.getMappedDefaultConfigAttributeValue( | ||||||
|                     exam.id, |                     examId, | ||||||
|                     CONFIG_ATTR_NAME_QUIT_LINK); |  | ||||||
| 
 |  | ||||||
|             final String quitSecret = this.examConfigurationValueService.getMappedDefaultConfigAttributeValue( |  | ||||||
|                     exam.id, |  | ||||||
|                     CONFIG_ATTR_NAME_QUIT_SECRET); |                     CONFIG_ATTR_NAME_QUIT_SECRET); | ||||||
| 
 | 
 | ||||||
|             if (StringUtils.isNotEmpty(quitLink)) { |             if (StringUtils.isNotEmpty(quitSecretEncrypted)) { | ||||||
|                 sebRestrictionData.additionalProperties.put(ADDITIONAL_ATTR_QUIT_LINK, quitLink); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if (StringUtils.isNotEmpty(quitSecret)) { |  | ||||||
|                 try { |                 try { | ||||||
|                     final String decryptedSecret = this.cryptor | 
 | ||||||
|                             .encrypt(quitSecret) |                     return this.cryptor | ||||||
|  |                             .decrypt(quitSecretEncrypted) | ||||||
|                             .getOrThrow() |                             .getOrThrow() | ||||||
|                             .toString(); |                             .toString(); | ||||||
| 
 | 
 | ||||||
|                     sebRestrictionData.additionalProperties.put(ADDITIONAL_ATTR_QUIT_SECRET, decryptedSecret); |  | ||||||
|                 } catch (final Exception e) { |                 } catch (final Exception e) { | ||||||
|                     log.error("Failed to decrypt quitSecret: ", 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) { |         } 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) |     @JsonIgnoreProperties(ignoreUnknown = true) | ||||||
|     static final class RestrictionData { |     public static final class RestrictionData { | ||||||
|         /* |         /* | ||||||
|          * OLAT API example: |          * OLAT API example: | ||||||
|          * { |          * { | ||||||
|  | @ -74,7 +74,7 @@ public final class OlatLmsData { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @JsonIgnoreProperties(ignoreUnknown = true) |     @JsonIgnoreProperties(ignoreUnknown = true) | ||||||
|     static final class RestrictionDataPost { |     public static final class RestrictionDataPost { | ||||||
|         /* |         /* | ||||||
|          * OLAT API example: |          * 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), |     (1,1,1,1,0,NULL), | ||||||
|     (2,1,1,2,0,'true'), |     (2,1,1,2,0,'true'), | ||||||
|     (3,1,1,3,0,'false'), |     (3,1,1,3,0,'false'), | ||||||
|     (4,1,1,4,0,NULL), |     (4,1,1,4,0,'e6494b842987b4e039a101f14d4a76acc338d33205336f2562c7d8071e3ed65886edbbe3b71a4a33cc09c6'), | ||||||
|     (5,1,1,5,0,'2'), |     (5,1,1,5,0,'2'), | ||||||
|     (6,1,1,6,0,'10'), |     (6,1,1,6,0,'10'), | ||||||
|     (7,1,1,7,0,'5'), |     (7,1,1,7,0,'5'), | ||||||
|  | @ -602,7 +602,7 @@ INSERT IGNORE INTO configuration_value VALUES | ||||||
|     (64,1,1,64,0,'true'), |     (64,1,1,64,0,'true'), | ||||||
|     (65,1,1,65,0,'true'), |     (65,1,1,65,0,'true'), | ||||||
|     (66,1,1,66,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'), |     (68,1,1,68,0,'true'), | ||||||
|     (69,1,1,69,0,'false'), |     (69,1,1,69,0,'false'), | ||||||
|     (70,1,1,70,0,NULL), |     (70,1,1,70,0,NULL), | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 anhefti
						anhefti