diff --git a/src/main/java/org/olat/admin/user/delete/ConfirmDeleteUserController.java b/src/main/java/org/olat/admin/user/delete/ConfirmDeleteUserController.java index 4e6130bee4fb56a866accfeacbe5ebfd940aee20..33bffffcc4daf39de5df26155623ebc5b6e714e0 100644 --- a/src/main/java/org/olat/admin/user/delete/ConfirmDeleteUserController.java +++ b/src/main/java/org/olat/admin/user/delete/ConfirmDeleteUserController.java @@ -78,11 +78,13 @@ public class ConfirmDeleteUserController extends FormBasicController { String[] confirmValues = new String[] { translate("readyToDelete.delete.confirm.check") }; confirmEl = uifactory.addCheckboxesHorizontal("readyToDelete.delete.confirm.check.label", layoutCont, confirmKeys, confirmValues); + confirmEl.setElementCssClass("o_sel_confirm_delete_user"); FormLayoutContainer buttonsCont = FormLayoutContainer.createButtonLayout("buttons", getTranslator()); layoutCont.add(buttonsCont); uifactory.addFormCancelButton("cancel", buttonsCont, ureq, getWindowControl()); deleteButton = uifactory.addFormLink("delete", buttonsCont, Link.BUTTON); + deleteButton.setElementCssClass("o_sel_delete_user"); } } diff --git a/src/main/java/org/olat/core/commons/services/commentAndRating/CommentAndRatingService.java b/src/main/java/org/olat/core/commons/services/commentAndRating/CommentAndRatingService.java index 1d25a38199d7500ee78b3597832d2cbcbb3df126..aa058036e44f9ced6a007dc812374c362ac12b59 100644 --- a/src/main/java/org/olat/core/commons/services/commentAndRating/CommentAndRatingService.java +++ b/src/main/java/org/olat/core/commons/services/commentAndRating/CommentAndRatingService.java @@ -117,14 +117,6 @@ public interface CommentAndRatingService { * in the meantime and could not be updated at all. */ public UserRating updateRating(UserRating rating, int newRatingValue); - - /** - * Delete a rating - * - * @param rating - * @param int number of deleted ratings - */ - public abstract int deleteRating(UserRating rating); /** * Return the most rated resources diff --git a/src/main/java/org/olat/core/commons/services/commentAndRating/manager/CommentAndRatingServiceImpl.java b/src/main/java/org/olat/core/commons/services/commentAndRating/manager/CommentAndRatingServiceImpl.java index 8a12a5ab300b2b2301053d16809695177c481c28..7632019edb79fb6b949cf373faa08791e4526944 100644 --- a/src/main/java/org/olat/core/commons/services/commentAndRating/manager/CommentAndRatingServiceImpl.java +++ b/src/main/java/org/olat/core/commons/services/commentAndRating/manager/CommentAndRatingServiceImpl.java @@ -20,6 +20,7 @@ package org.olat.core.commons.services.commentAndRating.manager; +import java.io.File; import java.util.List; import org.olat.core.commons.services.commentAndRating.CommentAndRatingService; @@ -31,6 +32,9 @@ import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.core.logging.AssertException; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; +import org.olat.user.UserDataDeletable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -46,7 +50,9 @@ import org.springframework.stereotype.Service; * @author gnaegi */ @Service -public class CommentAndRatingServiceImpl implements CommentAndRatingService { +public class CommentAndRatingServiceImpl implements CommentAndRatingService, UserDataDeletable { + + private static final OLog log = Tracing.createLoggerFor(CommentAndRatingServiceImpl.class); @Autowired private UserRatingsDAO userRatingsDao; @@ -58,7 +64,7 @@ public class CommentAndRatingServiceImpl implements CommentAndRatingService { @Override public Long countRatings(OLATResourceable ores, String resSubPath) { - return new Long(userRatingsDao.countRatings(ores, resSubPath)); + return Long.valueOf(userRatingsDao.countRatings(ores, resSubPath)); } @Override @@ -96,11 +102,6 @@ public class CommentAndRatingServiceImpl implements CommentAndRatingService { return userRatingsDao.updateRating(rating, newRatingValue); } - @Override - public int deleteRating(UserRating rating) { - return userRatingsDao.deleteRating(rating); - } - @Override public List<OLATResourceableRating> getMostRatedResourceables(OLATResourceable ores, int maxResults) { return userRatingsDao.getMostRatedResourceables(ores, maxResults); @@ -153,9 +154,6 @@ public class CommentAndRatingServiceImpl implements CommentAndRatingService { return userCommentsDao.deleteComment(comment, deleteReplies); } - /** - * @see org.olat.core.commons.services.commentAndRating.CommentAndRatingService#deleteAll() - */ @Override public int deleteAll(OLATResourceable ores, String resSubPath) { if (ores == null) { @@ -166,10 +164,6 @@ public class CommentAndRatingServiceImpl implements CommentAndRatingService { return delCount; } - /** - * - * @see org.olat.core.commons.services.commentAndRating.CommentAndRatingService#deleteAllIgnoringSubPath() - */ @Override public int deleteAllIgnoringSubPath(OLATResourceable ores) { if (ores == null) { @@ -180,6 +174,14 @@ public class CommentAndRatingServiceImpl implements CommentAndRatingService { return delCount; } + @Override + public void deleteUserData(Identity identity, String newDeletedUserName, File archivePath) { + int rows = userRatingsDao.deleteRatings(identity); + log.audit(rows + " rating deleted"); + int comments = userCommentsDao.deleteAllComments(identity); + log.audit(comments + " rating erased"); + } + private void markPublisherNews(UserComment comment) { if (comment == null) return; diff --git a/src/main/java/org/olat/core/commons/services/commentAndRating/manager/UserCommentsDAO.java b/src/main/java/org/olat/core/commons/services/commentAndRating/manager/UserCommentsDAO.java index 601e3ab27a707c08e146ffbe3e3b10d40f4fc715..80d50d90d91b29b555764c6d4851ded622f3a3a6 100644 --- a/src/main/java/org/olat/core/commons/services/commentAndRating/manager/UserCommentsDAO.java +++ b/src/main/java/org/olat/core/commons/services/commentAndRating/manager/UserCommentsDAO.java @@ -28,6 +28,7 @@ import java.util.Set; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; +import org.olat.basesecurity.IdentityRef; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.DBFactory; import org.olat.core.commons.services.commentAndRating.CommentAndRatingLoggingAction; @@ -38,8 +39,6 @@ import org.olat.core.commons.services.commentAndRating.model.UserCommentsCount; import org.olat.core.commons.services.commentAndRating.model.UserCommentsCountImpl; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; -import org.olat.core.logging.OLog; -import org.olat.core.logging.Tracing; import org.olat.core.logging.activity.CoreLoggingResourceable; import org.olat.core.logging.activity.OlatResourceableType; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; @@ -55,10 +54,7 @@ import org.springframework.stereotype.Service; */ @Service("userCommentsDAO") public class UserCommentsDAO { - - private static final OLog log = Tracing.createLoggerFor(UserCommentsDAO.class); - - + @Autowired private DB dbInstance; @@ -72,7 +68,7 @@ public class UserCommentsDAO { public UserComment createComment(Identity creator, OLATResourceable ores, String resSubPath, String commentText) { UserComment comment = new UserCommentImpl(ores, resSubPath, creator, commentText); dbInstance.getCurrentEntityManager().persist(comment); - updateDelegateRatings(ores, resSubPath); + updateDelegateRatings(ores, resSubPath, true); // do Logging ThreadLocalUserActivityLogger.log(CommentAndRatingLoggingAction.COMMENT_CREATED, getClass(), @@ -81,19 +77,12 @@ public class UserCommentsDAO { } public UserComment reloadComment(UserComment comment) { - try { - String q = "select comment from usercomment as comment where comment.key=:commentKey"; - List<UserComment> comments = dbInstance.getCurrentEntityManager() - .createQuery(q, UserComment.class) - .setParameter("commentKey", comment.getKey()) - .getResultList(); - return comments.isEmpty() ? null : comments.get(0); - } catch (Exception e) { - // Huh, most likely the given object does not exist anymore on the - // db, probably deleted by someone else - log.warn("Tried to reload a user comment but got an exception. Probably deleted in the meantime", e); - return null; - } + String q = "select comment from usercomment as comment where comment.key=:commentKey"; + List<UserComment> comments = dbInstance.getCurrentEntityManager() + .createQuery(q, UserComment.class) + .setParameter("commentKey", comment.getKey()) + .getResultList(); + return comments.isEmpty() ? null : comments.get(0); } public UserComment replyTo(UserComment originalComment, Identity creator, String replyCommentText) { @@ -107,7 +96,7 @@ public class UserCommentsDAO { UserCommentImpl reply = new UserCommentImpl(ores, originalComment.getResSubPath(), creator, replyCommentText); reply.setParent(originalComment); dbInstance.getCurrentEntityManager().persist(reply); - updateDelegateRatings(ores, originalComment.getResSubPath()); + updateDelegateRatings(ores, originalComment.getResSubPath(), true); return reply; } @@ -172,7 +161,7 @@ public class UserCommentsDAO { dbInstance.getCurrentEntityManager().remove(comment); // do Logging OLATResourceable ores = OresHelper.createOLATResourceableInstance(comment.getResName(), comment.getResId()); - updateDelegateRatings(ores, comment.getResSubPath()); + updateDelegateRatings(ores, comment.getResSubPath(), true); ThreadLocalUserActivityLogger.log(CommentAndRatingLoggingAction.COMMENT_DELETED, getClass(), CoreLoggingResourceable.wrap(ores, OlatResourceableType.feedItem)); return counter+1; @@ -195,8 +184,8 @@ public class UserCommentsDAO { .setParameter("resId", ores.getResourceableId()) .getResultList(); - Set<String> countMap = new HashSet<String>(); - List<UserCommentsCount> countList = new ArrayList<UserCommentsCount>(); + Set<String> countMap = new HashSet<>(); + List<UserCommentsCount> countList = new ArrayList<>(); for(Object[] count:counts) { Object subPath = count[0] == null ? "" : count[0]; if(!countMap.contains(subPath)) { @@ -223,9 +212,50 @@ public class UserCommentsDAO { .getSingleResult().longValue(); } - /** - * @see org.olat.core.commons.services.commentAndRating.UserCommentsManager#deleteAllComments() - */ + public int deleteAllComments(IdentityRef identity) { + Set<Long> commentWithReplyKeys = getCommentKeysWithReply(identity); + + String query = "select comment.key from usercomment comment where comment.creator.key=:creatorKey"; + List<Long> commentKeys = dbInstance.getCurrentEntityManager() + .createQuery(query, Long.class) + .setParameter("creatorKey", identity.getKey()) + .getResultList(); + + int count = 0; + for(Long commentKey:commentKeys) { + UserComment comment = dbInstance.getCurrentEntityManager() + .getReference(UserCommentImpl.class, commentKey); + if(commentWithReplyKeys.contains(commentKey)) { + comment.setComment("User has been deleted"); + dbInstance.getCurrentEntityManager().merge(comment); + } else { + dbInstance.getCurrentEntityManager().remove(comment); + } + + if(count++ % 25 == 0) { + dbInstance.commitAndCloseSession(); + } else { + dbInstance.commit(); + } + + OLATResourceable ores = OresHelper.createOLATResourceableInstance(comment.getResName(), comment.getResId()); + updateDelegateRatings(ores, comment.getResSubPath(), false); + } + return commentKeys.size(); + } + + private Set<Long> getCommentKeysWithReply(IdentityRef identity) { + StringBuilder sb = new StringBuilder(); + sb.append("select comment.key from usercomment as comment") + .append(" inner join usercomment as reply on (comment.key=reply.parent.key)") + .append(" where comment.creator.key=:creatorKey"); + List<Long> commentWithReplyKeyList = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Long.class) + .setParameter("creatorKey", identity.getKey()) + .getResultList(); + return new HashSet<>(commentWithReplyKeyList); + } + public int deleteAllComments(OLATResourceable ores, String resSubPath) { EntityManager em = dbInstance.getCurrentEntityManager(); // special query when sub path is null @@ -258,7 +288,7 @@ public class UserCommentsDAO { em.remove(comment); } } - updateDelegateRatings(ores, resSubPath); + updateDelegateRatings(ores, resSubPath, false); return comments == null ? 0 : comments.size(); } @@ -280,11 +310,11 @@ public class UserCommentsDAO { for(UserCommentImpl comment:comments) { em.remove(comment); } - updateDelegateRatings(ores, null); + updateDelegateRatings(ores, null, false); return comments.size(); } - private void updateDelegateRatings(OLATResourceable ores, String resSubPath) { + private void updateDelegateRatings(OLATResourceable ores, String resSubPath, boolean newRating) { if(delegates == null || delegates.isEmpty()) return; for(UserCommentsDelegate delegate:delegates) { @@ -308,7 +338,8 @@ public class UserCommentsDAO { Number count = query.getSingleResult(); if(count == null) { - delegate.update(ores, resSubPath, 1); + int val = newRating ? 1 : 0; + delegate.update(ores, resSubPath, val); } else { delegate.update(ores, resSubPath, count.intValue()); } diff --git a/src/main/java/org/olat/core/commons/services/commentAndRating/manager/UserRatingsDAO.java b/src/main/java/org/olat/core/commons/services/commentAndRating/manager/UserRatingsDAO.java index 9d679398739cc7133140f3b87269caec8e8c5ed5..eb265ee4e36f79705037db35c962486430c25bb8 100644 --- a/src/main/java/org/olat/core/commons/services/commentAndRating/manager/UserRatingsDAO.java +++ b/src/main/java/org/olat/core/commons/services/commentAndRating/manager/UserRatingsDAO.java @@ -25,6 +25,7 @@ import java.util.List; import javax.persistence.TypedQuery; +import org.olat.basesecurity.IdentityRef; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.services.commentAndRating.UserRatingsDelegate; import org.olat.core.commons.services.commentAndRating.model.OLATResourceableRating; @@ -32,8 +33,6 @@ import org.olat.core.commons.services.commentAndRating.model.UserRating; import org.olat.core.commons.services.commentAndRating.model.UserRatingImpl; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; -import org.olat.core.logging.OLog; -import org.olat.core.logging.Tracing; import org.olat.core.util.resource.OresHelper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -46,9 +45,7 @@ import org.springframework.stereotype.Service; */ @Service("userRatingsDAO") public class UserRatingsDAO { - - private static final OLog log = Tracing.createLoggerFor(UserRatingsDAO.class); - + @Autowired private DB dbInstance; @@ -129,8 +126,7 @@ public class UserRatingsDAO { query.setMaxResults(maxResults); } - List<OLATResourceableRating> mostRated = query.getResultList(); - return mostRated; + return query.getResultList(); } public int countRatings(OLATResourceable ores, String resSubPath) { @@ -227,14 +223,12 @@ public class UserRatingsDAO { } public UserRating reloadRating(UserRating rating) { - try { - return (UserRating)dbInstance.loadObject(rating); - } catch (Exception e) { - // Huh, most likely the given object does not exist anymore on the - // db, probably deleted by someone else - log.warn("Tried to reload a user rating but got an exception. Probably deleted in the meantime", e); - return null; - } + String query = "select r from userrating as r where r.key=:ratingKey"; + List<UserRating> ratings = dbInstance.getCurrentEntityManager() + .createQuery(query, UserRating.class) + .setParameter("ratingKey", rating.getKey()) + .getResultList(); + return ratings != null && !ratings.isEmpty() ? ratings.get(0) : null; } private void updateDelegateRatings(UserRating rating) { @@ -273,24 +267,63 @@ public class UserRatingsDAO { } else { long numOfRatings = ((Number)stats[0]).longValue(); long sumOfRatings = ((Number)stats[1]).longValue(); - double rate = (sumOfRatings + rating.getRating().intValue()) / (numOfRatings + 1); + double rate = (sumOfRatings + rating.getRating().intValue()) / (numOfRatings + 1.0d); delegate.update(ores, rating.getResSubPath(), rate, numOfRatings + 1); } } } } - - public int deleteRating(UserRating rating) { - // First reload parent from cache to prevent stale object or cache issues - UserRating ratingRef = dbInstance.getCurrentEntityManager().getReference(UserRatingImpl.class, rating.getKey()); - if (ratingRef == null) { - // Original rating has been deleted in the meantime. Don't delete it again. - return 0; + + public int deleteRatings(IdentityRef identity) { + String query = "select r from userrating as r where r.creator.key=:creatorKey"; + List<UserRating> ratings = dbInstance.getCurrentEntityManager() + .createQuery(query, UserRating.class) + .setParameter("creatorKey", identity.getKey()) + .getResultList(); + + for(UserRating rating:ratings) { + dbInstance.getCurrentEntityManager().remove(rating); + dbInstance.commit(); + OLATResourceable ores = OresHelper.createOLATResourceableInstance(rating.getResName(), rating.getResId()); + recalculateDelegateRatings(ores, rating.getResSubPath()); } - // Delete this rating and finish - dbInstance.getCurrentEntityManager().remove(ratingRef); - return 1; + return ratings.size(); + } + + private void recalculateDelegateRatings(OLATResourceable ores, String resSubPath) { + if(delegates == null || delegates.isEmpty()) return; + + for(UserRatingsDelegate delegate:delegates) { + if(delegate.accept(ores, resSubPath)) { + StringBuilder sb = new StringBuilder(); + sb.append("select count(rating.key), sum(rating.rating) from userrating as rating") + .append(" where rating.resName=:resname and rating.resId=:resId"); + if(resSubPath == null) { + sb.append(" and rating.resSubPath is null"); + } else { + sb.append(" and rating.resSubPath=:resSubPath"); + } + + TypedQuery<Object[]> query = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Object[].class) + .setParameter("resname", ores.getResourceableTypeName()) + .setParameter("resId", ores.getResourceableId()); + if(resSubPath != null) { + query.setParameter("resSubPath", resSubPath); + } + + Object[] stats = query.getSingleResult(); + if(stats == null || stats[0] == null || stats[1] == null) { + delegate.update(ores, resSubPath, 0.0d, 0l); + } else { + long numOfRatings = ((Number)stats[0]).longValue(); + long sumOfRatings = ((Number)stats[1]).longValue(); + double rate = sumOfRatings / (double)numOfRatings; + delegate.update(ores, resSubPath, rate, numOfRatings); + } + } + } } public int deleteAllRatings(OLATResourceable ores, String resSubPath) { diff --git a/src/main/java/org/olat/core/commons/services/commentAndRating/model/UserCommentImpl.java b/src/main/java/org/olat/core/commons/services/commentAndRating/model/UserCommentImpl.java index 247b0ca07852ca2d1448cd6f123c51c6035f5a65..c48063e1ca210659aa33759f672bc260fa74f710 100644 --- a/src/main/java/org/olat/core/commons/services/commentAndRating/model/UserCommentImpl.java +++ b/src/main/java/org/olat/core/commons/services/commentAndRating/model/UserCommentImpl.java @@ -114,7 +114,8 @@ public class UserCommentImpl implements Persistable, CreateInfo, UserComment { this.resId = ores.getResourceableId(); this.resSubPath = subpath; } - + + @Override public Long getKey() { return key; } @@ -123,53 +124,36 @@ public class UserCommentImpl implements Persistable, CreateInfo, UserComment { this.key = key; } + @Override public Date getCreationDate() { return creationDate; } - /** - * @see org.olat.core.commons.services.commentAndRating.model.UserComment#getCreator() - */ @Override public Identity getCreator() { return creator; } - /** - * @see org.olat.core.commons.services.commentAndRating.model.UserComment#getComment() - */ @Override public String getComment() { return comment; } - /** - * @see org.olat.core.commons.services.commentAndRating.model.UserComment#getResId() - */ @Override public Long getResId() { return this.resId; } - /** - * @see org.olat.core.commons.services.commentAndRating.model.UserComment#getResName() - */ @Override public String getResName() { return this.resName; } - /** - * @see org.olat.core.commons.services.commentAndRating.model.UserComment#getResSubPath() - */ @Override public String getResSubPath() { return this.resSubPath; } - - /** - * @see org.olat.core.commons.services.commentAndRating.model.UserComment#getParent() - */ + @Override public UserComment getParent() { return parent; @@ -199,23 +183,17 @@ public class UserCommentImpl implements Persistable, CreateInfo, UserComment { this.resId = resId; } - /** - * @see org.olat.core.commons.services.commentAndRating.model.UserComment#setCreator(org.olat.core.id.Identity) - */ + @Override public void setCreator(Identity creator) { this.creator = creator; } - /** - * @see org.olat.core.commons.services.commentAndRating.model.UserComment#setComment(java.lang.String) - */ + @Override public void setComment(String commentText) { this.comment = commentText; } - /** - * @see org.olat.core.commons.services.commentAndRating.model.UserComment#setParent(org.olat.core.commons.services.commentAndRating.model.UserComment) - */ + @Override public void setParent(UserComment parentComment) { this.parent = parentComment; } diff --git a/src/test/java/org/olat/core/commons/services/commentAndRating/manager/CommentAndRatingServiceImplTest.java b/src/test/java/org/olat/core/commons/services/commentAndRating/manager/CommentAndRatingServiceTest.java similarity index 99% rename from src/test/java/org/olat/core/commons/services/commentAndRating/manager/CommentAndRatingServiceImplTest.java rename to src/test/java/org/olat/core/commons/services/commentAndRating/manager/CommentAndRatingServiceTest.java index 601b6d56787f09ce2695cd28d2164ae997b678dd..0403c989bd825cd2f010af10b41fc6ae59f97078 100644 --- a/src/test/java/org/olat/core/commons/services/commentAndRating/manager/CommentAndRatingServiceImplTest.java +++ b/src/test/java/org/olat/core/commons/services/commentAndRating/manager/CommentAndRatingServiceTest.java @@ -39,7 +39,7 @@ import org.olat.resource.OLATResource; * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com * */ -public class CommentAndRatingServiceImplTest { +public class CommentAndRatingServiceTest { private static final String RESOURCEABLE_TYPE_NAME = "resurcable type name"; private static final Long RESOURCABLE_ID = 5L; diff --git a/src/test/java/org/olat/core/commons/services/commentAndRating/manager/UserCommentsDAOTest.java b/src/test/java/org/olat/core/commons/services/commentAndRating/manager/UserCommentsDAOTest.java index e8bafd9f3a8c0fcd1e274aaa25a09b983588033d..fcaa72e9406d64a9ee4990feed2afcb8d43e8a0d 100644 --- a/src/test/java/org/olat/core/commons/services/commentAndRating/manager/UserCommentsDAOTest.java +++ b/src/test/java/org/olat/core/commons/services/commentAndRating/manager/UserCommentsDAOTest.java @@ -22,14 +22,17 @@ package org.olat.core.commons.services.commentAndRating.manager; import static org.junit.Assert.assertEquals; import java.util.List; -import java.util.UUID; import org.junit.Assert; import org.junit.Test; -import org.olat.core.commons.services.commentAndRating.manager.UserCommentsDAO; +import org.olat.admin.user.delete.service.UserDeletionManager; +import org.olat.core.commons.persistence.DB; import org.olat.core.commons.services.commentAndRating.model.UserComment; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; +import org.olat.repository.RepositoryEntry; +import org.olat.repository.RepositoryService; +import org.olat.repository.model.RepositoryEntryStatistics; import org.olat.test.JunitTestHelper; import org.olat.test.OlatTestCase; import org.springframework.beans.factory.annotation.Autowired; @@ -45,8 +48,14 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class UserCommentsDAOTest extends OlatTestCase { + @Autowired + private DB dbInstance; @Autowired private UserCommentsDAO userCommentsDao; + @Autowired + private RepositoryService repositoryService; + @Autowired + private UserDeletionManager userDeletionManager; @Test @@ -58,8 +67,8 @@ public class UserCommentsDAOTest extends OlatTestCase { public void testCRUDComment() { //init OLATResourceable ores = JunitTestHelper.createRandomResource(); - Identity ident1 = JunitTestHelper.createAndPersistIdentityAsUser("ucar-crud-1-" + UUID.randomUUID().toString()); - Identity ident2 = JunitTestHelper.createAndPersistIdentityAsUser("ucar-crud-2-" + UUID.randomUUID().toString()); + Identity ident1 = JunitTestHelper.createAndPersistIdentityAsRndUser("ucar-crud-1"); + Identity ident2 = JunitTestHelper.createAndPersistIdentityAsRndUser("ucar-crud-2"); //check if there is any comments @@ -135,4 +144,49 @@ public class UserCommentsDAOTest extends OlatTestCase { assertEquals(0, userCommentsDao.countComments(ores, null)); assertEquals(0, userCommentsDao.countComments(ores, "blubli")); } + + @Test + public void deleteUser() { + Identity identToDelete = JunitTestHelper.createAndPersistIdentityAsRndUser("ucom-del"); + Identity ident = JunitTestHelper.createAndPersistIdentityAsRndUser("ucom-ndel"); + RepositoryEntry course = JunitTestHelper.deployBasicCourse(ident); + + // add comments + UserComment comment_del_1 = userCommentsDao.createComment(identToDelete, course, null, "Hello"); + UserComment comment_ndel_2 = userCommentsDao.createComment(ident, course, null, "Hello "); + // add comments and replies + UserComment comment_ndel_3 = userCommentsDao.createComment(ident, course, null, "Reply"); + UserComment comment_del_4 = userCommentsDao.replyTo(comment_ndel_3, identToDelete, "Hello, I reply"); + // more + UserComment comment_del_5 = userCommentsDao.createComment(identToDelete, course, null, "To reply"); + UserComment comment_ndel_6 = userCommentsDao.replyTo(comment_del_5, ident, "I replied"); + dbInstance.commitAndCloseSession(); + + // delete the first user + userDeletionManager.deleteIdentity(identToDelete); + dbInstance.commitAndCloseSession(); + + // delete comments from first identity, and replace the comment if it has a reply + UserComment deletedComment_del_1 = userCommentsDao.reloadComment(comment_del_1); + Assert.assertNull(deletedComment_del_1); + UserComment reloadedComment_ndel_2 = userCommentsDao.reloadComment(comment_ndel_2); + Assert.assertNotNull(reloadedComment_ndel_2); + + // 4 was a reply -> delete it + UserComment deletedComment_del_4 = userCommentsDao.reloadComment(comment_del_4); + Assert.assertNull(deletedComment_del_4); + UserComment reloadedComment_ndel_3 = userCommentsDao.reloadComment(comment_ndel_3); + Assert.assertNotNull(reloadedComment_ndel_3); + + // 5 has a reply, don't delete it + UserComment deletedComment_del_5 = userCommentsDao.reloadComment(comment_del_5); + Assert.assertNotNull(deletedComment_del_5); + UserComment reloadedComment_ndel_6 = userCommentsDao.reloadComment(comment_ndel_6); + Assert.assertNotNull(reloadedComment_ndel_6); + + // check repository statistics + RepositoryEntry reloadedEntry = repositoryService.loadByKey(course.getKey()); + RepositoryEntryStatistics entryStatistics = reloadedEntry.getStatistics(); + Assert.assertEquals(4, entryStatistics.getNumOfComments()); + } } diff --git a/src/test/java/org/olat/core/commons/services/commentAndRating/manager/UserRatingsDAOTest.java b/src/test/java/org/olat/core/commons/services/commentAndRating/manager/UserRatingsDAOTest.java index 2185c6b2395db34fc742b4b9184b8310118c4bcf..5c1dcd8ce7f396eef06ca05be13115f7a1a93f30 100644 --- a/src/test/java/org/olat/core/commons/services/commentAndRating/manager/UserRatingsDAOTest.java +++ b/src/test/java/org/olat/core/commons/services/commentAndRating/manager/UserRatingsDAOTest.java @@ -22,16 +22,17 @@ package org.olat.core.commons.services.commentAndRating.manager; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import java.util.UUID; - import org.junit.Assert; import org.junit.Test; +import org.olat.admin.user.delete.service.UserDeletionManager; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.services.commentAndRating.CommentAndRatingService; -import org.olat.core.commons.services.commentAndRating.manager.UserRatingsDAO; import org.olat.core.commons.services.commentAndRating.model.UserRating; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; +import org.olat.repository.RepositoryEntry; +import org.olat.repository.RepositoryService; +import org.olat.repository.model.RepositoryEntryStatistics; import org.olat.test.JunitTestHelper; import org.olat.test.OlatTestCase; import org.springframework.beans.factory.annotation.Autowired; @@ -50,6 +51,10 @@ public class UserRatingsDAOTest extends OlatTestCase { private UserRatingsDAO userRatingsDao; @Autowired private CommentAndRatingService service; + @Autowired + private RepositoryService repositoryService; + @Autowired + private UserDeletionManager userDeletionManager; @Test public void should_service_present() { @@ -60,7 +65,7 @@ public class UserRatingsDAOTest extends OlatTestCase { @Test public void createRating() { OLATResourceable ores = JunitTestHelper.createRandomResource(); - Identity id = JunitTestHelper.createAndPersistIdentityAsUser("ucar-crud-1-" + UUID.randomUUID().toString()); + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("ucar-crud-1"); dbInstance.commitAndCloseSession(); //create @@ -80,7 +85,7 @@ public class UserRatingsDAOTest extends OlatTestCase { @Test public void createUpdateRating() { OLATResourceable ores = JunitTestHelper.createRandomResource(); - Identity id = JunitTestHelper.createAndPersistIdentityAsUser("ucar-crud-1-" + UUID.randomUUID().toString()); + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("ucar-crud-1"); dbInstance.commitAndCloseSession(); //create @@ -106,13 +111,13 @@ public class UserRatingsDAOTest extends OlatTestCase { public void testCRUDRating() { //init OLATResourceable ores = JunitTestHelper.createRandomResource(); - Identity ident1 = JunitTestHelper.createAndPersistIdentityAsUser("ucar-crud-1-" + UUID.randomUUID().toString()); - Identity ident2 = JunitTestHelper.createAndPersistIdentityAsUser("ucar-crud-2-" + UUID.randomUUID().toString()); - Identity ident3 = JunitTestHelper.createAndPersistIdentityAsUser("ucar-crud-3-" + UUID.randomUUID().toString()); + Identity ident1 = JunitTestHelper.createAndPersistIdentityAsRndUser("ucar-crud-1"); + Identity ident2 = JunitTestHelper.createAndPersistIdentityAsRndUser("ucar-crud-2"); + Identity ident3 = JunitTestHelper.createAndPersistIdentityAsRndUser("ucar-crud-3"); - assertEquals(0, userRatingsDao.getRatingAverage(ores, null), 0.01); - assertEquals(0, userRatingsDao.getRatingAverage(ores, "blubli"), 0.01); + assertEquals(0.0f, userRatingsDao.getRatingAverage(ores, null), 0.01f); + assertEquals(0.0f, userRatingsDao.getRatingAverage(ores, "blubli"), 0.01f); assertEquals(0l, userRatingsDao.countRatings(ores, null)); assertEquals(0l, userRatingsDao.countRatings(ores, "blubli")); @@ -120,8 +125,8 @@ public class UserRatingsDAOTest extends OlatTestCase { Assert.assertNotNull(r1); UserRating r2 = userRatingsDao.createRating(ident1, ores, "blubli", 2); Assert.assertNotNull(r2); - assertEquals(2, userRatingsDao.getRatingAverage(ores, null), 0.01); - assertEquals(2, userRatingsDao.getRatingAverage(ores, "blubli"), 0.01); + assertEquals(2.0f, userRatingsDao.getRatingAverage(ores, null), 0.01f); + assertEquals(2.0f, userRatingsDao.getRatingAverage(ores, "blubli"), 0.01f); assertEquals(1l, userRatingsDao.countRatings(ores, null)); assertEquals(1l, userRatingsDao.countRatings(ores, "blubli")); // @@ -129,8 +134,8 @@ public class UserRatingsDAOTest extends OlatTestCase { Assert.assertNotNull(r3); UserRating r4 = userRatingsDao.createRating(ident2, ores, "blubli", 4); Assert.assertNotNull(r4); - assertEquals(3, userRatingsDao.getRatingAverage(ores, null), 0.01); - assertEquals(3, userRatingsDao.getRatingAverage(ores, "blubli"), 0.01); + assertEquals(3.0f, userRatingsDao.getRatingAverage(ores, null), 0.01f); + assertEquals(3.0f, userRatingsDao.getRatingAverage(ores, "blubli"), 0.01f); assertEquals(2l, userRatingsDao.countRatings(ores, null)); assertEquals(2l, userRatingsDao.countRatings(ores, "blubli")); // @@ -138,8 +143,8 @@ public class UserRatingsDAOTest extends OlatTestCase { Assert.assertNotNull(r5); UserRating r6 = userRatingsDao.createRating(ident3, ores, "blubli", 1); Assert.assertNotNull(r6); - assertEquals(2.33f, userRatingsDao.getRatingAverage(ores, null), 0.01); - assertEquals(2.33f, userRatingsDao.getRatingAverage(ores, "blubli"), 0.01); + assertEquals(2.33f, userRatingsDao.getRatingAverage(ores, null), 0.01f); + assertEquals(2.33f, userRatingsDao.getRatingAverage(ores, "blubli"), 0.01f); assertEquals(3l, userRatingsDao.countRatings(ores, null)); assertEquals(3l, userRatingsDao.countRatings(ores, "blubli")); // @@ -149,30 +154,84 @@ public class UserRatingsDAOTest extends OlatTestCase { // can !!not!! create two ratings per person r1 = userRatingsDao.createRating(ident1, ores, null, 2); r2 = userRatingsDao.createRating(ident1, ores, "blubli", 2); - assertEquals(2.25f, userRatingsDao.getRatingAverage(ores, null), 0.01); - assertEquals(2.25f, userRatingsDao.getRatingAverage(ores, "blubli"), 0.01); + assertEquals(2.25f, userRatingsDao.getRatingAverage(ores, null), 0.01f); + assertEquals(2.25f, userRatingsDao.getRatingAverage(ores, "blubli"), 0.01f); //can create 2 ratings assertEquals(4l, userRatingsDao.countRatings(ores, null)); assertEquals(4l, userRatingsDao.countRatings(ores, "blubli")); // Delete ratings without subpath userRatingsDao.deleteAllRatings(ores, null); - assertEquals(0f, userRatingsDao.getRatingAverage(ores, null), 0.01); - assertEquals(2.25f, userRatingsDao.getRatingAverage(ores, "blubli"), 0.01); + assertEquals(0f, userRatingsDao.getRatingAverage(ores, null), 0.01f); + assertEquals(2.25f, userRatingsDao.getRatingAverage(ores, "blubli"), 0.01f); assertEquals(0l, userRatingsDao.countRatings(ores, null)); assertEquals(4l, userRatingsDao.countRatings(ores, "blubli")); // Recreate and delete ignoring subpath r1 = userRatingsDao.createRating(ident1, ores, null, 2); r2 = userRatingsDao.createRating(ident1, ores, "blubli", 2); - assertEquals(2f, userRatingsDao.getRatingAverage(ores, null), 0.01); - assertEquals(2.2f, userRatingsDao.getRatingAverage(ores, "blubli"), 0.01); + assertEquals(2f, userRatingsDao.getRatingAverage(ores, null), 0.01f); + assertEquals(2.2f, userRatingsDao.getRatingAverage(ores, "blubli"), 0.01f); assertEquals(1, userRatingsDao.countRatings(ores, null)); assertEquals(5l, userRatingsDao.countRatings(ores, "blubli")); userRatingsDao.deleteAllRatingsIgnoringSubPath(ores); - assertEquals(0f, userRatingsDao.getRatingAverage(ores, null), 0.01); - assertEquals(0f, userRatingsDao.getRatingAverage(ores, "blubli"), 0.01); + assertEquals(0f, userRatingsDao.getRatingAverage(ores, null), 0.01f); + assertEquals(0f, userRatingsDao.getRatingAverage(ores, "blubli"), 0.01f); assertEquals(0l, userRatingsDao.countRatings(ores, null)); assertEquals(0l, userRatingsDao.countRatings(ores, "blubli")); } + + @Test + public void deleteUser() { + Identity identToDelete = JunitTestHelper.createAndPersistIdentityAsRndUser("ucar-crud-4"); + Identity ident2 = JunitTestHelper.createAndPersistIdentityAsRndUser("ucar-crud-5"); + Identity ident3 = JunitTestHelper.createAndPersistIdentityAsRndUser("ucar-crud-6"); + OLATResourceable randomOres = JunitTestHelper.createRandomResource(); + RepositoryEntry entry = JunitTestHelper.deployBasicCourse(ident2); + dbInstance.commitAndCloseSession(); + + // make some rating + UserRating r1 = userRatingsDao.createRating(identToDelete, randomOres, "rate", 2); + UserRating r2 = userRatingsDao.createRating(identToDelete, entry, null, 2); + UserRating r3 = userRatingsDao.createRating(ident2, randomOres, "rate", 4); + UserRating r4 = userRatingsDao.createRating(ident2, entry, null, 4); + userRatingsDao.createRating(ident3, randomOres, "rate", 3); + userRatingsDao.createRating(ident3, entry, null, 3); + dbInstance.commitAndCloseSession(); + // check average before deletion + float randomAverage = userRatingsDao.getRatingAverage(randomOres, "rate"); + Assert.assertEquals(3.0f, randomAverage, 0.001f); + float courseAverage = userRatingsDao.getRatingAverage(entry, null); + Assert.assertEquals(3.0f, courseAverage, 0.001f); + + // delete first user + userDeletionManager.deleteIdentity(identToDelete); + dbInstance.commitAndCloseSession(); + + //check that rating of the first user are deleted + UserRating deletedRating1 = userRatingsDao.reloadRating(r1); + Assert.assertNull(deletedRating1); + UserRating deletedRating2 = userRatingsDao.reloadRating(r2); + Assert.assertNull(deletedRating2); + // but not the rating of the other users + UserRating reloadedRating3 = userRatingsDao.reloadRating(r3); + Assert.assertNotNull(reloadedRating3); + UserRating reloadedRating4 = userRatingsDao.reloadRating(r4); + Assert.assertNotNull(reloadedRating4); + + // check averages + float afterRandomAverage = userRatingsDao.getRatingAverage(randomOres, "rate"); + Assert.assertEquals(3.5f, afterRandomAverage, 0.001f); + float afterCourseAverage = userRatingsDao.getRatingAverage(entry, null); + Assert.assertEquals(3.5f, afterCourseAverage, 0.001f); + + // check repository + RepositoryEntry reloadedEntry = repositoryService.loadByKey(entry.getKey()); + RepositoryEntryStatistics entryStatistics = reloadedEntry.getStatistics(); + Assert.assertEquals(2l, entryStatistics.getNumOfRatings()); + Assert.assertEquals(3.5d, entryStatistics.getRating().doubleValue(), 0.001d); + } + + + } \ No newline at end of file diff --git a/src/test/java/org/olat/selenium/page/user/UserAdminPage.java b/src/test/java/org/olat/selenium/page/user/UserAdminPage.java index a7456fc006400b10d0cf058f0c174c08faf26e41..dfd5e1b85e38b4f819556ac3b115eadfb977369a 100644 --- a/src/test/java/org/olat/selenium/page/user/UserAdminPage.java +++ b/src/test/java/org/olat/selenium/page/user/UserAdminPage.java @@ -115,14 +115,16 @@ public class UserAdminPage { OOGraphene.waitModalDialog(browser); //confirm - By usernameBy = By.xpath("//div[contains(@class,'modal-dialog')]//p[text()[contains(.,'" + lastName + "')]]"); + By usernameBy = By.xpath("//div[contains(@class,'modal-dialog')]//div[@class='o_error']/strong[text()[contains(.,'" + lastName + "')]]"); List<WebElement> confirmUserEls = browser.findElements(usernameBy); Assert.assertFalse(confirmUserEls.isEmpty()); - By buttonsBy = By.cssSelector("div.modal-dialog div.modal-footer a.btn.btn-default"); - List<WebElement> buttonEls = browser.findElements(buttonsBy); - Assert.assertEquals(2, buttonEls.size()); - buttonEls.get(0).click(); + By confirmCheckBy = By.cssSelector("div.o_sel_confirm_delete_user input[type='checkbox']"); + WebElement confirmCheckEl = browser.findElement(confirmCheckBy); + OOGraphene.check(confirmCheckEl, Boolean.TRUE); + + By buttonsBy = By.cssSelector("div.modal-dialog div.modal-body a.btn.o_sel_delete_user"); + browser.findElement(buttonsBy).click(); OOGraphene.waitBusy(browser); OOGraphene.waitAndCloseBlueMessageWindow(browser); return this; diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java index acf2aec79686273d731db3abfae8dc5e931ab880..a1035bda32cd92cf81454464a7d79081fac290ec 100644 --- a/src/test/java/org/olat/test/AllTestsJunit4.java +++ b/src/test/java/org/olat/test/AllTestsJunit4.java @@ -351,7 +351,7 @@ import org.junit.runners.Suite; /** * Pure JUnit test without need of framework */ - org.olat.core.commons.services.commentAndRating.manager.CommentAndRatingServiceImplTest.class, + org.olat.core.commons.services.commentAndRating.manager.CommentAndRatingServiceTest.class, org.olat.core.commons.services.license.ui.LicenseSelectionConfigTest.class, org.olat.core.gui.components.form.flexible.impl.elements.richText.TextModeTest.class, org.olat.core.gui.components.form.flexible.impl.elements.SelectboxSelectionImplTest.class,