From 3372f99f4f292843d690e4f441ed25bf98f2f4a8 Mon Sep 17 00:00:00 2001
From: srosse <stephane.rosse@frentix.com>
Date: Thu, 12 Mar 2020 07:48:34 +0100
Subject: [PATCH] OO-4567: search by owner in question pool

---
 .../qpool/manager/QItemQueriesDAO.java        | 17 +++++++++
 .../qpool/model/SearchQuestionItemParams.java | 12 +++++++
 .../qpool/ui/_i18n/LocalStrings_de.properties |  1 +
 .../qpool/ui/_i18n/LocalStrings_en.properties |  1 +
 .../ui/metadata/ExtendedSearchController.java |  5 ++-
 .../qpool/manager/QItemQueriesDAOTest.java    | 35 +++++++++++++++++++
 6 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/olat/modules/qpool/manager/QItemQueriesDAO.java b/src/main/java/org/olat/modules/qpool/manager/QItemQueriesDAO.java
index e0fa376ee41..da8ac85911e 100644
--- a/src/main/java/org/olat/modules/qpool/manager/QItemQueriesDAO.java
+++ b/src/main/java/org/olat/modules/qpool/manager/QItemQueriesDAO.java
@@ -300,6 +300,19 @@ public class QItemQueriesDAO {
 			sb.and();
 			PersistenceHelper.appendFuzzyLike(sb, "item.topic", "topic", dbInstance.getDbVendor());
 		}
+		if(StringHelper.containsNonWhitespace(params.getOwner())) {
+			sb.and()
+			  .append(" exists (select mship.key from ").append(SecurityGroupMembershipImpl.class.getName()).append(" as mship ")
+		      .append("  inner join mship.identity as oIdent")
+		      .append("  inner join oIdent.user as oUser")
+	          .append("  where mship.securityGroup.key=item.ownerGroup.key and (");
+			PersistenceHelper.appendFuzzyLike(sb, "oUser.firstName", "owner", dbInstance.getDbVendor());
+			sb.append(" or ");
+			PersistenceHelper.appendFuzzyLike(sb, "oUser.lastName", "owner", dbInstance.getDbVendor());
+			sb.append(" or ");
+			PersistenceHelper.appendFuzzyLike(sb, "oIdent.name", "owner", dbInstance.getDbVendor());
+			sb.append(" ))");
+		}
 		if(StringHelper.containsNonWhitespace(params.getKeywords())) {
 			sb.and();
 			PersistenceHelper.appendFuzzyLike(sb, "item.keywords", "keywords", dbInstance.getDbVendor());
@@ -427,6 +440,10 @@ public class QItemQueriesDAO {
 			String fuzzySearch = PersistenceHelper.makeFuzzyQueryString(params.getTopic());
 			query.setParameter("topic", fuzzySearch);
 		}
+		if(StringHelper.containsNonWhitespace(params.getOwner())) {
+			String fuzzySearch = PersistenceHelper.makeFuzzyQueryString(params.getOwner());
+			query.setParameter("owner", fuzzySearch);
+		}
 		if(StringHelper.containsNonWhitespace(params.getKeywords())) {
 			String fuzzySearch = PersistenceHelper.makeFuzzyQueryString(params.getKeywords());
 			query.setParameter("keywords", fuzzySearch);
diff --git a/src/main/java/org/olat/modules/qpool/model/SearchQuestionItemParams.java b/src/main/java/org/olat/modules/qpool/model/SearchQuestionItemParams.java
index 367c6eadea4..0f49b80eec6 100644
--- a/src/main/java/org/olat/modules/qpool/model/SearchQuestionItemParams.java
+++ b/src/main/java/org/olat/modules/qpool/model/SearchQuestionItemParams.java
@@ -48,6 +48,7 @@ public class SearchQuestionItemParams implements Cloneable {
 	private Identity author;
 	private String title;
 	private String topic;
+	private String owner;
 	private String keywords;
 	private String coverage;
 	private String informations;
@@ -146,6 +147,14 @@ public class SearchQuestionItemParams implements Cloneable {
 		this.topic = topic;
 	}
 
+	public String getOwner() {
+		return owner;
+	}
+
+	public void setOwner(String owner) {
+		this.owner = owner;
+	}
+
 	public String getKeywords() {
 		return keywords;
 	}
@@ -345,6 +354,9 @@ public class SearchQuestionItemParams implements Cloneable {
 		if(StringHelper.containsNonWhitespace(searchString)) {
 			clone.searchString = searchString;
 		}
+		if(StringHelper.containsNonWhitespace(owner)) {
+			clone.owner = owner;
+		}
 		if(favoritOnly) {
 			clone.favoritOnly = favoritOnly;
 		}
diff --git a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties
index 0960dec9316..1d3e2aa9a95 100644
--- a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties
@@ -200,6 +200,7 @@ my.share=Meine Shares
 new.item=Frage erstellen
 next=N\u00E4chste
 numberOfRatings=Anzahl Bewertungen
+owner=Autor
 pool.add.to.source=Fragen zum Pool "{0}" hinzuf\u00FCgen
 pool.key=ID
 pool.name=Name
diff --git a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_en.properties
index 11f9173265e..45017392462 100644
--- a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_en.properties
@@ -200,6 +200,7 @@ my.share=My shares
 new.item=Create question
 next=Next
 numberOfRatings=Number of ratings
+owner=Author
 pool.add.to.source=Add questions to pool "{0}"
 pool.key=ID
 pool.name=Name
diff --git a/src/main/java/org/olat/modules/qpool/ui/metadata/ExtendedSearchController.java b/src/main/java/org/olat/modules/qpool/ui/metadata/ExtendedSearchController.java
index 2ec0a4a4f6e..2b25b5efa67 100644
--- a/src/main/java/org/olat/modules/qpool/ui/metadata/ExtendedSearchController.java
+++ b/src/main/java/org/olat/modules/qpool/ui/metadata/ExtendedSearchController.java
@@ -334,6 +334,7 @@ public class ExtendedSearchController extends FormBasicController implements Ext
 				attributes.add(new SearchAttribute("classification.taxonomy.level", new TaxonomicFieldQueryParameter()));
 				attributes.add(new SearchAttribute("classification.taxonomic.path.incl", new TaxonomicPathQueryParameter()));
 			}
+			attributes.add(new SearchAttribute("owner", new StringQueryParameter(AbstractOlatDocument.AUTHOR_FIELD_NAME)));
 			//educational
 			if (qPoolSecurityCallback.canUseEducationalContext()) {
 				attributes.add(new SearchAttribute("educational.context", new ContextQueryParameter()));
@@ -400,6 +401,8 @@ public class ExtendedSearchController extends FormBasicController implements Ext
 					searchParams.setTopic(val);
 				} else if(QItemDocument.KEYWORDS_FIELD.equals(docAttribute)) {
 					searchParams.setKeywords(val);
+				} else if(AbstractOlatDocument.AUTHOR_FIELD_NAME.equals(docAttribute)) {
+					searchParams.setOwner(val);
 				} else if(QItemDocument.COVERAGE_FIELD.equals(docAttribute)) {
 					searchParams.setCoverage(val);
 				} else if(QItemDocument.ADD_INFOS_FIELD.equals(docAttribute)) {
@@ -461,7 +464,7 @@ public class ExtendedSearchController extends FormBasicController implements Ext
 		private final LicenseSelectionConfig config;
 		
 		public LicenseQueryParameter() {
-			super(QItemDocument.LICENSE_TYPE_FIELD_NAME);
+			super(AbstractOlatDocument.LICENSE_TYPE_FIELD_NAME);
 			config = LicenseUIFactory.createLicenseSelectionConfig(licenseHandler);
 		}
 		
diff --git a/src/test/java/org/olat/modules/qpool/manager/QItemQueriesDAOTest.java b/src/test/java/org/olat/modules/qpool/manager/QItemQueriesDAOTest.java
index d546edd606a..b76b547a238 100644
--- a/src/test/java/org/olat/modules/qpool/manager/QItemQueriesDAOTest.java
+++ b/src/test/java/org/olat/modules/qpool/manager/QItemQueriesDAOTest.java
@@ -327,6 +327,41 @@ public class QItemQueriesDAOTest extends OlatTestCase  {
 		}
 	}
 	
+	@Test
+	public void getItemsByOwner() {
+		//create an author with 2 items
+		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("QOwner-and-only-2-");
+		QuestionItem item = questionDao.createAndPersist(id, "NGC 7837", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, qItemType);
+		dbInstance.commitAndCloseSession();
+
+		SearchQuestionItemParams params = new SearchQuestionItemParams(id, null, Locale.ENGLISH);
+		params.setOwner("Owner-and-only");
+		
+		SortKey sortAsc = new SortKey(QuestionItemView.OrderBy.title.name(), true);
+		List<QuestionItemView> views = qItemQueriesDao.getItems(params, 0, -1, sortAsc);
+		Assert.assertNotNull(views);
+		Assert.assertFalse(views.isEmpty());	
+		boolean match = views.stream().anyMatch(view -> item.getKey().equals(view.getKey()));
+		Assert.assertTrue(match);
+	}
+	
+	@Test
+	public void getItemsByOwner_negativeTest() {
+		//create an author with 2 items
+		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("QOwn-29-");
+		QuestionItem item = questionDao.createAndPersist(id, "NGC 7838", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, qItemType);
+		dbInstance.commitAndCloseSession();
+		Assert.assertNotNull(item);
+
+		SearchQuestionItemParams params = new SearchQuestionItemParams(id, null, Locale.ENGLISH);
+		params.setOwner(UUID.randomUUID().toString());
+		
+		SortKey sortAsc = new SortKey(QuestionItemView.OrderBy.title.name(), true);
+		List<QuestionItemView> views = qItemQueriesDao.getItems(params, 0, -1, sortAsc);
+		Assert.assertNotNull(views);
+		Assert.assertTrue(views.isEmpty());
+	}
+	
 	@Test
 	public void getItemsOfPool() {
 		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("Poolman-");
-- 
GitLab