From b94e44525766c45529b47c66546d59174dcbf0c7 Mon Sep 17 00:00:00 2001 From: anhefti Date: Mon, 10 Feb 2020 15:04:40 +0100 Subject: [PATCH] fix quit instruction, added default indicator, connection status filter --- .../session/ClientConnectionTable.java | 103 +++++++++----- .../servicelayer/exam/ExamAdminService.java | 29 ++++ .../exam/ExamAdminServiceImpl.java | 130 ++++++++++++++++++ .../moodle/MoodleRestTemplateFactory.java | 5 +- .../impl/SebInstructionServiceImpl.java | 20 +-- .../api/ExamAdministrationController.java | 40 ++---- .../api/ExamMonitoringController.java | 2 +- .../gbl/model/exam/IndicatorTest.java | 56 ++++++++ 8 files changed, 305 insertions(+), 80 deletions(-) create mode 100644 src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/ExamAdminService.java create mode 100644 src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/ExamAdminServiceImpl.java create mode 100644 src/test/java/ch/ethz/seb/sebserver/gbl/model/exam/IndicatorTest.java diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/session/ClientConnectionTable.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/session/ClientConnectionTable.java index 2c4123ef..5f264aae 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/session/ClientConnectionTable.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/session/ClientConnectionTable.java @@ -41,6 +41,7 @@ import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import ch.ethz.seb.sebserver.gbl.Constants; +import ch.ethz.seb.sebserver.gbl.api.API; import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.model.Domain; import ch.ethz.seb.sebserver.gbl.model.EntityKey; @@ -85,10 +86,13 @@ public final class ClientConnectionTable { private final Table table; private final ColorData colorData; private final EnumSet statusFilter; + private String statusFilterParam = ""; + private boolean statusFilterChanged = false; private int tableWidth; private boolean needsSort = false; private LinkedHashMap tableMapping; + private final Set toDelete = new HashSet<>(); private final MultiValueMap sessionIds; private final Color darkFontColor; @@ -180,39 +184,6 @@ public final class ClientConnectionTable { saveStatusFilter(); } - private void saveStatusFilter() { - try { - this.resourceService - .getCurrentUser() - .putAttribute( - USER_SESSION_STATUS_FILTER_ATTRIBUTE, - StringUtils.join(this.statusFilter, Constants.LIST_SEPARATOR)); - } catch (final Exception e) { - log.warn("Failed to save status filter to user session"); - } - } - - private void loadStatusFilter() { - try { - final String attribute = this.resourceService - .getCurrentUser() - .getAttribute(USER_SESSION_STATUS_FILTER_ATTRIBUTE); - if (attribute != null) { - this.statusFilter.clear(); - Arrays.asList(StringUtils.split(attribute, Constants.LIST_SEPARATOR)) - .forEach(name -> this.statusFilter.add(ConnectionStatus.valueOf(name))); - - } else { - this.statusFilter.clear(); - this.statusFilter.add(ConnectionStatus.DISABLED); - } - } catch (final Exception e) { - log.warn("Failed to load status filter to user session"); - this.statusFilter.clear(); - this.statusFilter.add(ConnectionStatus.DISABLED); - } - } - public void withDefaultAction(final PageAction pageAction, final PageService pageService) { this.table.addListener(SWT.MouseDoubleClick, event -> { final Tuple selection = getSingleSelection(); @@ -300,7 +271,12 @@ public final class ClientConnectionTable { } public void updateValues() { + if (this.statusFilterChanged) { + this.toDelete.clear(); + this.toDelete.addAll(this.tableMapping.keySet()); + } this.restCallBuilder + .withHeader(API.EXAM_MONITORING_STATE_FILTER, this.statusFilterParam) .call() .get(error -> { log.error("Error poll connection data: ", error); @@ -312,7 +288,21 @@ public final class ClientConnectionTable { data.getConnectionId(), connectionId -> new UpdatableTableItem(connectionId)); tableItem.push(data); + if (this.statusFilterChanged) { + this.toDelete.remove(data.getConnectionId()); + } }); + + if (this.statusFilterChanged && !this.toDelete.isEmpty()) { + this.toDelete.stream().forEach(id -> { + final UpdatableTableItem item = this.tableMapping.remove(id); + final List list = this.sessionIds.get(item.connectionData.clientConnection.userSessionId); + if (list != null) { + list.remove(id); + } + }); + this.statusFilterChanged = false; + } } public void updateGUI() { @@ -370,6 +360,45 @@ public final class ClientConnectionTable { (e1, e2) -> e1, LinkedHashMap::new)); } + private void saveStatusFilter() { + try { + this.resourceService + .getCurrentUser() + .putAttribute( + USER_SESSION_STATUS_FILTER_ATTRIBUTE, + StringUtils.join(this.statusFilter, Constants.LIST_SEPARATOR)); + } catch (final Exception e) { + log.warn("Failed to save status filter to user session"); + } finally { + this.statusFilterParam = StringUtils.join(this.statusFilter, Constants.LIST_SEPARATOR); + this.statusFilterChanged = true; + } + } + + private void loadStatusFilter() { + try { + final String attribute = this.resourceService + .getCurrentUser() + .getAttribute(USER_SESSION_STATUS_FILTER_ATTRIBUTE); + if (attribute != null) { + this.statusFilter.clear(); + Arrays.asList(StringUtils.split(attribute, Constants.LIST_SEPARATOR)) + .forEach(name -> this.statusFilter.add(ConnectionStatus.valueOf(name))); + + } else { + this.statusFilter.clear(); + this.statusFilter.add(ConnectionStatus.DISABLED); + } + } catch (final Exception e) { + log.warn("Failed to load status filter to user session"); + this.statusFilter.clear(); + this.statusFilter.add(ConnectionStatus.DISABLED); + } finally { + this.statusFilterParam = StringUtils.join(this.statusFilter, Constants.LIST_SEPARATOR); + this.statusFilterChanged = true; + } + } + private final class UpdatableTableItem implements Comparable { final Long connectionId; @@ -567,8 +596,12 @@ public final class ClientConnectionTable { this.connectionData = connectionData; - if (!this.duplicateChecked && StringUtils.isNotBlank(connectionData.clientConnection.userSessionId)) { - ClientConnectionTable.this.sessionIds.add(connectionData.clientConnection.userSessionId, + if (!this.duplicateChecked && + this.connectionData.clientConnection.status != ConnectionStatus.DISABLED && + StringUtils.isNotBlank(connectionData.clientConnection.userSessionId)) { + + ClientConnectionTable.this.sessionIds.add( + connectionData.clientConnection.userSessionId, this.connectionId); this.duplicateChecked = true; } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/ExamAdminService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/ExamAdminService.java new file mode 100644 index 00000000..0caf66cc --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/ExamAdminService.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020 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.exam; + +import ch.ethz.seb.sebserver.gbl.model.exam.Exam; +import ch.ethz.seb.sebserver.gbl.util.Result; + +public interface ExamAdminService { + + /** Adds a default indicator that is defined by configuration to a given exam. + * + * @param exam The Exam to add the default indicator + * @return the Exam with added default indicator */ + Result addDefaultIndicator(final Exam exam); + + /** Applies all additional SEB restriction attributes that are defined by the + * type of the LMS of a given Exam to this given Exam. + * + * @param exam the Exam to apply all additional SEB restriction attributes + * @return the Exam */ + Result applyAdditionalSEBRestrictions(final Exam exam); + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/ExamAdminServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/ExamAdminServiceImpl.java new file mode 100644 index 00000000..617b5947 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/ExamAdminServiceImpl.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2020 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.exam; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; + +import com.fasterxml.jackson.core.type.TypeReference; + +import ch.ethz.seb.sebserver.gbl.Constants; +import ch.ethz.seb.sebserver.gbl.api.EntityType; +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.Indicator; +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.institution.LmsSetup; +import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType; +import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; +import ch.ethz.seb.sebserver.gbl.util.Result; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.AdditionalAttributesDAO; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.IndicatorDAO; +import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService; +import ch.ethz.seb.sebserver.webservice.servicelayer.lms.SebRestrictionService; + +@Lazy +@Service +@WebServiceProfile +public class ExamAdminServiceImpl implements ExamAdminService { + + private final ExamDAO examDAO; + private final IndicatorDAO indicatorDAO; + private final AdditionalAttributesDAO additionalAttributesDAO; + private final LmsAPIService lmsAPIService; + private final JSONMapper jsonMapper; + + private final String defaultIndicatorName; + private final String defaultIndicatorType; + private final String defaultIndicatorColor; + private final String defaultIndicatorThresholds; + + protected ExamAdminServiceImpl( + final ExamDAO examDAO, + final IndicatorDAO indicatorDAO, + final AdditionalAttributesDAO additionalAttributesDAO, + final LmsAPIService lmsAPIService, + final JSONMapper jsonMapper, + @Value("${sebserver.webservice.api.exam.indicator.name:Ping}") final String defaultIndicatorName, + @Value("${sebserver.webservice.api.exam.indicator.type:LAST_PING}") final String defaultIndicatorType, + @Value("${sebserver.webservice.api.exam.indicator.color:b4b4b4}") final String defaultIndicatorColor, + @Value("${sebserver.webservice.api.exam.indicator.thresholds:[{\"value\":2000.0,\"color\":\"22b14c\"},{\"value\":5000.0,\"color\":\"ff7e00\"},{\"value\":10000.0,\"color\":\"ed1c24\"}]}") final String defaultIndicatorThresholds) { + + this.examDAO = examDAO; + this.indicatorDAO = indicatorDAO; + this.additionalAttributesDAO = additionalAttributesDAO; + this.lmsAPIService = lmsAPIService; + this.jsonMapper = jsonMapper; + + this.defaultIndicatorName = defaultIndicatorName; + this.defaultIndicatorType = defaultIndicatorType; + this.defaultIndicatorColor = defaultIndicatorColor; + this.defaultIndicatorThresholds = defaultIndicatorThresholds; + } + + @Override + public Result addDefaultIndicator(final Exam exam) { + return Result.tryCatch(() -> { + + final Collection thresholds = this.jsonMapper.readValue( + this.defaultIndicatorThresholds, + new TypeReference>() { + }); + + final Indicator indicator = new Indicator( + null, + exam.id, + this.defaultIndicatorName, + IndicatorType.valueOf(this.defaultIndicatorType), + this.defaultIndicatorColor, + thresholds); + + this.indicatorDAO.createNew(indicator) + .getOrThrow(); + + return this.examDAO + .byPK(exam.id) + .getOrThrow(); + }); + } + + @Override + public Result applyAdditionalSEBRestrictions(final Exam exam) { + return Result.tryCatch(() -> { + final LmsSetup lmsSetup = this.lmsAPIService.getLmsSetup(exam.lmsSetupId) + .getOrThrow(); + + if (lmsSetup.lmsType == LmsType.OPEN_EDX) { + final List permissions = Arrays.asList( + OpenEdxSebRestriction.PermissionComponent.ALWAYS_ALLOW_STUFF.key, + OpenEdxSebRestriction.PermissionComponent.CHECK_CONFIG_KEY.key); + + this.additionalAttributesDAO.saveAdditionalAttribute( + EntityType.EXAM, + exam.id, + SebRestrictionService.SEB_RESTRICTION_ADDITIONAL_PROPERTY_NAME_PREFIX + + OpenEdxSebRestriction.ATTR_PERMISSION_COMPONENTS, + StringUtils.join(permissions, Constants.LIST_SEPARATOR_CHAR)) + .getOrThrow(); + } + + return this.examDAO + .byPK(exam.id) + .getOrThrow(); + }); + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactory.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactory.java index a23d3728..134b9259 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactory.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactory.java @@ -28,6 +28,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; @@ -180,7 +181,7 @@ final class MoodleRestTemplateFactory { private CharSequence accessToken = null; private final Map tokenReqURIVars; - private final HttpEntity tokenReqEntity = new HttpEntity<>(null); + private final HttpEntity tokenReqEntity = new HttpEntity<>(new LinkedMultiValueMap<>()); protected MoodleAPIRestTemplate( @@ -272,7 +273,7 @@ final class MoodleRestTemplateFactory { functionReqEntity = new HttpEntity<>(body, headers); } else { - functionReqEntity = new HttpEntity<>(null); + functionReqEntity = new HttpEntity<>(new LinkedMultiValueMap<>()); } final ResponseEntity response = super.exchange( diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SebInstructionServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SebInstructionServiceImpl.java index 781fabf9..ec745514 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SebInstructionServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SebInstructionServiceImpl.java @@ -15,6 +15,7 @@ import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Lazy; @@ -133,20 +134,19 @@ public class SebInstructionServiceImpl implements SebInstructionService { .append(Constants.COLON) .append(Constants.DOUBLE_QUOTE) .append(clientInstruction.getType()) - .append(Constants.DOUBLE_QUOTE) - .append(Constants.COMMA) - .append(Constants.DOUBLE_QUOTE) - .append(JSON_ATTR) - .append(Constants.DOUBLE_QUOTE) - .append(Constants.COLON); - if (attributes == null || attributes.isEmpty()) { - sBuilder.append(Constants.NULL); + .append(Constants.DOUBLE_QUOTE); - } else { - sBuilder.append(Constants.CURLY_BRACE_OPEN) + if (StringUtils.isNotBlank(attributes)) { + sBuilder.append(Constants.COMMA) + .append(Constants.DOUBLE_QUOTE) + .append(JSON_ATTR) + .append(Constants.DOUBLE_QUOTE) + .append(Constants.COLON) + .append(Constants.CURLY_BRACE_OPEN) .append(attributes) .append(Constants.CURLY_BRACE_CLOSE); } + return sBuilder .append(Constants.CURLY_BRACE_CLOSE) .toString(); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java index 8dcfdbd9..ca412d5e 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java @@ -10,7 +10,6 @@ package ch.ethz.seb.sebserver.webservice.weblayer.api; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -37,7 +36,6 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.api.API; import ch.ethz.seb.sebserver.gbl.api.APIMessage; import ch.ethz.seb.sebserver.gbl.api.APIMessage.APIMessageException; @@ -49,12 +47,10 @@ import ch.ethz.seb.sebserver.gbl.model.Domain.EXAM; import ch.ethz.seb.sebserver.gbl.model.Page; import ch.ethz.seb.sebserver.gbl.model.PageSortOrder; import ch.ethz.seb.sebserver.gbl.model.exam.Exam; -import ch.ethz.seb.sebserver.gbl.model.exam.OpenEdxSebRestriction; import ch.ethz.seb.sebserver.gbl.model.exam.QuizData; 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.Features; -import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType; import ch.ethz.seb.sebserver.gbl.model.user.UserRole; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Result; @@ -64,11 +60,11 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.Authorization import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.UserService; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.impl.SEBServerUser; import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionService; -import ch.ethz.seb.sebserver.webservice.servicelayer.dao.AdditionalAttributesDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserDAO; +import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamAdminService; import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService; import ch.ethz.seb.sebserver.webservice.servicelayer.lms.SebRestrictionService; import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ExamConfigService; @@ -84,7 +80,7 @@ public class ExamAdministrationController extends EntityController { private final ExamDAO examDAO; private final UserDAO userDAO; - private final AdditionalAttributesDAO additionalAttributesDAO; + private final ExamAdminService examAdminService; private final LmsAPIService lmsAPIService; private final ExamConfigService sebExamConfigService; private final ExamSessionService examSessionService; @@ -99,10 +95,10 @@ public class ExamAdministrationController extends EntityController { final BeanValidationService beanValidationService, final LmsAPIService lmsAPIService, final UserDAO userDAO, + final ExamAdminService examAdminService, final ExamConfigService sebExamConfigService, final ExamSessionService examSessionService, - final SebRestrictionService sebRestrictionService, - final AdditionalAttributesDAO additionalAttributesDAO) { + final SebRestrictionService sebRestrictionService) { super(authorization, bulkActionService, @@ -113,7 +109,7 @@ public class ExamAdministrationController extends EntityController { this.examDAO = examDAO; this.userDAO = userDAO; - this.additionalAttributesDAO = additionalAttributesDAO; + this.examAdminService = examAdminService; this.lmsAPIService = lmsAPIService; this.sebExamConfigService = sebExamConfigService; this.examSessionService = examSessionService; @@ -337,29 +333,9 @@ public class ExamAdministrationController extends EntityController { @Override protected Result notifyCreated(final Exam entity) { - return Result.tryCatch(() -> { - - final LmsSetup lmsSetup = this.lmsAPIService.getLmsSetup(entity.lmsSetupId) - .getOrThrow(); - - // if we have an Open edX LMS involved, add additional initial SEB restriction attributes - if (lmsSetup.lmsType == LmsType.OPEN_EDX) { - final List permissions = Arrays.asList( - OpenEdxSebRestriction.PermissionComponent.ALWAYS_ALLOW_STUFF.key, - OpenEdxSebRestriction.PermissionComponent.CHECK_CONFIG_KEY.key); - - this.additionalAttributesDAO.saveAdditionalAttribute( - EntityType.EXAM, - entity.id, - SebRestrictionService.SEB_RESTRICTION_ADDITIONAL_PROPERTY_NAME_PREFIX + - OpenEdxSebRestriction.ATTR_PERMISSION_COMPONENTS, - StringUtils.join(permissions, Constants.LIST_SEPARATOR_CHAR)) - .getOrThrow(); - - } - - return entity; - }); + return this.examAdminService + .addDefaultIndicator(entity) + .flatMap(this.examAdminService::applyAdditionalSEBRestrictions); } @Override diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamMonitoringController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamMonitoringController.java index 92e1d403..ac245f78 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamMonitoringController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamMonitoringController.java @@ -187,7 +187,7 @@ public class ExamMonitoringController { examId, filterStates.isEmpty() ? Objects::nonNull - : conn -> conn != null && filterStates.contains(conn.clientConnection.status)) + : conn -> conn != null && !filterStates.contains(conn.clientConnection.status)) .getOrThrow(); } diff --git a/src/test/java/ch/ethz/seb/sebserver/gbl/model/exam/IndicatorTest.java b/src/test/java/ch/ethz/seb/sebserver/gbl/model/exam/IndicatorTest.java new file mode 100644 index 00000000..9efc5639 --- /dev/null +++ b/src/test/java/ch/ethz/seb/sebserver/gbl/model/exam/IndicatorTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2020 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.gbl.model.exam; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; + +import org.junit.Test; + +import com.fasterxml.jackson.core.type.TypeReference; + +import ch.ethz.seb.sebserver.gbl.api.JSONMapper; +import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.IndicatorType; +import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.Threshold; + +public class IndicatorTest { + + @Test + public void testDefault() throws IOException { + final Indicator indicator = new Indicator( + null, + 1L, + "Ping", + IndicatorType.LAST_PING, + "b4b4b4", + Arrays.asList( + new Indicator.Threshold(2000d, "22b14c"), + new Indicator.Threshold(5000d, "ff7e00"), + new Indicator.Threshold(10000d, "ed1c24"))); + + final JSONMapper mapper = new JSONMapper(); + final String jsonString = mapper.writeValueAsString(indicator); + assertEquals( + "{\"examId\":1,\"name\":\"Ping\",\"type\":\"LAST_PING\",\"color\":\"b4b4b4\",\"thresholds\":[{\"value\":2000.0,\"color\":\"22b14c\"},{\"value\":5000.0,\"color\":\"ff7e00\"}", + jsonString); + + final String threholds = + "[{\"value\":2000.0,\"color\":\"22b14c\"},{\"value\":5000.0,\"color\":\"ff7e00\"},{\"value\":10000.0,\"color\":\"ed1c24\"}]"; + final Collection values = mapper.readValue(threholds, new TypeReference>() { + }); + + assertEquals( + "[Threshold [value=2000.0, color=22b14c], Threshold [value=5000.0, color=ff7e00], Threshold [value=10000.0, color=ed1c24]]", + values.toString()); + } + +}