From ae7c51d2fe051421e4eb432cf73bcb9bc117d5d4 Mon Sep 17 00:00:00 2001
From: uhensler <urs.hensler@frentix.com>
Date: Sun, 16 Jun 2019 09:00:32 +0200
Subject: [PATCH] OO-4080: Rubric column in assessment tool course node list

---
 .../IdentityListCourseNodeController.java     |   6 +-
 .../MSIdentityListCourseNodeController.java   |  64 ++++-
 .../org/olat/course/nodes/ms/MSService.java   |   2 +
 .../nodes/ms/_i18n/LocalStrings_de.properties |   1 +
 .../nodes/ms/_i18n/LocalStrings_en.properties |   1 +
 .../nodes/ms/manager/MSServiceImpl.java       |   6 +
 .../org/olat/modules/forms/SessionFilter.java |   4 +
 .../modules/forms/SessionFilterFactory.java   |  12 +-
 .../manager/EvaluationFormSessionDAO.java     |   6 +-
 .../modules/forms/model/jpa/SurveyFilter.java |  58 -----
 .../forms/model/jpa/SurveysFilter.java        | 113 +++++++++
 .../manager/EvaluationFormTestsHelper.java    |   2 +-
 .../forms/model/jpa/SurveyFilterTest.java     |  78 ------
 .../forms/model/jpa/SurveysFilterTest.java    | 226 ++++++++++++++++++
 .../java/org/olat/test/AllTestsJunit4.java    |   2 +-
 15 files changed, 436 insertions(+), 145 deletions(-)
 delete mode 100644 src/main/java/org/olat/modules/forms/model/jpa/SurveyFilter.java
 create mode 100644 src/main/java/org/olat/modules/forms/model/jpa/SurveysFilter.java
 delete mode 100644 src/test/java/org/olat/modules/forms/model/jpa/SurveyFilterTest.java
 create mode 100644 src/test/java/org/olat/modules/forms/model/jpa/SurveysFilterTest.java

diff --git a/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeController.java b/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeController.java
index 0870415c92c..a0317f75851 100644
--- a/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeController.java
+++ b/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeController.java
@@ -374,7 +374,7 @@ public class IdentityListCourseNodeController extends FormBasicController
 						columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, IdentityCourseElementCols.cut, new ScoreCellRenderer()));
 					}
 				}
-				columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.score, new ScoreCellRenderer()));
+				initScoreColumns(columnsModel);
 			}
 			if(assessableNode.hasPassedConfigured()) {
 				columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.passed, new PassedCellRenderer()));
@@ -384,6 +384,10 @@ public class IdentityListCourseNodeController extends FormBasicController
 			}
 		}
 	}
+
+	protected void initScoreColumns(FlexiTableColumnModel columnsModel) {
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.score, new ScoreCellRenderer()));
+	}
 	
 	protected void initStatusColumns(FlexiTableColumnModel columnsModel) {
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.assessmentStatus, new AssessmentStatusCellRenderer(getLocale())));
diff --git a/src/main/java/org/olat/course/nodes/ms/MSIdentityListCourseNodeController.java b/src/main/java/org/olat/course/nodes/ms/MSIdentityListCourseNodeController.java
index 6dbd106eb9b..3520b8bd465 100644
--- a/src/main/java/org/olat/course/nodes/ms/MSIdentityListCourseNodeController.java
+++ b/src/main/java/org/olat/course/nodes/ms/MSIdentityListCourseNodeController.java
@@ -19,18 +19,32 @@
  */
 package org.olat.course.nodes.ms;
 
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.BooleanCellRenderer;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.CSSIconFlexiCellRenderer;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
 import org.olat.core.gui.components.stack.TooledStackedPanel;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.course.assessment.bulk.BulkAssessmentToolController;
 import org.olat.course.assessment.ui.tool.IdentityListCourseNodeController;
+import org.olat.course.assessment.ui.tool.IdentityListCourseNodeTableModel.IdentityCourseElementCols;
 import org.olat.course.nodes.MSCourseNode;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.group.BusinessGroup;
+import org.olat.modules.ModuleConfiguration;
+import org.olat.modules.assessment.ui.AssessedIdentityElementRow;
 import org.olat.modules.assessment.ui.AssessmentToolContainer;
 import org.olat.modules.assessment.ui.AssessmentToolSecurityCallback;
+import org.olat.modules.forms.EvaluationFormSession;
 import org.olat.repository.RepositoryEntry;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * 
@@ -39,6 +53,11 @@ import org.olat.repository.RepositoryEntry;
  *
  */
 public class MSIdentityListCourseNodeController extends IdentityListCourseNodeController {
+	
+	private Boolean hasEvaluationForm;
+	
+	@Autowired
+	private MSService msService;
 
 	public MSIdentityListCourseNodeController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel,
 			RepositoryEntry courseEntry, BusinessGroup group, MSCourseNode courseNode, UserCourseEnvironment coachCourseEnv,
@@ -49,11 +68,50 @@ public class MSIdentityListCourseNodeController extends IdentityListCourseNodeCo
 	@Override
 	protected void initMultiSelectionTools(UserRequest ureq, FormLayoutContainer formLayout) {
 		if(!coachCourseEnv.isCourseReadOnly()) {
-			BulkAssessmentToolController bulkAssessmentTollCtrl = new BulkAssessmentToolController(ureq, getWindowControl(),
+			BulkAssessmentToolController bulkAssessmentToolCtrl = new BulkAssessmentToolController(ureq, getWindowControl(),
 					coachCourseEnv.getCourseEnvironment(), (MSCourseNode)courseNode);
-			listenTo(bulkAssessmentTollCtrl);
-			formLayout.put("bulk.assessment", bulkAssessmentTollCtrl.getInitialComponent());	
+			listenTo(bulkAssessmentToolCtrl);
+			formLayout.put("bulk.assessment", bulkAssessmentToolCtrl.getInitialComponent());
 		}
 		super.initMultiSelectionTools(ureq, formLayout);
 	}
+	
+	@Override
+	protected void initScoreColumns(FlexiTableColumnModel columnsModel) {
+		if (hasEvaluationForm()) {
+			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("table.header.details.ms",
+					IdentityCourseElementCols.details.ordinal(),
+					new BooleanCellRenderer(new CSSIconFlexiCellRenderer("o_icon_lg o_icon_check"), null)));
+		}
+		super.initScoreColumns(columnsModel);
+	}
+	
+	@Override
+	protected void loadModel(UserRequest ureq) {
+		super.loadModel(ureq);
+		
+		if (hasEvaluationForm) {
+			List<EvaluationFormSession> sessions = msService.getDoneSessions(getCourseRepositoryEntry(), courseNode.getIdent());
+			Map<String, EvaluationFormSession> identToSesssion = sessions.stream()
+					.collect(Collectors.toMap(
+							s -> s.getSurvey().getIdentifier().getSubident2(),
+							Function.identity()));
+			
+			for (AssessedIdentityElementRow row : usersTableModel.getObjects()) {
+				String ident = row.getIdentityKey().toString();
+				Boolean sessionDone = identToSesssion.containsKey(ident);
+				row.setDetails(sessionDone);
+			}
+		}
+	}
+
+	private boolean hasEvaluationForm() {
+		if (hasEvaluationForm == null) {
+			ModuleConfiguration config = courseNode.getModuleConfiguration();
+			String scoreConfig = config.getStringValue(MSCourseNode.CONFIG_KEY_SCORE);
+			hasEvaluationForm = MSCourseNode.CONFIG_VALUE_SCORE_EVAL_FORM_SUM.equals(scoreConfig)
+					|| MSCourseNode.CONFIG_VALUE_SCORE_EVAL_FORM_AVG.equals(scoreConfig);
+		}
+		return hasEvaluationForm.booleanValue();
+	}
 }
diff --git a/src/main/java/org/olat/course/nodes/ms/MSService.java b/src/main/java/org/olat/course/nodes/ms/MSService.java
index 0198aee4fca..66ca8db523d 100644
--- a/src/main/java/org/olat/course/nodes/ms/MSService.java
+++ b/src/main/java/org/olat/course/nodes/ms/MSService.java
@@ -47,6 +47,8 @@ public interface MSService {
 
 	boolean hasSessions(OLATResourceable ores, String nodeIdent);
 	
+	List<EvaluationFormSession> getDoneSessions(OLATResourceable ores, String nodeIdent);
+	
 	void deleteSessions(RepositoryEntry ores, String nodeIdent);
 	
 	List<RubricStatistic> getRubricStatistics(EvaluationFormSession session);
diff --git a/src/main/java/org/olat/course/nodes/ms/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/nodes/ms/_i18n/LocalStrings_de.properties
index 670d1cfaac1..98ba0b22e00 100644
--- a/src/main/java/org/olat/course/nodes/ms/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/course/nodes/ms/_i18n/LocalStrings_de.properties
@@ -62,4 +62,5 @@ score.yourscore=Erreichte Punktzahl
 scoring.config.enable.button=\u00C4ndern
 scoring.overwriting=Es wurden bereits Bewertungen vorgenommen. Wollen Sie die Bewertungskonfiguartion trotzdem \u00E4ndern ?
 scoring.overwriting.note=Hinweis \: Sie \u00E4ndern die Bewertungskonfiguration obwohl bereits Bewertungen vorgenommen wurden.
+table.header.details.ms=Rubrik
 warn.nodedelete=Achtung\: Alle bisher angefallenen Daten dieses Kursbausteines werden gel\u00F6scht.
diff --git a/src/main/java/org/olat/course/nodes/ms/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/nodes/ms/_i18n/LocalStrings_en.properties
index 1f71635e7f5..f86d089bc20 100644
--- a/src/main/java/org/olat/course/nodes/ms/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/course/nodes/ms/_i18n/LocalStrings_en.properties
@@ -62,4 +62,5 @@ score.yourscore=Your score
 scoring.config.enable.button=Modify
 scoring.overwriting=There are already some assessments existing. Do you still want to modify your assessment configuration?
 scoring.overwriting.note=Please note\: you are modifying the assessment configuration although there are already some assessments existing.
+table.header.details.ms=Rubric
 warn.nodedelete=Warning\: All data of this course element will be deleted.
diff --git a/src/main/java/org/olat/course/nodes/ms/manager/MSServiceImpl.java b/src/main/java/org/olat/course/nodes/ms/manager/MSServiceImpl.java
index a8d4be1180e..17e2534383e 100644
--- a/src/main/java/org/olat/course/nodes/ms/manager/MSServiceImpl.java
+++ b/src/main/java/org/olat/course/nodes/ms/manager/MSServiceImpl.java
@@ -114,6 +114,12 @@ public class MSServiceImpl implements MSService {
 		return !evaluationFormManager.loadSurveys(of(ores, nodeIdent)).isEmpty();
 	}
 
+	@Override
+	public List<EvaluationFormSession> getDoneSessions(OLATResourceable ores, String nodeIdent) {
+		SessionFilter filter = SessionFilterFactory.createSelectDone(of(ores, nodeIdent));
+		return evaluationFormManager.loadSessionsFiltered(filter, 0, -1);
+	}
+
 	@Override
 	public void deleteSessions(RepositoryEntry ores, String nodeIdent) {
 		List<EvaluationFormSurvey> surveys = evaluationFormManager.loadSurveys(of(ores, nodeIdent));
diff --git a/src/main/java/org/olat/modules/forms/SessionFilter.java b/src/main/java/org/olat/modules/forms/SessionFilter.java
index bcc8fbf1306..b7ca2e9293d 100644
--- a/src/main/java/org/olat/modules/forms/SessionFilter.java
+++ b/src/main/java/org/olat/modules/forms/SessionFilter.java
@@ -34,5 +34,9 @@ public interface SessionFilter {
 	public String getSelectKeys();
 	
 	public void addParameters(Query query);
+	
+	public default boolean fetchSurveys() {
+		return false;
+	}
 
 }
diff --git a/src/main/java/org/olat/modules/forms/SessionFilterFactory.java b/src/main/java/org/olat/modules/forms/SessionFilterFactory.java
index 5414e474337..3dbb36753c1 100644
--- a/src/main/java/org/olat/modules/forms/SessionFilterFactory.java
+++ b/src/main/java/org/olat/modules/forms/SessionFilterFactory.java
@@ -22,9 +22,10 @@ package org.olat.modules.forms;
 import static java.util.Collections.singletonList;
 
 import java.util.Collection;
+import java.util.Collections;
 
 import org.olat.modules.forms.model.jpa.SessionRefFilter;
-import org.olat.modules.forms.model.jpa.SurveyFilter;
+import org.olat.modules.forms.model.jpa.SurveysFilter;
 
 /**
  * 
@@ -43,7 +44,14 @@ public class SessionFilterFactory {
 	}
 
 	public static SessionFilter createSelectDone(EvaluationFormSurveyRef survey) {
-		return new SurveyFilter(survey);
+		return createSelectDone(Collections.singletonList(survey));
 	}
 
+	public static SessionFilter createSelectDone(Collection<? extends EvaluationFormSurveyRef> surveys) {
+		return new SurveysFilter(surveys, EvaluationFormSessionStatus.done);
+	}
+
+	public static SessionFilter createSelectDone(EvaluationFormSurveyIdentifier surveyIdentitfier) {
+		return new SurveysFilter(surveyIdentitfier, EvaluationFormSessionStatus.done);
+	}
 }
diff --git a/src/main/java/org/olat/modules/forms/manager/EvaluationFormSessionDAO.java b/src/main/java/org/olat/modules/forms/manager/EvaluationFormSessionDAO.java
index f112e240648..af9307de70c 100644
--- a/src/main/java/org/olat/modules/forms/manager/EvaluationFormSessionDAO.java
+++ b/src/main/java/org/olat/modules/forms/manager/EvaluationFormSessionDAO.java
@@ -94,7 +94,11 @@ class EvaluationFormSessionDAO {
 			SortKey... orderBy) {
 
 		StringBuilder sb = new StringBuilder();
-		sb.append("select session from evaluationformsession as session");
+		sb.append("select session");
+		sb.append("  from evaluationformsession as session");
+		if (filter.fetchSurveys()) {
+			sb.append("       join fetch session.survey as survey");
+		}
 		sb.append(" where session.key in (").append(filter.getSelectKeys()).append(")");
 		
 		appendOrderBy(sb, orderBy);
diff --git a/src/main/java/org/olat/modules/forms/model/jpa/SurveyFilter.java b/src/main/java/org/olat/modules/forms/model/jpa/SurveyFilter.java
deleted file mode 100644
index 87563198ca2..00000000000
--- a/src/main/java/org/olat/modules/forms/model/jpa/SurveyFilter.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * <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.modules.forms.model.jpa;
-
-import javax.persistence.Query;
-
-import org.olat.core.commons.persistence.QueryBuilder;
-import org.olat.modules.forms.EvaluationFormSessionStatus;
-import org.olat.modules.forms.EvaluationFormSurveyRef;
-import org.olat.modules.forms.SessionFilter;
-
-/**
- * 
- * Initial date: 10.09.2018<br>
- * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
- *
- */
-public class SurveyFilter implements SessionFilter {
-
-	private final EvaluationFormSurveyRef survey;
-
-	public SurveyFilter(EvaluationFormSurveyRef survey) {
-		this.survey = survey;
-	}
-
-	@Override
-	public String getSelectKeys() {
-		QueryBuilder sb = new QueryBuilder(128);
-		sb.append("select sessionFilter.key");
-		sb.append("  from evaluationformsession sessionFilter");
-		sb.and().append("sessionFilter.status = '").append(EvaluationFormSessionStatus.done).append("'");
-		sb.and().append("sessionFilter.survey.key = :surveyFilterKey");
-		return sb.toString();
-	}
-
-	@Override
-	public void addParameters(Query query) {
-		query.setParameter("surveyFilterKey", survey.getKey());
-	}
-
-}
diff --git a/src/main/java/org/olat/modules/forms/model/jpa/SurveysFilter.java b/src/main/java/org/olat/modules/forms/model/jpa/SurveysFilter.java
new file mode 100644
index 00000000000..0ef27629c87
--- /dev/null
+++ b/src/main/java/org/olat/modules/forms/model/jpa/SurveysFilter.java
@@ -0,0 +1,113 @@
+/**
+ * <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.modules.forms.model.jpa;
+
+import static java.util.stream.Collectors.toList;
+
+import java.util.Collection;
+import java.util.List;
+
+import javax.persistence.Query;
+
+import org.olat.core.commons.persistence.QueryBuilder;
+import org.olat.core.util.StringHelper;
+import org.olat.modules.forms.EvaluationFormSessionStatus;
+import org.olat.modules.forms.EvaluationFormSurveyIdentifier;
+import org.olat.modules.forms.EvaluationFormSurveyRef;
+import org.olat.modules.forms.SessionFilter;
+
+/**
+ * 
+ * Initial date: 10.09.2018<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class SurveysFilter implements SessionFilter {
+
+	private Collection<? extends EvaluationFormSurveyRef> surveys;
+	private EvaluationFormSessionStatus status;
+	private EvaluationFormSurveyIdentifier surveyIdentitfier;
+	
+	public SurveysFilter(Collection<? extends EvaluationFormSurveyRef> surveys) {
+		this(surveys, null);
+	}
+
+	public SurveysFilter(Collection<? extends EvaluationFormSurveyRef> surveys, EvaluationFormSessionStatus status) {
+		this.surveys = surveys;
+		this.status = status;
+	}
+	
+	public SurveysFilter(EvaluationFormSurveyIdentifier surveyIdentitfier) {
+		this(surveyIdentitfier, null);
+	}
+
+	public SurveysFilter(EvaluationFormSurveyIdentifier surveyIdentitfier, EvaluationFormSessionStatus status) {
+		this.surveyIdentitfier = surveyIdentitfier;
+		this.status = status;
+	}
+
+	@Override
+	public String getSelectKeys() {
+		QueryBuilder sb = new QueryBuilder();
+		sb.append("select sessionFilter.key");
+		sb.append("  from evaluationformsession sessionFilter");
+		if (status != null) {
+			sb.and().append("sessionFilter.status = '").append(EvaluationFormSessionStatus.done).append("'");
+		}
+		if (surveys != null) {
+			sb.and().append("sessionFilter.survey.key in :surveyFilterKeys");
+		}
+		if (surveyIdentitfier != null) {
+			sb.and().append("sessionFilter.survey.resId = :surveyResId");
+			sb.and().append("sessionFilter.survey.resName = :surveyResName");
+			if (StringHelper.containsNonWhitespace(surveyIdentitfier.getSubident())) {
+				sb.and().append("sessionFilter.survey.resSubident = :surveyResSubident");
+			}
+			if (StringHelper.containsNonWhitespace(surveyIdentitfier.getSubident2())) {
+				sb.and().append("sessionFilter.survey.resSubident2 = :surveyResSubident2");
+			}
+		}
+		return sb.toString();
+	}
+
+	@Override
+	public void addParameters(Query query) {
+		if (surveys != null) {
+			List<Long> keys = surveys.stream().map(EvaluationFormSurveyRef::getKey).collect(toList());
+			query.setParameter("surveyFilterKeys", keys);
+		}
+		if (surveyIdentitfier != null) {
+			query.setParameter("surveyResId", surveyIdentitfier.getOLATResourceable().getResourceableId());
+			query.setParameter("surveyResName", surveyIdentitfier.getOLATResourceable().getResourceableTypeName());
+			if (StringHelper.containsNonWhitespace(surveyIdentitfier.getSubident())) {
+				query.setParameter("surveyResSubident", surveyIdentitfier.getSubident());
+			}
+			if (StringHelper.containsNonWhitespace(surveyIdentitfier.getSubident2())) {
+				query.setParameter("surveyResSubident2", surveyIdentitfier.getSubident2());
+			}
+		}
+	}
+
+	@Override
+	public boolean fetchSurveys() {
+		return true;
+	}
+
+}
diff --git a/src/test/java/org/olat/modules/forms/manager/EvaluationFormTestsHelper.java b/src/test/java/org/olat/modules/forms/manager/EvaluationFormTestsHelper.java
index 4a4562bbbf3..e6af52d8cf5 100644
--- a/src/test/java/org/olat/modules/forms/manager/EvaluationFormTestsHelper.java
+++ b/src/test/java/org/olat/modules/forms/manager/EvaluationFormTestsHelper.java
@@ -111,7 +111,7 @@ public class EvaluationFormTestsHelper {
 		dbInstance.commitAndCloseSession();
 	}
 
-	RepositoryEntry createFormEntry() {
+	public RepositoryEntry createFormEntry() {
 		EvaluationFormResource ores = new EvaluationFormResource();
 		OLATResource resource = OLATResourceManager.getInstance().findOrPersistResourceable(ores);
 		Identity author = JunitTestHelper.createAndPersistIdentityAsRndUser(UUID.randomUUID().toString());
diff --git a/src/test/java/org/olat/modules/forms/model/jpa/SurveyFilterTest.java b/src/test/java/org/olat/modules/forms/model/jpa/SurveyFilterTest.java
deleted file mode 100644
index 6a0b8e8b53c..00000000000
--- a/src/test/java/org/olat/modules/forms/model/jpa/SurveyFilterTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * <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.modules.forms.model.jpa;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.util.List;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.olat.core.commons.persistence.DB;
-import org.olat.modules.forms.EvaluationFormManager;
-import org.olat.modules.forms.EvaluationFormSession;
-import org.olat.modules.forms.EvaluationFormSurvey;
-import org.olat.modules.forms.manager.EvaluationFormTestsHelper;
-import org.olat.modules.forms.model.jpa.SurveyFilter;
-import org.olat.test.OlatTestCase;
-import org.springframework.beans.factory.annotation.Autowired;
-
-/**
- * 
- * Initial date: 10.09.2018<br>
- * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
- *
- */
-public class SurveyFilterTest extends OlatTestCase {
-	
-	@Autowired
-	private DB dbInstance;
-	@Autowired
-	private EvaluationFormTestsHelper evaTestHelper;
-	@Autowired
-	private EvaluationFormManager evaManager;
-	
-	@Before
-	public void cleanUp() {
-		evaTestHelper.deleteAll();
-	}
-	
-	@Test
-	public void shouldFilterBySurvey() {
-		EvaluationFormSurvey survey = evaTestHelper.createSurvey();
-		EvaluationFormSurvey otherSurvey = evaTestHelper.createSurvey();
-		EvaluationFormSession session1 = evaTestHelper.createSession(survey);
-		evaManager.finishSession(session1);
-		EvaluationFormSession session2 = evaTestHelper.createSession(survey);
-		evaManager.finishSession(session2);
-		EvaluationFormSession unfinishedSession = evaTestHelper.createSession(survey);
-		EvaluationFormSession otherSession = evaTestHelper.createSession(otherSurvey);
-		evaManager.finishSession(otherSession);
-		dbInstance.commitAndCloseSession();
-		
-		SurveyFilter filter = new SurveyFilter(survey);
-		List<EvaluationFormSession> filtered = evaManager.loadSessionsFiltered(filter, 0, -1);
-		
-		assertThat(filtered)
-				.containsExactlyInAnyOrder(session1, session2)
-				.doesNotContain(unfinishedSession, otherSession);
-	}
-
-}
diff --git a/src/test/java/org/olat/modules/forms/model/jpa/SurveysFilterTest.java b/src/test/java/org/olat/modules/forms/model/jpa/SurveysFilterTest.java
new file mode 100644
index 00000000000..52d37b3e742
--- /dev/null
+++ b/src/test/java/org/olat/modules/forms/model/jpa/SurveysFilterTest.java
@@ -0,0 +1,226 @@
+/**
+ * <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.modules.forms.model.jpa;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.olat.modules.forms.EvaluationFormSurveyIdentifier.of;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.olat.core.commons.persistence.DB;
+import org.olat.core.id.OLATResourceable;
+import org.olat.modules.forms.EvaluationFormManager;
+import org.olat.modules.forms.EvaluationFormSession;
+import org.olat.modules.forms.EvaluationFormSessionStatus;
+import org.olat.modules.forms.EvaluationFormSurvey;
+import org.olat.modules.forms.manager.EvaluationFormTestsHelper;
+import org.olat.repository.RepositoryEntry;
+import org.olat.test.JunitTestHelper;
+import org.olat.test.OlatTestCase;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * 
+ * Initial date: 10.09.2018<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class SurveysFilterTest extends OlatTestCase {
+	
+	@Autowired
+	private DB dbInstance;
+	@Autowired
+	private EvaluationFormTestsHelper evaTestHelper;
+	@Autowired
+	private EvaluationFormManager evaManager;
+	
+	@Before
+	public void cleanUp() {
+		evaTestHelper.deleteAll();
+	}
+	
+	@Test
+	public void shouldFilterBySurvey() {
+		EvaluationFormSurvey survey = evaTestHelper.createSurvey();
+		EvaluationFormSurvey otherSurvey = evaTestHelper.createSurvey();
+		EvaluationFormSession session1 = evaTestHelper.createSession(survey);
+		evaManager.finishSession(session1);
+		EvaluationFormSession session2 = evaTestHelper.createSession(survey);
+		evaManager.finishSession(session2);
+		EvaluationFormSession sessionOtherSurvey = evaTestHelper.createSession(otherSurvey);
+		evaManager.finishSession(sessionOtherSurvey);
+		dbInstance.commitAndCloseSession();
+		
+		SurveysFilter filter = new SurveysFilter(Collections.singletonList(survey));
+		List<EvaluationFormSession> filtered = evaManager.loadSessionsFiltered(filter, 0, -1);
+		
+		assertThat(filtered)
+				.containsExactlyInAnyOrder(session1, session2)
+				.doesNotContain(sessionOtherSurvey);
+	}
+	
+	@Test
+	public void shouldFilterBySurveys() {
+		EvaluationFormSurvey survey1 = evaTestHelper.createSurvey();
+		EvaluationFormSurvey survey2 = evaTestHelper.createSurvey();
+		EvaluationFormSurvey otherSurvey = evaTestHelper.createSurvey();
+		EvaluationFormSession session11 = evaTestHelper.createSession(survey1);
+		evaManager.finishSession(session11);
+		EvaluationFormSession session22 = evaTestHelper.createSession(survey1);
+		evaManager.finishSession(session22);
+		EvaluationFormSession session21 = evaTestHelper.createSession(survey2);
+		evaManager.finishSession(session21);
+		EvaluationFormSession otherSession = evaTestHelper.createSession(otherSurvey);
+		evaManager.finishSession(otherSession);
+		dbInstance.commitAndCloseSession();
+		
+		SurveysFilter filter = new SurveysFilter(Arrays.asList(survey1, survey2));
+		List<EvaluationFormSession> filtered = evaManager.loadSessionsFiltered(filter, 0, -1);
+		
+		assertThat(filtered)
+				.containsExactlyInAnyOrder(session11, session22, session21)
+				.doesNotContain(otherSession);
+	}
+	
+	@Test
+	public void shouldFilterByIdentitfierOres() {
+		RepositoryEntry formEntry = evaTestHelper.createFormEntry();
+		OLATResourceable ores = JunitTestHelper.createRandomResource();
+		OLATResourceable oresOther = JunitTestHelper.createRandomResource();
+		String subIdent = UUID.randomUUID().toString();
+		String subIdent2 = UUID.randomUUID().toString();
+		String subIdent2a = UUID.randomUUID().toString();
+		
+		EvaluationFormSurvey survey = evaManager.createSurvey(of(ores), formEntry);
+		EvaluationFormSession session = evaTestHelper.createSession(survey);
+		EvaluationFormSurvey surveySubident = evaManager.createSurvey(of(ores, subIdent), formEntry);
+		EvaluationFormSession sessionSubident = evaTestHelper.createSession(surveySubident);
+		EvaluationFormSurvey surveySubident2 = evaManager.createSurvey(of(ores, subIdent, subIdent2), formEntry);
+		EvaluationFormSession sessionSubident2 = evaTestHelper.createSession(surveySubident2);
+		EvaluationFormSurvey surveySubident2a = evaManager.createSurvey(of(ores, subIdent, subIdent2a), formEntry);
+		EvaluationFormSession sessionSubident2a = evaTestHelper.createSession(surveySubident2a);
+		EvaluationFormSurvey otherSurveySubident2 = evaManager.createSurvey(of(oresOther, subIdent, subIdent2), formEntry);
+		EvaluationFormSession otherSessionSubident2 = evaTestHelper.createSession(otherSurveySubident2);
+		dbInstance.commitAndCloseSession();
+		
+		SurveysFilter filter = new SurveysFilter(of(ores));
+		List<EvaluationFormSession> filtered = evaManager.loadSessionsFiltered(filter, 0, -1);
+		
+		assertThat(filtered)
+				.containsExactlyInAnyOrder(
+						session,
+						sessionSubident,
+						sessionSubident2,
+						sessionSubident2a)
+				.doesNotContain(
+						otherSessionSubident2);
+	}
+	
+	@Test
+	public void shouldFilterByIdentitfierSubident() {
+		RepositoryEntry formEntry = evaTestHelper.createFormEntry();
+		OLATResourceable ores = JunitTestHelper.createRandomResource();
+		OLATResourceable oresOther = JunitTestHelper.createRandomResource();
+		String subIdent = UUID.randomUUID().toString();
+		String subIdent2 = UUID.randomUUID().toString();
+		String subIdent2a = UUID.randomUUID().toString();
+		
+		EvaluationFormSurvey survey = evaManager.createSurvey(of(ores), formEntry);
+		EvaluationFormSession session = evaTestHelper.createSession(survey);
+		EvaluationFormSurvey surveySubident = evaManager.createSurvey(of(ores, subIdent), formEntry);
+		EvaluationFormSession sessionSubident = evaTestHelper.createSession(surveySubident);
+		EvaluationFormSurvey surveySubident2 = evaManager.createSurvey(of(ores, subIdent, subIdent2), formEntry);
+		EvaluationFormSession sessionSubident2 = evaTestHelper.createSession(surveySubident2);
+		EvaluationFormSurvey surveySubident2a = evaManager.createSurvey(of(ores, subIdent, subIdent2a), formEntry);
+		EvaluationFormSession sessionSubident2a = evaTestHelper.createSession(surveySubident2a);
+		EvaluationFormSurvey otherSurveySubident2 = evaManager.createSurvey(of(oresOther, subIdent, subIdent2), formEntry);
+		EvaluationFormSession otherSessionSubident2 = evaTestHelper.createSession(otherSurveySubident2);
+		dbInstance.commitAndCloseSession();
+		
+		SurveysFilter filter = new SurveysFilter(of(ores, subIdent));
+		List<EvaluationFormSession> filtered = evaManager.loadSessionsFiltered(filter, 0, -1);
+		
+		assertThat(filtered)
+				.containsExactlyInAnyOrder(
+						sessionSubident,
+						sessionSubident2,
+						sessionSubident2a)
+				.doesNotContain(
+						session,
+						otherSessionSubident2);
+	}
+	
+	@Test
+	public void shouldFilterByIdentitfierSubident2() {
+		RepositoryEntry formEntry = evaTestHelper.createFormEntry();
+		OLATResourceable ores = JunitTestHelper.createRandomResource();
+		OLATResourceable oresOther = JunitTestHelper.createRandomResource();
+		String subIdent = UUID.randomUUID().toString();
+		String subIdent2 = UUID.randomUUID().toString();
+		String subIdent2a = UUID.randomUUID().toString();
+		
+		EvaluationFormSurvey survey = evaManager.createSurvey(of(ores), formEntry);
+		EvaluationFormSession session = evaTestHelper.createSession(survey);
+		EvaluationFormSurvey surveySubident = evaManager.createSurvey(of(ores, subIdent), formEntry);
+		EvaluationFormSession sessionSubident = evaTestHelper.createSession(surveySubident);
+		EvaluationFormSurvey surveySubident2 = evaManager.createSurvey(of(ores, subIdent, subIdent2), formEntry);
+		EvaluationFormSession sessionSubident2 = evaTestHelper.createSession(surveySubident2);
+		EvaluationFormSurvey surveySubident2a = evaManager.createSurvey(of(ores, subIdent, subIdent2a), formEntry);
+		EvaluationFormSession sessionSubident2a = evaTestHelper.createSession(surveySubident2a);
+		EvaluationFormSurvey otherSurveySubident2 = evaManager.createSurvey(of(oresOther, subIdent, subIdent2), formEntry);
+		EvaluationFormSession otherSessionSubident2 = evaTestHelper.createSession(otherSurveySubident2);
+		dbInstance.commitAndCloseSession();
+		
+		SurveysFilter filter = new SurveysFilter(of(ores, subIdent, subIdent2));
+		List<EvaluationFormSession> filtered = evaManager.loadSessionsFiltered(filter, 0, -1);
+		
+		assertThat(filtered)
+				.containsExactlyInAnyOrder(
+						sessionSubident2)
+				.doesNotContain(
+						session,
+						sessionSubident,
+						sessionSubident2a,
+						otherSessionSubident2);
+	}
+	
+	@Test
+	public void shouldFilterByStatus() {
+		EvaluationFormSurvey survey = evaTestHelper.createSurvey();
+		EvaluationFormSession sessionFinished1 = evaTestHelper.createSession(survey);
+		evaManager.finishSession(sessionFinished1);
+		EvaluationFormSession sessionFinished2 = evaTestHelper.createSession(survey);
+		evaManager.finishSession(sessionFinished2);
+		EvaluationFormSession sessionUnfinished = evaTestHelper.createSession(survey);
+		dbInstance.commitAndCloseSession();
+		
+		SurveysFilter filter = new SurveysFilter(Collections.singletonList(survey), EvaluationFormSessionStatus.done);
+		List<EvaluationFormSession> filtered = evaManager.loadSessionsFiltered(filter, 0, -1);
+		
+		assertThat(filtered)
+				.containsExactlyInAnyOrder(sessionFinished1, sessionFinished2)
+				.doesNotContain(sessionUnfinished);
+	}
+}
diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java
index 46b1977093a..1c0aa676ef1 100644
--- a/src/test/java/org/olat/test/AllTestsJunit4.java
+++ b/src/test/java/org/olat/test/AllTestsJunit4.java
@@ -216,7 +216,7 @@ import org.junit.runners.Suite;
 	org.olat.modules.forms.manager.EvaluationFormSessionDAOTest.class,
 	org.olat.modules.forms.manager.EvaluationFormStorageTest.class,
 	org.olat.modules.forms.manager.EvaluationFormSurveyDAOTest.class,
-	org.olat.modules.forms.model.jpa.SurveyFilterTest.class,
+	org.olat.modules.forms.model.jpa.SurveysFilterTest.class,
 	org.olat.modules.gotomeeting.manager.GoToJsonUtilTest.class,
 	org.olat.modules.gotomeeting.manager.GoToMeetingDAOTest.class,
 	org.olat.modules.gotomeeting.manager.GoToOrganizerDAOTest.class,
-- 
GitLab