From 3fc4f714494cc2d987cd0fd7de19730b8c85a057 Mon Sep 17 00:00:00 2001 From: uhensler <urs.hensler@frentix.com> Date: Wed, 23 Oct 2019 09:15:52 +0200 Subject: [PATCH] OO-4207: Structure nodes are done if all mandatory children are done Evaluation of the obligation of the structure node --- .../manager/CourseAssessmentManagerImpl.java | 1 + .../evaluation/ConfigObligationEvaluator.java | 11 ++- .../DefaultLinearStatusEvaluator.java | 14 +++- .../MandatoryObligationEvaluator.java | 53 ++++++++++++ .../st/assessment/STAssessmentHandler.java | 7 +- .../assessment/STLinearStatusEvaluator.java | 34 +++++++- .../st/assessment/ScoreStatusEvaluator.java | 2 +- .../scoring/AccountingEvaluatorsFactory.java | 10 ++- .../run/scoring/AssessmentAccounting.java | 20 +++-- .../run/scoring/ObligationEvaluator.java | 6 +- .../course/run/scoring/StatusEvaluator.java | 2 +- .../DefaultLinearStatusEvaluatorTest.java | 21 +++-- .../MandatoryObligationEvaluatorTest.java | 82 +++++++++++++++++++ .../STLinearStatusEvaluatorTest.java | 55 ++++++++++--- .../java/org/olat/test/AllTestsJunit4.java | 1 + 15 files changed, 278 insertions(+), 41 deletions(-) create mode 100644 src/main/java/org/olat/course/nodes/st/assessment/MandatoryObligationEvaluator.java create mode 100644 src/test/java/org/olat/course/nodes/st/assessment/MandatoryObligationEvaluatorTest.java diff --git a/src/main/java/org/olat/course/assessment/manager/CourseAssessmentManagerImpl.java b/src/main/java/org/olat/course/assessment/manager/CourseAssessmentManagerImpl.java index a56fbf8817d..68e5b2c83ec 100644 --- a/src/main/java/org/olat/course/assessment/manager/CourseAssessmentManagerImpl.java +++ b/src/main/java/org/olat/course/assessment/manager/CourseAssessmentManagerImpl.java @@ -139,6 +139,7 @@ public class CourseAssessmentManagerImpl implements AssessmentManager { @Override public List<AssessmentEntry> getAssessmentEntries(Identity assessedIdentity) { + log.debug("Load assessment entries of {}", assessedIdentity); return assessmentService.loadAssessmentEntriesByAssessedIdentity(assessedIdentity, cgm.getCourseEntry()); } diff --git a/src/main/java/org/olat/course/learningpath/evaluation/ConfigObligationEvaluator.java b/src/main/java/org/olat/course/learningpath/evaluation/ConfigObligationEvaluator.java index 11cd7dfc3bf..051129d6650 100644 --- a/src/main/java/org/olat/course/learningpath/evaluation/ConfigObligationEvaluator.java +++ b/src/main/java/org/olat/course/learningpath/evaluation/ConfigObligationEvaluator.java @@ -19,9 +19,12 @@ */ package org.olat.course.learningpath.evaluation; +import java.util.List; + import org.olat.core.CoreSpringFactory; import org.olat.course.learningpath.LearningPathService; import org.olat.course.nodes.CourseNode; +import org.olat.course.run.scoring.AssessmentEvaluation; import org.olat.course.run.scoring.ObligationEvaluator; import org.olat.modules.assessment.model.AssessmentObligation; @@ -34,9 +37,15 @@ import org.olat.modules.assessment.model.AssessmentObligation; public class ConfigObligationEvaluator implements ObligationEvaluator { @Override - public AssessmentObligation getObligation(CourseNode courseNode) { + public AssessmentObligation getObligation(AssessmentEvaluation currentEvaluation, CourseNode courseNode) { LearningPathService learningPathService = CoreSpringFactory.getImpl(LearningPathService.class); return learningPathService.getConfigs(courseNode).getObligation(); } + @Override + public AssessmentObligation getObligation(AssessmentEvaluation currentEvaluation, + List<AssessmentEvaluation> children) { + return currentEvaluation.getObligation(); + } + } diff --git a/src/main/java/org/olat/course/learningpath/evaluation/DefaultLinearStatusEvaluator.java b/src/main/java/org/olat/course/learningpath/evaluation/DefaultLinearStatusEvaluator.java index 09b15b21e43..e6925ce4a6a 100644 --- a/src/main/java/org/olat/course/learningpath/evaluation/DefaultLinearStatusEvaluator.java +++ b/src/main/java/org/olat/course/learningpath/evaluation/DefaultLinearStatusEvaluator.java @@ -39,11 +39,12 @@ public class DefaultLinearStatusEvaluator implements StatusEvaluator { private static final Logger log = Tracing.createLoggerFor(DefaultLinearStatusEvaluator.class); @Override - public AssessmentEntryStatus getStatus(AssessmentEvaluation previousEvaluation, AssessmentEvaluation currentEvaluation) { + public AssessmentEntryStatus getStatus(AssessmentEvaluation previousEvaluation, + AssessmentEvaluation currentEvaluation, boolean firstChild) { AssessmentEntryStatus currentStatus = currentEvaluation.getAssessmentStatus(); AssessmentEntryStatus status = currentStatus; if (isNotReadyYet(currentStatus)) { - if (isAccessible(previousEvaluation)) { + if (isAccessible(previousEvaluation, firstChild)) { status = AssessmentEntryStatus.notStarted; } else { status = AssessmentEntryStatus.notReady; @@ -67,10 +68,11 @@ public class DefaultLinearStatusEvaluator implements StatusEvaluator { return currentStatus == null || AssessmentEntryStatus.notReady.equals(currentStatus); } - private boolean isAccessible(AssessmentEvaluation assessmentEvaluation) { + private boolean isAccessible(AssessmentEvaluation assessmentEvaluation, boolean firstChild) { return isRoot(assessmentEvaluation) || isFullyAssessed(assessmentEvaluation) - || isOptionalAndReady(assessmentEvaluation); + || isOptionalAndReady(assessmentEvaluation) + || isFirstChildAndNotStarted(assessmentEvaluation, firstChild); } private boolean isRoot(AssessmentEvaluation assessmentEvaluation) { @@ -86,6 +88,10 @@ public class DefaultLinearStatusEvaluator implements StatusEvaluator { && !AssessmentEntryStatus.notReady.equals(assessmentEvaluation.getAssessmentStatus()); } + private boolean isFirstChildAndNotStarted(AssessmentEvaluation assessmentEvaluation, boolean firstChild) { + return firstChild && AssessmentEntryStatus.notStarted.equals(assessmentEvaluation.getAssessmentStatus()); + } + @Override public AssessmentEntryStatus getStatus(AssessmentEvaluation currentEvaluation, List<AssessmentEvaluation> children) { diff --git a/src/main/java/org/olat/course/nodes/st/assessment/MandatoryObligationEvaluator.java b/src/main/java/org/olat/course/nodes/st/assessment/MandatoryObligationEvaluator.java new file mode 100644 index 00000000000..db1a2b48d21 --- /dev/null +++ b/src/main/java/org/olat/course/nodes/st/assessment/MandatoryObligationEvaluator.java @@ -0,0 +1,53 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.course.nodes.st.assessment; + +import java.util.List; + +import org.olat.course.nodes.CourseNode; +import org.olat.course.run.scoring.AssessmentEvaluation; +import org.olat.course.run.scoring.ObligationEvaluator; +import org.olat.modules.assessment.model.AssessmentObligation; + +/** + * + * Initial date: 23 Oct 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public class MandatoryObligationEvaluator implements ObligationEvaluator { + + @Override + public AssessmentObligation getObligation(AssessmentEvaluation currentEvaluation, CourseNode courseNode) { + return currentEvaluation.getObligation(); + } + + @Override + public AssessmentObligation getObligation(AssessmentEvaluation currentEvaluation, + List<AssessmentEvaluation> children) { + for (AssessmentEvaluation child : children) { + if (AssessmentObligation.mandatory.equals(child.getObligation())) { + return AssessmentObligation.mandatory; + } + } + return AssessmentObligation.optional; + } + +} diff --git a/src/main/java/org/olat/course/nodes/st/assessment/STAssessmentHandler.java b/src/main/java/org/olat/course/nodes/st/assessment/STAssessmentHandler.java index 74dade79b6d..bad65e678a1 100644 --- a/src/main/java/org/olat/course/nodes/st/assessment/STAssessmentHandler.java +++ b/src/main/java/org/olat/course/nodes/st/assessment/STAssessmentHandler.java @@ -47,6 +47,7 @@ import org.olat.course.run.scoring.AverageCompletionEvaluator; import org.olat.course.run.scoring.CompletionEvaluator; import org.olat.course.run.scoring.FullyAssessedEvaluator; import org.olat.course.run.scoring.LastModificationsEvaluator; +import org.olat.course.run.scoring.ObligationEvaluator; import org.olat.course.run.scoring.PassedEvaluator; import org.olat.course.run.scoring.ScoreCalculator; import org.olat.course.run.scoring.ScoreEvaluator; @@ -68,11 +69,12 @@ import org.springframework.stereotype.Service; @Service public class STAssessmentHandler implements AssessmentHandler { + private static final ObligationEvaluator MANDATORY_OBLIGATION_EVALUATOR = new MandatoryObligationEvaluator(); private static final CumulatingDurationEvaluator CUMULATION_DURATION_EVALUATOR = new CumulatingDurationEvaluator(); private static final ScoreEvaluator CONDITION_SCORE_EVALUATOR = new ConditionScoreEvaluator(); private static final PassedEvaluator CONDITION_PASSED_EVALUATOR = new ConditionPassedEvaluator(); private static final StatusEvaluator SCORE_STATUS_EVALUATOR = new ScoreStatusEvaluator(); - private static final StatusEvaluator STATUS_LEARNING_PATH_STATUS_EVALUATOR = new STLinearStatusEvaluator(); + private static final StatusEvaluator LEARNING_PATH_STATUS_EVALUATOR = new STLinearStatusEvaluator(); private static final FullyAssessedEvaluator FULLY_ASSESSED_EVALUATOR = new STFullyAssessedEvaluator(); private static final LastModificationsEvaluator LAST_MODIFICATION_EVALUATOR = new STLastModificationsEvaluator(); private static final AccountingEvaluators CONVENTIONAL_EVALUATORS = AccountingEvaluatorsBuilder.builder() @@ -107,10 +109,11 @@ public class STAssessmentHandler implements AssessmentHandler { public AccountingEvaluators getEvaluators(CourseNode courseNode, CourseConfig courseConfig) { if (LearningPathNodeAccessProvider.TYPE.equals(courseConfig.getNodeAccessType().getType())) { AccountingEvaluatorsBuilder builder = AccountingEvaluatorsBuilder.builder() + .withObligationEvaluator(MANDATORY_OBLIGATION_EVALUATOR) .withDurationEvaluator(CUMULATION_DURATION_EVALUATOR) .withScoreEvaluator(CONDITION_SCORE_EVALUATOR) .withPassedEvaluator(CONDITION_PASSED_EVALUATOR) - .withStatusEvaluator(STATUS_LEARNING_PATH_STATUS_EVALUATOR) + .withStatusEvaluator(LEARNING_PATH_STATUS_EVALUATOR) .withFullyAssessedEvaluator(FULLY_ASSESSED_EVALUATOR) .withLastModificationsEvaluator(LAST_MODIFICATION_EVALUATOR); CompletionEvaluator completionEvaluator = CompletionType.duration.equals(courseConfig.getCompletionType()) diff --git a/src/main/java/org/olat/course/nodes/st/assessment/STLinearStatusEvaluator.java b/src/main/java/org/olat/course/nodes/st/assessment/STLinearStatusEvaluator.java index 93a8dc550e7..dbbb765c1f6 100644 --- a/src/main/java/org/olat/course/nodes/st/assessment/STLinearStatusEvaluator.java +++ b/src/main/java/org/olat/course/nodes/st/assessment/STLinearStatusEvaluator.java @@ -25,6 +25,7 @@ import org.olat.course.learningpath.evaluation.DefaultLinearStatusEvaluator; import org.olat.course.run.scoring.AssessmentEvaluation; import org.olat.course.run.scoring.StatusEvaluator; import org.olat.modules.assessment.model.AssessmentEntryStatus; +import org.olat.modules.assessment.model.AssessmentObligation; /** * @@ -38,25 +39,50 @@ public class STLinearStatusEvaluator implements StatusEvaluator { @Override public AssessmentEntryStatus getStatus(AssessmentEvaluation previousEvaluation, - AssessmentEvaluation currentEvaluation) { - return defaultEvaluator.getStatus(previousEvaluation, currentEvaluation); + AssessmentEvaluation currentEvaluation, boolean firstChild) { + return defaultEvaluator.getStatus(previousEvaluation, currentEvaluation, firstChild); } @Override public AssessmentEntryStatus getStatus(AssessmentEvaluation currentEvaluation, List<AssessmentEvaluation> children) { + boolean notStarted = false; + boolean inProgress = false; + boolean done = true; for (AssessmentEvaluation child : children) { + if (isNotStarted(child)) { + notStarted = true; + } if (isInProgess(child)) { - return AssessmentEntryStatus.inProgress; + inProgress = true; + } + if (isMandatory(child) && isNotDone(child)) { + done = false; } } - return currentEvaluation.getAssessmentStatus(); + + if (done) return AssessmentEntryStatus.done; + if (inProgress) return AssessmentEntryStatus.inProgress; + if (notStarted) return AssessmentEntryStatus.notStarted; + return currentEvaluation.getAssessmentStatus(); } + private boolean isNotStarted(AssessmentEvaluation assessmentEvaluation) { + return isInProgess(assessmentEvaluation) + || AssessmentEntryStatus.notStarted.equals(assessmentEvaluation.getAssessmentStatus()); + } + private boolean isInProgess(AssessmentEvaluation assessmentEvaluation) { return AssessmentEntryStatus.inProgress.equals(assessmentEvaluation.getAssessmentStatus()) || AssessmentEntryStatus.inReview.equals(assessmentEvaluation.getAssessmentStatus()) || AssessmentEntryStatus.done.equals(assessmentEvaluation.getAssessmentStatus()); } + private boolean isMandatory(AssessmentEvaluation evaluation) { + return evaluation.getObligation() != null && AssessmentObligation.mandatory.equals(evaluation.getObligation()); + } + private boolean isNotDone(AssessmentEvaluation assessmentEvaluation) { + return !AssessmentEntryStatus.done.equals(assessmentEvaluation.getAssessmentStatus()); + } + } diff --git a/src/main/java/org/olat/course/nodes/st/assessment/ScoreStatusEvaluator.java b/src/main/java/org/olat/course/nodes/st/assessment/ScoreStatusEvaluator.java index 3ce8806f298..ca679c440b7 100644 --- a/src/main/java/org/olat/course/nodes/st/assessment/ScoreStatusEvaluator.java +++ b/src/main/java/org/olat/course/nodes/st/assessment/ScoreStatusEvaluator.java @@ -35,7 +35,7 @@ public class ScoreStatusEvaluator implements StatusEvaluator { @Override public AssessmentEntryStatus getStatus(AssessmentEvaluation previousEvaluation, - AssessmentEvaluation currentEvaluation) { + AssessmentEvaluation currentEvaluation, boolean firstChild) { if (currentEvaluation.getPassed() != null && currentEvaluation.getPassed().booleanValue()) { return AssessmentEntryStatus.done; } else if (currentEvaluation.getScore() != null) { diff --git a/src/main/java/org/olat/course/run/scoring/AccountingEvaluatorsFactory.java b/src/main/java/org/olat/course/run/scoring/AccountingEvaluatorsFactory.java index 3520fb46490..20840356838 100644 --- a/src/main/java/org/olat/course/run/scoring/AccountingEvaluatorsFactory.java +++ b/src/main/java/org/olat/course/run/scoring/AccountingEvaluatorsFactory.java @@ -83,7 +83,13 @@ class AccountingEvaluatorsFactory { private static class NullObligationEvaluator implements ObligationEvaluator { @Override - public AssessmentObligation getObligation(CourseNode courseNode) { + public AssessmentObligation getObligation(AssessmentEvaluation currentEvaluation, CourseNode courseNode) { + return null; + } + + @Override + public AssessmentObligation getObligation(AssessmentEvaluation currentEvaluation, + List<AssessmentEvaluation> children) { return null; } @@ -145,7 +151,7 @@ class AccountingEvaluatorsFactory { @Override public AssessmentEntryStatus getStatus(AssessmentEvaluation previousEvaluation, - AssessmentEvaluation currentEvaluation) { + AssessmentEvaluation currentEvaluation, boolean firstChild) { return currentEvaluation.getAssessmentStatus(); } diff --git a/src/main/java/org/olat/course/run/scoring/AssessmentAccounting.java b/src/main/java/org/olat/course/run/scoring/AssessmentAccounting.java index c0b17d34646..f74940b0bba 100644 --- a/src/main/java/org/olat/course/run/scoring/AssessmentAccounting.java +++ b/src/main/java/org/olat/course/run/scoring/AssessmentAccounting.java @@ -57,7 +57,7 @@ public class AssessmentAccounting implements ScoreAccounting { private final CourseConfig courseConfig; private Map<String, AssessmentEntry> identToEntry = new HashMap<>(); private final Map<CourseNode, AssessmentEvaluation> courseNodeToEval = new HashMap<>(); - private AssessmentEvaluation previosEvaluation; + private AssessmentEvaluation previousEvaluation; @Autowired private CourseAssessmentService courseAssessmentService; @@ -90,7 +90,7 @@ public class AssessmentAccounting implements ScoreAccounting { @Override public boolean evaluateAll(boolean update) { - previosEvaluation = null; + previousEvaluation = null; courseNodeToEval.clear(); identToEntry = loadAssessmentEntries(getIdentity()); @@ -99,7 +99,7 @@ public class AssessmentAccounting implements ScoreAccounting { fillCacheRecursiv(root); if (update) { - updateEntryRecursiv(root); + updateEntryRecursiv(root, true); } return false; @@ -145,7 +145,7 @@ public class AssessmentAccounting implements ScoreAccounting { return entry; } - private AccountingResult updateEntryRecursiv(CourseNode courseNode) { + private AccountingResult updateEntryRecursiv(CourseNode courseNode, boolean firstChild) { log.debug("Evaluate course node: type '{}', ident: '{}'", courseNode.getType(), courseNode.getIdent()); AssessmentEvaluation currentEvaluation = courseNodeToEval.get(courseNode); @@ -154,7 +154,7 @@ public class AssessmentAccounting implements ScoreAccounting { AccountingEvaluators evaluators = courseAssessmentService.getEvaluators(courseNode, courseConfig); ObligationEvaluator obligationEvaluator = evaluators.getObligationEvaluator(); - AssessmentObligation obligation = obligationEvaluator.getObligation(courseNode); + AssessmentObligation obligation = obligationEvaluator.getObligation(result, courseNode); result.setObligation(obligation); DurationEvaluator durationEvaluator = evaluators.getDurationEvaluator(); @@ -174,17 +174,18 @@ public class AssessmentAccounting implements ScoreAccounting { result.setPassed(passed); StatusEvaluator statusEvaluator = evaluators.getStatusEvaluator(); - AssessmentEntryStatus status = statusEvaluator.getStatus(previosEvaluation, result); + AssessmentEntryStatus status = statusEvaluator.getStatus(previousEvaluation, result, firstChild); result.setStatus(status); - previosEvaluation = result; + previousEvaluation = result; int childCount = courseNode.getChildCount(); List<AssessmentEvaluation> children = new ArrayList<>(childCount); for (int i = 0; i < childCount; i++) { INode child = courseNode.getChildAt(i); + firstChild = i== 0; if (child instanceof CourseNode) { CourseNode childCourseNode = (CourseNode) child; - AccountingResult childResult = updateEntryRecursiv(childCourseNode); + AccountingResult childResult = updateEntryRecursiv(childCourseNode, firstChild); children.add(childResult); } } @@ -199,6 +200,9 @@ public class AssessmentAccounting implements ScoreAccounting { result.setLastUserModified(lastModifications.getLastUserModified()); result.setLastCoachModified(lastModifications.getLastCoachModified()); + obligation = obligationEvaluator.getObligation(result, children); + result.setObligation(obligation); + CompletionEvaluator completionEvaluator = evaluators.getCompletionEvaluator(); Double completion = completionEvaluator.getCompletion(result, courseNode, this); result.setCompletion(completion); diff --git a/src/main/java/org/olat/course/run/scoring/ObligationEvaluator.java b/src/main/java/org/olat/course/run/scoring/ObligationEvaluator.java index 74bbdad6958..0d22a418592 100644 --- a/src/main/java/org/olat/course/run/scoring/ObligationEvaluator.java +++ b/src/main/java/org/olat/course/run/scoring/ObligationEvaluator.java @@ -19,6 +19,8 @@ */ package org.olat.course.run.scoring; +import java.util.List; + import org.olat.course.nodes.CourseNode; import org.olat.modules.assessment.model.AssessmentObligation; @@ -30,6 +32,8 @@ import org.olat.modules.assessment.model.AssessmentObligation; */ public interface ObligationEvaluator { - public AssessmentObligation getObligation(CourseNode courseNode); + public AssessmentObligation getObligation(AssessmentEvaluation currentEvaluation, CourseNode courseNode); + + public AssessmentObligation getObligation(AssessmentEvaluation currentEvaluation, List<AssessmentEvaluation> children); } diff --git a/src/main/java/org/olat/course/run/scoring/StatusEvaluator.java b/src/main/java/org/olat/course/run/scoring/StatusEvaluator.java index 9c70e98d659..c20f4a90e64 100644 --- a/src/main/java/org/olat/course/run/scoring/StatusEvaluator.java +++ b/src/main/java/org/olat/course/run/scoring/StatusEvaluator.java @@ -31,7 +31,7 @@ import org.olat.modules.assessment.model.AssessmentEntryStatus; */ public interface StatusEvaluator { - public AssessmentEntryStatus getStatus(AssessmentEvaluation previousEvaluation, AssessmentEvaluation currentEvaluation); + public AssessmentEntryStatus getStatus(AssessmentEvaluation previousEvaluation, AssessmentEvaluation currentEvaluation, boolean firstChild); public AssessmentEntryStatus getStatus(AssessmentEvaluation currentEvaluation, List<AssessmentEvaluation>children); diff --git a/src/test/java/org/olat/course/learningpath/evaluation/DefaultLinearStatusEvaluatorTest.java b/src/test/java/org/olat/course/learningpath/evaluation/DefaultLinearStatusEvaluatorTest.java index 9a17cde9281..fa740e41adb 100644 --- a/src/test/java/org/olat/course/learningpath/evaluation/DefaultLinearStatusEvaluatorTest.java +++ b/src/test/java/org/olat/course/learningpath/evaluation/DefaultLinearStatusEvaluatorTest.java @@ -48,7 +48,7 @@ public class DefaultLinearStatusEvaluatorTest { public void shouldReturnDoneIfAssessmentStatusIsDone() { AssessmentEvaluation assessmentEvaluation = getAssessmentEvaluation(null, done, null); - AssessmentEntryStatus status = sut.getStatus(null, assessmentEvaluation); + AssessmentEntryStatus status = sut.getStatus(null, assessmentEvaluation, false); assertThat(status).isEqualTo(done); } @@ -57,7 +57,7 @@ public class DefaultLinearStatusEvaluatorTest { public void shouldReturnReadyIfIsRootNodeAndNotAlreadyDone() { AssessmentEvaluation assessmentEvaluation = getAssessmentEvaluation(null, notStarted, null); - AssessmentEntryStatus status = sut.getStatus(null, assessmentEvaluation); + AssessmentEntryStatus status = sut.getStatus(null, assessmentEvaluation, false); assertThat(status).isEqualTo(notStarted); } @@ -66,7 +66,7 @@ public class DefaultLinearStatusEvaluatorTest { public void shouldReturnReadyIfIsRootNodeAndIsNotStartedYet() { AssessmentEvaluation assessmentEvaluation = getAssessmentEvaluation(null, notReady, null); - AssessmentEntryStatus status = sut.getStatus(null, assessmentEvaluation); + AssessmentEntryStatus status = sut.getStatus(null, assessmentEvaluation, false); assertThat(status).isEqualTo(notStarted); } @@ -75,7 +75,7 @@ public class DefaultLinearStatusEvaluatorTest { public void shouldReturnReadyIfIsRootNodeAndHasNoStatusYet() { AssessmentEvaluation assessmentEvaluation = getAssessmentEvaluation(null, null, null); - AssessmentEntryStatus status = sut.getStatus(null, assessmentEvaluation); + AssessmentEntryStatus status = sut.getStatus(null, assessmentEvaluation, false); assertThat(status).isEqualTo(notStarted); } @@ -123,10 +123,21 @@ public class DefaultLinearStatusEvaluatorTest { AssessmentEvaluation previousEvaluation = getAssessmentEvaluation(previousFullyAssessd, previousStatus, previousObligation); AssessmentEvaluation currentEvaluation = getAssessmentEvaluation(null, currentStatus, null); - AssessmentEntryStatus status = sut.getStatus(previousEvaluation, currentEvaluation); + AssessmentEntryStatus status = sut.getStatus(previousEvaluation, currentEvaluation, false); assertThat(status).isEqualTo(expected); } + + @Test + public void shouldRetrunNotStartedIfisFirstChildAndPreviuosIsNotStartedAndMandatory() { + AssessmentEvaluation previousEvaluation = getAssessmentEvaluation(null, AssessmentEntryStatus.notStarted, AssessmentObligation.mandatory); + AssessmentEvaluation currentEvaluation = getAssessmentEvaluation(null, AssessmentEntryStatus.notReady, null); + + AssessmentEntryStatus status = sut.getStatus(previousEvaluation, currentEvaluation, true); + + assertThat(status).isEqualTo(AssessmentEntryStatus.notStarted); + } + @Test public void shouldNotChangeStatusWhenCheckingAgainstChildren() { diff --git a/src/test/java/org/olat/course/nodes/st/assessment/MandatoryObligationEvaluatorTest.java b/src/test/java/org/olat/course/nodes/st/assessment/MandatoryObligationEvaluatorTest.java new file mode 100644 index 00000000000..2275c2bca8d --- /dev/null +++ b/src/test/java/org/olat/course/nodes/st/assessment/MandatoryObligationEvaluatorTest.java @@ -0,0 +1,82 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.course.nodes.st.assessment; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; +import org.olat.course.nodes.CourseNode; +import org.olat.course.nodes.STCourseNode; +import org.olat.course.run.scoring.AssessmentEvaluation; +import org.olat.modules.assessment.model.AssessmentObligation; + +/** + * + * Initial date: 23 Oct 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public class MandatoryObligationEvaluatorTest { + + private MandatoryObligationEvaluator sut = new MandatoryObligationEvaluator(); + + @Test + public void shouldReturnMandatoryIfAtLeastOneChildIsMandatory() { + AssessmentEvaluation currentEvaluation = getAssessmentEvaluation(null); + AssessmentEvaluation child1 = getAssessmentEvaluation(AssessmentObligation.mandatory); + AssessmentEvaluation child2 = getAssessmentEvaluation(AssessmentObligation.optional); + List<AssessmentEvaluation> children = Arrays.asList(child1, child2); + + AssessmentObligation obligation = sut.getObligation(currentEvaluation, children); + + assertThat(obligation).isEqualTo(AssessmentObligation.mandatory); + } + + @Test + public void shouldReturnOptionalIfAllChildrenAreOptional() { + AssessmentEvaluation currentEvaluation = getAssessmentEvaluation(null); + AssessmentEvaluation child1 = getAssessmentEvaluation(null); + AssessmentEvaluation child2 = getAssessmentEvaluation(AssessmentObligation.optional); + List<AssessmentEvaluation> children = Arrays.asList(child1, child2); + + AssessmentObligation obligation = sut.getObligation(currentEvaluation, children); + + assertThat(obligation).isEqualTo(AssessmentObligation.optional); + + } + + @Test + public void shouldNotDependOnCourseNode() { + AssessmentEvaluation currentEvaluation = getAssessmentEvaluation(AssessmentObligation.optional); + CourseNode courseNode = new STCourseNode(); + + AssessmentObligation obligation = sut.getObligation(currentEvaluation, courseNode); + + assertThat(obligation).isEqualTo(AssessmentObligation.optional); + } + + private AssessmentEvaluation getAssessmentEvaluation(AssessmentObligation obligation) { + return new AssessmentEvaluation(null, null, null, null, null, null, null, null, null, null, null, null, 0, null, null, null, null, obligation, null); + } + +} diff --git a/src/test/java/org/olat/course/nodes/st/assessment/STLinearStatusEvaluatorTest.java b/src/test/java/org/olat/course/nodes/st/assessment/STLinearStatusEvaluatorTest.java index 079dc0c8d44..9dc3815a459 100644 --- a/src/test/java/org/olat/course/nodes/st/assessment/STLinearStatusEvaluatorTest.java +++ b/src/test/java/org/olat/course/nodes/st/assessment/STLinearStatusEvaluatorTest.java @@ -25,7 +25,6 @@ import java.util.Arrays; import java.util.List; import org.junit.Test; -import org.olat.course.nodes.st.assessment.STLinearStatusEvaluator; import org.olat.course.run.scoring.AssessmentEvaluation; import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.modules.assessment.model.AssessmentObligation; @@ -56,28 +55,60 @@ public class STLinearStatusEvaluatorTest { } @Test - public void shouldReturnInProgressIfChildIsDone() { - assertStatus(AssessmentEntryStatus.notStarted, AssessmentEntryStatus.done, AssessmentEntryStatus.inProgress); + public void shouldReturnNotStartedIfNoChildIsStarted() { + assertStatus(AssessmentEntryStatus.inProgress, AssessmentEntryStatus.notStarted, AssessmentEntryStatus.notStarted); + } + + private void assertStatus(AssessmentEntryStatus currentStatus, AssessmentEntryStatus childStatus, AssessmentEntryStatus expectedtStatus) { + AssessmentEvaluation currentEvaluation = getAssessmentEvaluation(null, currentStatus, null); + AssessmentEvaluation child = getAssessmentEvaluation(Boolean.TRUE, childStatus, AssessmentObligation.mandatory); + List<AssessmentEvaluation> children = Arrays.asList(child); + + AssessmentEntryStatus status = sut.getStatus(currentEvaluation, children); + + assertThat(status).isEqualTo(expectedtStatus); } @Test - public void shouldReturnInProgessEvenIfChildIsNot() { - assertStatus(AssessmentEntryStatus.inProgress, AssessmentEntryStatus.notStarted, AssessmentEntryStatus.inProgress); + public void shouldReturnDoneIfAllMandatoryChildrenAreDone() { + AssessmentEvaluation currentEvaluation = getAssessmentEvaluation(Boolean.FALSE, AssessmentEntryStatus.inProgress, null); + AssessmentEvaluation child1 = getAssessmentEvaluation(Boolean.TRUE, AssessmentEntryStatus.done, + AssessmentObligation.mandatory); + AssessmentEvaluation child2 = getAssessmentEvaluation(Boolean.TRUE, AssessmentEntryStatus.inProgress, + AssessmentObligation.optional); + List<AssessmentEvaluation> children = Arrays.asList(child1, child2); + + AssessmentEntryStatus status = sut.getStatus(currentEvaluation, children); + + assertThat(status).isEqualTo(AssessmentEntryStatus.done); } @Test - public void shouldReturnDoneEvenIfChildIsNot() { - assertStatus(AssessmentEntryStatus.done, AssessmentEntryStatus.notStarted, AssessmentEntryStatus.done); + public void shouldNotReturnDoneIfNotAllMandatoryChildrenAreDone() { + AssessmentEvaluation currentEvaluation = getAssessmentEvaluation(Boolean.TRUE, AssessmentEntryStatus.done, null); + AssessmentEvaluation child1 = getAssessmentEvaluation(Boolean.TRUE, AssessmentEntryStatus.inProgress, + AssessmentObligation.mandatory); + AssessmentEvaluation child2 = getAssessmentEvaluation(Boolean.TRUE, AssessmentEntryStatus.done, + AssessmentObligation.optional); + List<AssessmentEvaluation> children = Arrays.asList(child1, child2); + + AssessmentEntryStatus status = sut.getStatus(currentEvaluation, children); + + assertThat(status).isEqualTo(AssessmentEntryStatus.inProgress); } - public void assertStatus(AssessmentEntryStatus currentStatus, AssessmentEntryStatus childStatus, AssessmentEntryStatus expectedtStatus) { - AssessmentEvaluation currentEvaluation = getAssessmentEvaluation(null, currentStatus, null); - AssessmentEvaluation child = getAssessmentEvaluation(Boolean.TRUE, childStatus, null); - List<AssessmentEvaluation> children = Arrays.asList(child); + @Test + public void shouldReturnDoneIfItHAsOnlyOptionalChildren() { + AssessmentEvaluation currentEvaluation = getAssessmentEvaluation(Boolean.TRUE, AssessmentEntryStatus.notStarted, null); + AssessmentEvaluation child1 = getAssessmentEvaluation(Boolean.FALSE, AssessmentEntryStatus.inProgress, + AssessmentObligation.optional); + AssessmentEvaluation child2 = getAssessmentEvaluation(Boolean.FALSE, AssessmentEntryStatus.notStarted, + AssessmentObligation.optional); + List<AssessmentEvaluation> children = Arrays.asList(child1, child2); AssessmentEntryStatus status = sut.getStatus(currentEvaluation, children); - assertThat(status).isEqualTo(expectedtStatus); + assertThat(status).isEqualTo(AssessmentEntryStatus.done); } private AssessmentEvaluation getAssessmentEvaluation(Boolean fullyAssessd, AssessmentEntryStatus assessmentStatus, AssessmentObligation obligation) { diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java index 1d1c513cbe7..996dfac9a88 100644 --- a/src/test/java/org/olat/test/AllTestsJunit4.java +++ b/src/test/java/org/olat/test/AllTestsJunit4.java @@ -460,6 +460,7 @@ import org.junit.runners.Suite; org.olat.course.learningpath.evaluation.LinearAccessEvaluator.class, org.olat.course.learningpath.manager.LearningPathNodeAccessProviderTest.class, org.olat.course.nodes.st.assessment.CumulatingDurationEvaluatorTest.class, + org.olat.course.nodes.st.assessment.MandatoryObligationEvaluatorTest.class, org.olat.course.nodes.st.assessment.STFullyAssessedEvaluatorTest.class, org.olat.course.nodes.st.assessment.STLastModificationsEvaluatorTest.class, org.olat.course.nodes.st.assessment.STLinearStatusEvaluatorTest.class, -- GitLab