/** * <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.qpool.manager; import java.math.BigDecimal; import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.UUID; import org.junit.Assert; import org.junit.Test; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.services.mark.MarkManager; import org.olat.core.id.Identity; import org.olat.group.BusinessGroup; import org.olat.group.manager.BusinessGroupDAO; import org.olat.ims.qti.QTIConstants; import org.olat.ims.qti21.QTI21Constants; import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionItem2Resource; import org.olat.modules.qpool.QuestionItemFull; import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.QuestionItemView; import org.olat.modules.qpool.QuestionStatus; import org.olat.modules.qpool.QuestionType; import org.olat.modules.qpool.TaxonomyLevel; import org.olat.modules.qpool.model.QEducationalContext; import org.olat.modules.qpool.model.QItemType; import org.olat.modules.qpool.model.QLicense; import org.olat.modules.qpool.model.QuestionItemImpl; import org.olat.resource.OLATResource; import org.olat.test.JunitTestHelper; import org.olat.test.OlatTestCase; import org.springframework.beans.factory.annotation.Autowired; /** * * Initial date: 21.01.2013<br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ public class QuestionDAOTest extends OlatTestCase { @Autowired private DB dbInstance; @Autowired private BusinessGroupDAO businessGroupDao; @Autowired private QuestionItemDAO questionDao; @Autowired private MarkManager markManager; @Autowired private QItemTypeDAO qItemTypeDao; @Autowired private QLicenseDAO qLicenseDao; @Autowired private QItemQueriesDAO qItemQueriesDao; @Autowired private QEducationalContextDAO qEduContextDao; @Autowired private TaxonomyLevelDAO taxonomyLevelDao; @Test public void createQuestion() { QItemType fibType = qItemTypeDao.loadByType(QuestionType.FIB.name()); QuestionItem item = questionDao.createAndPersist(null, "Stars", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, fibType); Assert.assertNotNull(item); Assert.assertNotNull(item.getKey()); Assert.assertNotNull(item.getIdentifier()); Assert.assertNotNull(item.getCreationDate()); Assert.assertNotNull(item.getLastModified()); Assert.assertNotNull(item.getType()); Assert.assertNotNull(item.getQuestionStatus()); Assert.assertEquals("Stars", item.getTitle()); dbInstance.commitAndCloseSession(); } @Test public void createQuestion_withOwner() { QItemType fibType = qItemTypeDao.loadByType(QuestionType.FIB.name()); Identity id = JunitTestHelper.createAndPersistIdentityAsUser("QOwn-1-" + UUID.randomUUID().toString()); QuestionItem item = questionDao.createAndPersist(id, "My fav. stars", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, fibType); Assert.assertNotNull(item); Assert.assertNotNull(item.getKey()); Assert.assertNotNull(item.getCreationDate()); Assert.assertNotNull(item.getLastModified()); Assert.assertNotNull(item.getType()); Assert.assertNotNull(item.getQuestionStatus()); Assert.assertEquals("My fav. stars", item.getTitle()); dbInstance.commitAndCloseSession(); } @Test public void copyQuestion() { // create an item and fill it TaxonomyLevel taxonomyLevel = taxonomyLevelDao.createAndPersist(null, "Tax. to copy"); QEducationalContext eduContext = qEduContextDao.create("primary.school", true); QLicense mitLicense = qLicenseDao.create("mit-" + UUID.randomUUID().toString(), null, true); QItemType fibType = qItemTypeDao.loadByType(QuestionType.FIB.name()); QItemType essayType = qItemTypeDao.loadByType(QuestionType.ESSAY.name()); Identity author = JunitTestHelper.createAndPersistIdentityAsUser("QClone-1-" + UUID.randomUUID().toString()); Identity cloner = JunitTestHelper.createAndPersistIdentityAsUser("QClone-2-" + UUID.randomUUID().toString()); QuestionItemImpl original = questionDao.createAndPersist(author, "To copy", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), taxonomyLevel, null, "root.xml", fibType); dbInstance.commit(); Assert.assertNotNull(original); Assert.assertNotNull(original.getIdentifier()); Assert.assertNull(original.getMasterIdentifier()); //general original.setTitle("Original"); original.setDescription("Original description"); original.setKeywords("original copy to"); original.setCoverage("New coverage"); original.setAdditionalInformations("Additional informations before copy"); original.setLanguage("en"); //educational original.setEducationalContext(eduContext); original.setEducationalLearningTime("PT1H30M"); //question original.setType(essayType); original.setDifficulty(new BigDecimal("0.1")); original.setStdevDifficulty(new BigDecimal("0.2")); original.setDifferentiation(new BigDecimal("-0.5")); original.setNumOfAnswerAlternatives(4); original.setUsage(5); original.setAssessmentType("formative"); //lifecycle original.setItemVersion("1.0"); original.setStatus(QuestionStatus.review.name()); //rights original.setLicense(mitLicense); //technical original.setEditor("OpenOLAT"); original.setEditorVersion("9.0a"); original = questionDao.merge(original); dbInstance.commitAndCloseSession(); //clone it QuestionItemImpl clone = questionDao.copy(original); questionDao.persist(cloner, clone); //compare Assert.assertEquals(1, questionDao.countItems(cloner)); //general Assert.assertNotNull(clone.getIdentifier()); Assert.assertFalse(clone.getIdentifier().equals(original.getIdentifier())); Assert.assertEquals(original.getIdentifier(), clone.getMasterIdentifier()); Assert.assertNotNull(clone.getTitle()); Assert.assertFalse(clone.getTitle().equals(original.getTitle())); Assert.assertEquals(original.getDescription(), clone.getDescription()); Assert.assertEquals(original.getKeywords(), clone.getKeywords()); Assert.assertEquals(original.getCoverage(), clone.getCoverage()); Assert.assertEquals(original.getAdditionalInformations(), clone.getAdditionalInformations()); Assert.assertEquals(original.getLanguage(), clone.getLanguage()); //classification Assert.assertEquals(original.getTaxonomyLevelName(), clone.getTaxonomyLevelName()); //educational Assert.assertEquals(original.getEducationalContext(), clone.getEducationalContext()); Assert.assertEquals(original.getEducationalLearningTime(), clone.getEducationalLearningTime()); //question Assert.assertEquals(original.getType(), clone.getType()); Assert.assertNotNull(clone.getDifficulty()); Assert.assertEquals(original.getDifficulty().doubleValue(), clone.getDifficulty().doubleValue(), 0.000001); Assert.assertNotNull(clone.getStdevDifficulty()); Assert.assertEquals(original.getStdevDifficulty().doubleValue(), clone.getStdevDifficulty().doubleValue(), 0.000001); Assert.assertNotNull(clone.getDifferentiation()); Assert.assertEquals(original.getDifferentiation().doubleValue(), clone.getDifferentiation().doubleValue(), 0.000001); Assert.assertEquals(original.getNumOfAnswerAlternatives(), clone.getNumOfAnswerAlternatives()); Assert.assertEquals(0, clone.getUsage()); Assert.assertEquals(original.getAssessmentType(), clone.getAssessmentType()); //lifecycle Assert.assertEquals(QuestionStatus.draft.name(), clone.getStatus()); Assert.assertEquals(original.getItemVersion(), clone.getItemVersion()); //rights Assert.assertEquals(original.getLicense(), clone.getLicense()); //technical Assert.assertEquals(original.getEditor(), clone.getEditor()); Assert.assertEquals(original.getEditorVersion(), clone.getEditorVersion()); Assert.assertEquals(original.getFormat(), clone.getFormat()); Assert.assertNotNull(clone.getCreationDate()); Assert.assertNotNull(clone.getLastModified()); } @Test public void getItems_all() { //create an author with 2 items QItemType fibType = qItemTypeDao.loadByType(QuestionType.FIB.name()); Identity id = JunitTestHelper.createAndPersistIdentityAsUser("QOwn-all-" + UUID.randomUUID().toString()); QuestionItem item = questionDao.createAndPersist(id, "NGC all", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, fibType); dbInstance.commitAndCloseSession(); //retrieve all items List<QuestionItemFull> items = questionDao.getAllItems(0, -1); Assert.assertNotNull(items); Assert.assertTrue(items.size() >= 1); Assert.assertTrue(items.contains(item)); } @Test public void getNumOfQuestions() { QItemType mcType = qItemTypeDao.loadByType(QuestionType.MC.name()); QuestionItem item = questionDao.createAndPersist(null, "NGC 1277", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, mcType); Assert.assertNotNull(item); dbInstance.commitAndCloseSession(); int numOfQuestions = questionDao.getNumOfQuestions(); Assert.assertTrue(numOfQuestions >= 1); dbInstance.commitAndCloseSession(); } @Test public void getFavoritItemKeys() { QItemType mcType = qItemTypeDao.loadByType(QuestionType.MC.name()); Identity id = JunitTestHelper.createAndPersistIdentityAsUser("fav-item-" + UUID.randomUUID().toString()); QuestionItem item1 = questionDao.createAndPersist(id, "NGC 331", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, mcType); QuestionItem item2 = questionDao.createAndPersist(id, "NGC 332", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, mcType); QuestionItem item3 = questionDao.createAndPersist(id, "NGC 333", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, mcType); markManager.setMark(item1, id, null, "[QuestionItem:" + item1.getKey() + "]"); markManager.setMark(item2, id, null, "[QuestionItem:" + item2.getKey() + "]"); dbInstance.commitAndCloseSession(); List<Long> favoritKeys = questionDao.getFavoritKeys(id); Assert.assertNotNull(favoritKeys); Assert.assertEquals(2, favoritKeys.size()); Assert.assertTrue(favoritKeys.contains(item1.getKey())); Assert.assertTrue(favoritKeys.contains(item2.getKey())); Assert.assertFalse(favoritKeys.contains(item3.getKey())); } @Test public void shareItems_countSharedItemByResource() { //create a group to share 2 items QItemType mcType = qItemTypeDao.loadByType(QuestionType.MC.name()); QItemType fibType = qItemTypeDao.loadByType(QuestionType.FIB.name()); BusinessGroup group = businessGroupDao.createAndPersist(null, "gdao", "gdao-desc", -1, -1, false, false, false, false, false); QuestionItem item1 = questionDao.createAndPersist(null, "Count-shared-Item-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, mcType); QuestionItem item2 = questionDao.createAndPersist(null, "Count-shared-Item-2", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, mcType); QuestionItem item3 = questionDao.createAndPersist(null, "Count-shared-Item-3", QTIConstants.QTI_12_FORMAT, Locale.FRENCH.getLanguage(), null, null, null, fibType); dbInstance.commit(); //share them questionDao.share(item1, group.getResource()); questionDao.share(item2, group.getResource()); questionDao.share(item3, group.getResource()); dbInstance.commitAndCloseSession(); //retrieve them int sharedItems = questionDao.countSharedItemByResource(group.getResource(), null); Assert.assertEquals(3, sharedItems); } @Test public void shareItems_countSharedItemByResource_format() { //create a group to share 2 items QItemType mcType = qItemTypeDao.loadByType(QuestionType.MC.name()); QItemType fibType = qItemTypeDao.loadByType(QuestionType.FIB.name()); BusinessGroup group = businessGroupDao.createAndPersist(null, "gdao", "gdao-desc", -1, -1, false, false, false, false, false); QuestionItem item1 = questionDao.createAndPersist(null, "Count-shared-Item-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, mcType); QuestionItem item2 = questionDao.createAndPersist(null, "Count-shared-Item-2", QTI21Constants.QTI_21_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, mcType); QuestionItem item3 = questionDao.createAndPersist(null, "Count-shared-Item-3", QTIConstants.QTI_12_FORMAT, Locale.FRENCH.getLanguage(), null, null, null, fibType); dbInstance.commit(); //share them questionDao.share(item1, group.getResource()); questionDao.share(item2, group.getResource()); questionDao.share(item3, group.getResource()); dbInstance.commitAndCloseSession(); //retrieve them int sharedItems = questionDao.countSharedItemByResource(group.getResource(), QTI21Constants.QTI_21_FORMAT); Assert.assertEquals(1, sharedItems); } @Test public void shareItems_avoidDuplicates() { //create a group to share 2 items QItemType mcType = qItemTypeDao.loadByType(QuestionType.MC.name()); Identity id = JunitTestHelper.createAndPersistIdentityAsUser("QShare-3-" + UUID.randomUUID()); BusinessGroup group = businessGroupDao.createAndPersist(id, "gdao", "gdao-desc", -1, -1, false, false, false, false, false); QuestionItem item = questionDao.createAndPersist(id, "Share-Item-Dup-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, mcType); dbInstance.commit(); //share them questionDao.share(item, group.getResource()); questionDao.share(item, group.getResource()); questionDao.share(item, group.getResource()); //retrieve them List<QuestionItemView> sharedItems = qItemQueriesDao.getSharedItemByResource(id, group.getResource(), null, null, 0, -1); Assert.assertNotNull(sharedItems); Assert.assertEquals(1, sharedItems.size()); Assert.assertEquals(item.getKey(), sharedItems.get(0).getKey()); } @Test public void shareItems_businessGroups() { //create a group to share 2 items QItemType mcType = qItemTypeDao.loadByType(QuestionType.MC.name()); Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Share-item-" + UUID.randomUUID().toString()); BusinessGroup group = businessGroupDao.createAndPersist(id, "gdao", "gdao-desc", -1, -1, false, false, false, false, false); QuestionItem item = questionDao.createAndPersist(id, "Share-Item-Dup-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, mcType); dbInstance.commit(); //share them questionDao.share(item, group.getResource()); questionDao.share(item, group.getResource()); questionDao.share(item, group.getResource()); //retrieve them List<BusinessGroup> shared = questionDao.getResourcesWithSharedItems(id); Assert.assertNotNull(shared); Assert.assertEquals(1, shared.size()); Assert.assertTrue(shared.contains(group)); } @Test public void shareInfos_byItems() { //create a group to share 2 items QItemType mcType = qItemTypeDao.loadByType(QuestionType.MC.name()); Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Share-item-" + UUID.randomUUID().toString()); BusinessGroup group1 = businessGroupDao.createAndPersist(id, "gdap", "gdao-desc", -1, -1, false, false, false, false, false); BusinessGroup group2 = businessGroupDao.createAndPersist(id, "gdaq", "gdao-desc", -1, -1, false, false, false, false, false); QuestionItem item = questionDao.createAndPersist(id, "Share-Item-Dup-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, mcType); questionDao.share(item, group1.getResource()); questionDao.share(item, group2.getResource()); dbInstance.commit(); //retrieve them List<QuestionItem2Resource> shared = questionDao.getSharedResourceInfos(item); Assert.assertNotNull(shared); Assert.assertEquals(2, shared.size()); } @Test public void shareItems_removeFromBusinessGroups() { //create a group to share 2 items QItemType mcType = qItemTypeDao.loadByType(QuestionType.MC.name()); Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Share-item-" + UUID.randomUUID().toString()); BusinessGroup group = businessGroupDao.createAndPersist(id, "gdao", "gdao-desc", -1, -1, false, false, false, false, false); QuestionItem item = questionDao.createAndPersist(id, "Share-Item-Dup-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, mcType); questionDao.share(item, group.getResource()); dbInstance.commit(); //check them List<QuestionItemView> shared = qItemQueriesDao.getSharedItemByResource(id, group.getResource(), null, null, 0, -1); Assert.assertNotNull(shared); Assert.assertEquals(1, shared.size()); //remove questionDao.removeFromShare(Collections.<QuestionItemShort>singletonList(item), group.getResource()); dbInstance.commitAndCloseSession(); //check int numOfStayingItems = questionDao.countSharedItemByResource(group.getResource(), null); Assert.assertEquals(0, numOfStayingItems); } @Test public void shareItems_removeFromBusinessGroups_paranoid() { //create a group to share 2 items QItemType mcType = qItemTypeDao.loadByType(QuestionType.MC.name()); Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Share-item-" + UUID.randomUUID().toString()); BusinessGroup group1 = businessGroupDao.createAndPersist(id, "gdao-b", "gdao-desc", -1, -1, false, false, false, false, false); BusinessGroup group2 = businessGroupDao.createAndPersist(id, "gdao-c", "gdao-desc", -1, -1, false, false, false, false, false); QuestionItem item1 = questionDao.createAndPersist(id, "Share-Item-Dup-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, mcType); QuestionItem item2 = questionDao.createAndPersist(id, "Share-Item-Dup-1", QTI21Constants.QTI_21_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, mcType); questionDao.share(item1, group1.getResource()); questionDao.share(item1, group2.getResource()); questionDao.share(item2, group1.getResource()); questionDao.share(item2, group2.getResource()); dbInstance.commit(); //check them int numOfItems_1 = questionDao.countSharedItemByResource(group1.getResource(), null); Assert.assertEquals(2, numOfItems_1); int numOfItems_2 = questionDao.countSharedItemByResource(group2.getResource(), null); Assert.assertEquals(2, numOfItems_2); //remove questionDao.removeFromShare(Collections.<QuestionItemShort>singletonList(item2), group1.getResource()); dbInstance.commitAndCloseSession(); //check int numOfStayingItems_1 = questionDao.countSharedItemByResource(group1.getResource(), null); Assert.assertEquals(1, numOfStayingItems_1); int numOfStayingItems_2 = questionDao.countSharedItemByResource(group2.getResource(), null); Assert.assertEquals(2, numOfStayingItems_2); List<QuestionItemView> items_1 = qItemQueriesDao.getSharedItemByResource(id, group1.getResource(), null, null, 0, -1); Assert.assertEquals(1, items_1.size()); Assert.assertEquals(item1.getKey(), items_1.get(0).getKey()); } @Test public void getSharedResources() { //create a group to share 2 items QItemType mcType = qItemTypeDao.loadByType(QuestionType.MC.name()); Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Share-item-" + UUID.randomUUID().toString()); BusinessGroup group1 = businessGroupDao.createAndPersist(id, "gdao", "gdao-desc", -1, -1, false, false, false, false, false); BusinessGroup group2 = businessGroupDao.createAndPersist(id, "gdao", "gdao-desc", -1, -1, false, false, false, false, false); QuestionItem item = questionDao.createAndPersist(id, "Share-Item-Dup-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, mcType); dbInstance.commit(); //share them questionDao.share(item, group1.getResource()); questionDao.share(item, group2.getResource()); dbInstance.commitAndCloseSession(); //retrieve them List<OLATResource> shared = questionDao.getSharedResources(item); Assert.assertNotNull(shared); Assert.assertEquals(2, shared.size()); Assert.assertTrue(shared.contains(group1.getResource())); Assert.assertTrue(shared.contains(group2.getResource())); } @Test public void removeFromShare() { //create a group to share 2 items QItemType mcType = qItemTypeDao.loadByType(QuestionType.MC.name()); Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Share-rm-" + UUID.randomUUID().toString()); BusinessGroup group = businessGroupDao.createAndPersist(id, "gdrm", "gdrm-desc", -1, -1, false, false, false, false, false); QuestionItem item = questionDao.createAndPersist(id, "Share-item-rm-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, mcType); dbInstance.commit(); //share them questionDao.share(item, group.getResource()); //retrieve them as a check List<QuestionItemView> shared = qItemQueriesDao.getSharedItemByResource(id, group.getResource(), null, null, 0, -1); Assert.assertEquals(1, shared.size()); //and remove the items List<QuestionItemShort> toDelete = Collections.<QuestionItemShort>singletonList(shared.get(0)); int count = questionDao.removeFromShares(toDelete); Assert.assertEquals(1, count); dbInstance.commit();//make sure that changes are committed } }