mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Rating Service Part 2.
Users can't rate their own content any more. Added a RunAs(System) so that users can rate content they don't own, which is all they can rate! First stab at adding rating totals, means and counts - to be tidied tomorrow. Miscellaneous improvements & doc'ing. Tests for the above. Refactored existing tests to run as different users (all were running as admin previously). git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21013 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
package org.alfresco.repo.rating;
|
package org.alfresco.repo.rating;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -37,6 +38,8 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
|||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.service.namespace.QNamePattern;
|
||||||
|
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
@@ -79,17 +82,39 @@ public class RatingServiceImpl implements RatingService
|
|||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.alfresco.service.cmr.rating.RatingService#applyRating(org.alfresco.service.cmr.repository.NodeRef, int, java.lang.String)
|
* @see org.alfresco.service.cmr.rating.RatingService#applyRating(org.alfresco.service.cmr.repository.NodeRef, int, java.lang.String)
|
||||||
*/
|
*/
|
||||||
public void applyRating(NodeRef targetNode, int rating,
|
public void applyRating(final NodeRef targetNode, final int rating,
|
||||||
String ratingSchemeName) throws RatingServiceException
|
final String ratingSchemeName) throws RatingServiceException
|
||||||
{
|
{
|
||||||
String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
|
final String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||||
this.applyRating(targetNode, rating, ratingSchemeName, currentUser);
|
boolean isCreator = isCurrentUserNodeCreator(targetNode);
|
||||||
|
if (isCreator)
|
||||||
|
{
|
||||||
|
throw new RatingServiceException("Users can't rate their own content.");
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Void>() {
|
||||||
|
public Void doWork() throws Exception
|
||||||
|
{
|
||||||
|
applyRating(targetNode, rating, ratingSchemeName, currentUser);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isCurrentUserNodeCreator(NodeRef targetNode)
|
||||||
|
{
|
||||||
|
final String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||||
|
// TODO Is creator the right property here?
|
||||||
|
Serializable creator = nodeService.getProperty(targetNode, ContentModel.PROP_CREATOR);
|
||||||
|
return currentUser.equals(creator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void applyRating(NodeRef targetNode, int rating,
|
private void applyRating(NodeRef targetNode, int rating,
|
||||||
String ratingSchemeName, final String userName) throws RatingServiceException
|
String ratingSchemeName, final String userName) throws RatingServiceException
|
||||||
{
|
{
|
||||||
|
//TODO More logging.
|
||||||
|
|
||||||
// Sanity check the rating scheme being used and the rating being applied.
|
// Sanity check the rating scheme being used and the rating being applied.
|
||||||
final RatingScheme ratingScheme = this.getRatingScheme(ratingSchemeName);
|
final RatingScheme ratingScheme = this.getRatingScheme(ratingSchemeName);
|
||||||
if (ratingScheme == null)
|
if (ratingScheme == null)
|
||||||
@@ -127,11 +152,12 @@ public class RatingServiceImpl implements RatingService
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// There are previous ratings by this user. Things are a little more complex.
|
// There are previous ratings by this user. Things are a little more complex.
|
||||||
if (myRatingChildren.size() > 1)
|
if (myRatingChildren.size() > 1 && log.isDebugEnabled())
|
||||||
{
|
{
|
||||||
//TODO This should not happen. Log
|
log.debug("");
|
||||||
}
|
}
|
||||||
NodeRef myPreviousRatingsNode = myRatingChildren.get(0).getChildRef();
|
NodeRef myPreviousRatingsNode = myRatingChildren.get(0).getChildRef();
|
||||||
|
|
||||||
Map<QName, Serializable> existingProps = nodeService.getProperties(myPreviousRatingsNode);
|
Map<QName, Serializable> existingProps = nodeService.getProperties(myPreviousRatingsNode);
|
||||||
List<String> existingRatingSchemes = (List<String>)existingProps.get(ContentModel.PROP_RATING_SCHEME);
|
List<String> existingRatingSchemes = (List<String>)existingProps.get(ContentModel.PROP_RATING_SCHEME);
|
||||||
List<Integer> existingRatingScores = (List<Integer>)existingProps.get(ContentModel.PROP_RATING_SCORE);
|
List<Integer> existingRatingScores = (List<Integer>)existingProps.get(ContentModel.PROP_RATING_SCORE);
|
||||||
@@ -164,16 +190,16 @@ public class RatingServiceImpl implements RatingService
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.alfresco.service.cmr.rating.RatingService#getRating(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.rating.RatingScheme)
|
* @see org.alfresco.service.cmr.rating.RatingService#getRatingByCurrentUser(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
|
||||||
*/
|
*/
|
||||||
public Rating getRatingByCurrentUser(NodeRef targetNode, RatingScheme ratingScheme)
|
public Rating getRatingByCurrentUser(NodeRef targetNode, String ratingSchemeName)
|
||||||
{
|
{
|
||||||
String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
|
String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||||
return this.getRating(targetNode, ratingScheme, currentUser);
|
return this.getRating(targetNode, ratingSchemeName, currentUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private Rating getRating(NodeRef targetNode, RatingScheme ratingScheme, String user)
|
private Rating getRating(NodeRef targetNode, String ratingSchemeName, String user)
|
||||||
{
|
{
|
||||||
List<ChildAssociationRef> ratingChildren = getRatingNodeChildren(targetNode, user);
|
List<ChildAssociationRef> ratingChildren = getRatingNodeChildren(targetNode, user);
|
||||||
|
|
||||||
@@ -188,6 +214,7 @@ public class RatingServiceImpl implements RatingService
|
|||||||
Map<QName, Serializable> properties = nodeService.getProperties(lastChild.getChildRef());
|
Map<QName, Serializable> properties = nodeService.getProperties(lastChild.getChildRef());
|
||||||
|
|
||||||
// Find the index of the rating scheme we're interested in.
|
// Find the index of the rating scheme we're interested in.
|
||||||
|
RatingScheme ratingScheme = getRatingScheme(ratingSchemeName);
|
||||||
int index = findIndexOfRatingScheme(properties, ratingScheme);
|
int index = findIndexOfRatingScheme(properties, ratingScheme);
|
||||||
if (index == -1)
|
if (index == -1)
|
||||||
{
|
{
|
||||||
@@ -219,17 +246,17 @@ public class RatingServiceImpl implements RatingService
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.alfresco.service.cmr.rating.RatingService#removeRatingByCurrentUser(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.rating.RatingScheme)
|
* @see org.alfresco.service.cmr.rating.RatingService#removeRatingByCurrentUser(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
|
||||||
*/
|
*/
|
||||||
public Rating removeRatingByCurrentUser(NodeRef targetNode,
|
public Rating removeRatingByCurrentUser(NodeRef targetNode,
|
||||||
RatingScheme ratingScheme)
|
String ratingScheme)
|
||||||
{
|
{
|
||||||
String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
|
String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||||
return removeRating(targetNode, ratingScheme, currentUser);
|
return removeRating(targetNode, ratingScheme, currentUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private Rating removeRating(NodeRef targetNode, RatingScheme ratingScheme, String user)
|
private Rating removeRating(NodeRef targetNode, String ratingSchemeName, String user)
|
||||||
{
|
{
|
||||||
List<ChildAssociationRef> ratingChildren = getRatingNodeChildren(targetNode, user);
|
List<ChildAssociationRef> ratingChildren = getRatingNodeChildren(targetNode, user);
|
||||||
if (ratingChildren.isEmpty())
|
if (ratingChildren.isEmpty())
|
||||||
@@ -242,6 +269,7 @@ public class RatingServiceImpl implements RatingService
|
|||||||
Map<QName, Serializable> properties = nodeService.getProperties(lastChild.getChildRef());
|
Map<QName, Serializable> properties = nodeService.getProperties(lastChild.getChildRef());
|
||||||
|
|
||||||
// Find the index of the rating scheme we're interested in.
|
// Find the index of the rating scheme we're interested in.
|
||||||
|
RatingScheme ratingScheme = getRatingScheme(ratingSchemeName);
|
||||||
int index = this.findIndexOfRatingScheme(properties, ratingScheme);
|
int index = this.findIndexOfRatingScheme(properties, ratingScheme);
|
||||||
if (index == -1)
|
if (index == -1)
|
||||||
{
|
{
|
||||||
@@ -263,23 +291,140 @@ public class RatingServiceImpl implements RatingService
|
|||||||
oldScore, user, oldDate);
|
oldScore, user, oldDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.alfresco.service.cmr.rating.RatingService#getTotalRating(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
|
||||||
|
*/
|
||||||
|
public int getTotalRating(NodeRef targetNode, String ratingSchemeName)
|
||||||
|
{
|
||||||
|
//TODO Put these in the db as properties?
|
||||||
|
List<ChildAssociationRef> ratingsNodes = this.getRatingNodeChildren(targetNode, null);
|
||||||
|
|
||||||
|
// It's one node per user so the size of this list is the number of ratings applied.
|
||||||
|
// However not all of these users' ratings need be in the specified scheme.
|
||||||
|
// So we need to go through and check that the rating node contains a rating for the
|
||||||
|
// specified scheme.
|
||||||
|
int result = 0;
|
||||||
|
for (ChildAssociationRef ratingsNode : ratingsNodes)
|
||||||
|
{
|
||||||
|
List<Rating> ratings = getRatingsFrom(ratingsNode.getChildRef());
|
||||||
|
for (Rating rating : ratings)
|
||||||
|
{
|
||||||
|
if (rating.getScheme().getName().equals(ratingSchemeName))
|
||||||
|
{
|
||||||
|
result += rating.getScore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO We can at least amagamate these into one looping call.
|
||||||
|
public float getAverageRating(NodeRef targetNode, String ratingSchemeName)
|
||||||
|
{
|
||||||
|
//TODO Put these in the db as properties?
|
||||||
|
List<ChildAssociationRef> ratingsNodes = this.getRatingNodeChildren(targetNode, null);
|
||||||
|
|
||||||
|
// It's one node per user so the size of this list is the number of ratings applied.
|
||||||
|
// However not all of these users' ratings need be in the specified scheme.
|
||||||
|
// So we need to go through and check that the rating node contains a rating for the
|
||||||
|
// specified scheme.
|
||||||
|
int ratingCount = 0;
|
||||||
|
int ratingTotal = 0;
|
||||||
|
for (ChildAssociationRef ratingsNode : ratingsNodes)
|
||||||
|
{
|
||||||
|
List<Rating> ratings = getRatingsFrom(ratingsNode.getChildRef());
|
||||||
|
for (Rating rating : ratings)
|
||||||
|
{
|
||||||
|
if (rating.getScheme().getName().equals(ratingSchemeName))
|
||||||
|
{
|
||||||
|
ratingCount++;
|
||||||
|
ratingTotal += rating.getScore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (float)ratingTotal / (float)ratingCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRatingsCount(NodeRef targetNode, String ratingSchemeName)
|
||||||
|
{
|
||||||
|
//TODO Put these in the db as properties?
|
||||||
|
List<ChildAssociationRef> ratingsNodes = this.getRatingNodeChildren(targetNode, null);
|
||||||
|
|
||||||
|
// It's one node per user so the size of this list is the number of ratings applied.
|
||||||
|
// However not all of these users' ratings need be in the specified scheme.
|
||||||
|
// So we need to go through and check that the rating node contains a rating for the
|
||||||
|
// specified scheme.
|
||||||
|
int result = 0;
|
||||||
|
for (ChildAssociationRef ratingsNode : ratingsNodes)
|
||||||
|
{
|
||||||
|
List<Rating> ratings = getRatingsFrom(ratingsNode.getChildRef());
|
||||||
|
for (Rating rating : ratings)
|
||||||
|
{
|
||||||
|
if (rating.getScheme().getName().equals(ratingSchemeName))
|
||||||
|
{
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method gets all the cm:rating child nodes of the specified targetNode that
|
* This method gets all the cm:rating child nodes of the specified targetNode that
|
||||||
* have been applied by the specified user.
|
* have been applied by the specified user.
|
||||||
*
|
*
|
||||||
* @param targetNode the target node under which the cm:rating nodes reside.
|
* @param targetNode the target node under which the cm:rating nodes reside.
|
||||||
* @param user the user name of the user whose ratings are sought.
|
* @param user the user name of the user whose ratings are sought, <code>null</code>
|
||||||
|
* for all users.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private List<ChildAssociationRef> getRatingNodeChildren(NodeRef targetNode,
|
private List<ChildAssociationRef> getRatingNodeChildren(NodeRef targetNode,
|
||||||
String user)
|
String user)
|
||||||
{
|
{
|
||||||
QName userAssocQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, user);
|
QNamePattern qnamePattern = null;
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
qnamePattern = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, user);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qnamePattern = RegexQNamePattern.MATCH_ALL;
|
||||||
|
}
|
||||||
|
List<ChildAssociationRef> results = nodeService.getChildAssocs(targetNode, ContentModel.ASSOC_RATINGS, qnamePattern);
|
||||||
|
|
||||||
// Get all the rating nodes which are from the specified user.
|
return results;
|
||||||
List<ChildAssociationRef> ratingChildren =
|
}
|
||||||
nodeService.getChildAssocs(targetNode, ContentModel.ASSOC_RATINGS, userAssocQName);
|
|
||||||
return ratingChildren;
|
/**
|
||||||
|
* This method returns a List of {@link Rating} objects for the specified cm:rating
|
||||||
|
* node. As it's one ratingNode the results will be form one user, but will represent
|
||||||
|
* 0..n schemes.
|
||||||
|
* @param ratingNode
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private List<Rating> getRatingsFrom(NodeRef ratingNode)
|
||||||
|
{
|
||||||
|
// The appliedBy is encoded in the parent assoc qname.
|
||||||
|
// It will be the same user for all ratings in this node.
|
||||||
|
ChildAssociationRef parentAssoc = nodeService.getPrimaryParent(ratingNode);
|
||||||
|
String appliedBy = parentAssoc.getQName().getLocalName();
|
||||||
|
|
||||||
|
Map<QName, Serializable> properties = nodeService.getProperties(ratingNode);
|
||||||
|
List<String> ratingSchemes = (List<String>)properties.get(ContentModel.PROP_RATING_SCHEME);
|
||||||
|
List<Integer> ratingScores = (List<Integer>)properties.get(ContentModel.PROP_RATING_SCORE);
|
||||||
|
List<Date> ratingDates = (List<Date>)properties.get(ContentModel.PROP_RATED_AT);
|
||||||
|
|
||||||
|
List<Rating> result = new ArrayList<Rating>(ratingSchemes.size());
|
||||||
|
for (int i = 0; i < ratingSchemes.size(); i++)
|
||||||
|
{
|
||||||
|
final String schemeName = ratingSchemes.get(i);
|
||||||
|
RatingScheme scheme = getRatingScheme(schemeName);
|
||||||
|
result.add(new Rating(scheme, ratingScores.get(i), appliedBy, ratingDates.get(i)));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -34,10 +34,12 @@ import org.alfresco.service.cmr.rating.RatingService;
|
|||||||
import org.alfresco.service.cmr.rating.RatingServiceException;
|
import org.alfresco.service.cmr.rating.RatingServiceException;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||||
import org.alfresco.util.BaseAlfrescoSpringTest;
|
import org.alfresco.util.BaseAlfrescoSpringTest;
|
||||||
|
import org.alfresco.util.PropertyMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Neil McErlean
|
* @author Neil McErlean
|
||||||
@@ -45,15 +47,18 @@ import org.alfresco.util.BaseAlfrescoSpringTest;
|
|||||||
*/
|
*/
|
||||||
public class RatingServiceIntegrationTest extends BaseAlfrescoSpringTest
|
public class RatingServiceIntegrationTest extends BaseAlfrescoSpringTest
|
||||||
{
|
{
|
||||||
|
private static final String USER_ERNIE = "Ernie";
|
||||||
|
private static final String USER_ERIC = "Eric";
|
||||||
|
private PersonService personService;
|
||||||
private RatingService ratingService;
|
private RatingService ratingService;
|
||||||
private Repository repositoryHelper;
|
private Repository repositoryHelper;
|
||||||
private NodeRef companyHome;
|
private NodeRef companyHome;
|
||||||
|
|
||||||
// These NodeRefs are used by the test methods.
|
// These NodeRefs are used by the test methods.
|
||||||
private NodeRef testFolder;
|
private NodeRef testFolder;
|
||||||
private NodeRef testSubFolder;
|
private NodeRef testDoc_Admin;
|
||||||
private NodeRef testDocInFolder;
|
private NodeRef testDoc_Eric;
|
||||||
private NodeRef testDocInSubFolder;
|
private NodeRef testDoc_Ernie;
|
||||||
|
|
||||||
// The out of the box scheme names.
|
// The out of the box scheme names.
|
||||||
private static final String LIKES_SCHEME_NAME = "likesRatingScheme";
|
private static final String LIKES_SCHEME_NAME = "likesRatingScheme";
|
||||||
@@ -63,6 +68,7 @@ public class RatingServiceIntegrationTest extends BaseAlfrescoSpringTest
|
|||||||
protected void onSetUpInTransaction() throws Exception
|
protected void onSetUpInTransaction() throws Exception
|
||||||
{
|
{
|
||||||
super.onSetUpInTransaction();
|
super.onSetUpInTransaction();
|
||||||
|
this.personService = (PersonService)this.applicationContext.getBean("PersonService");
|
||||||
this.ratingService = (RatingService) this.applicationContext.getBean("ratingService");
|
this.ratingService = (RatingService) this.applicationContext.getBean("ratingService");
|
||||||
this.repositoryHelper = (Repository) this.applicationContext.getBean("repositoryHelper");
|
this.repositoryHelper = (Repository) this.applicationContext.getBean("repositoryHelper");
|
||||||
|
|
||||||
@@ -73,10 +79,26 @@ public class RatingServiceIntegrationTest extends BaseAlfrescoSpringTest
|
|||||||
|
|
||||||
//TODO These could be created @BeforeClass
|
//TODO These could be created @BeforeClass
|
||||||
testFolder = createNode(companyHome, "testFolder", ContentModel.TYPE_FOLDER);
|
testFolder = createNode(companyHome, "testFolder", ContentModel.TYPE_FOLDER);
|
||||||
testSubFolder = createNode(testFolder, "testSubFolder", ContentModel.TYPE_FOLDER);
|
testDoc_Admin = createNode(testFolder, "testDocInFolder", ContentModel.TYPE_CONTENT);
|
||||||
|
|
||||||
testDocInFolder = createNode(testFolder, "testDocInFolder", ContentModel.TYPE_CONTENT);
|
createUser(USER_ERIC);
|
||||||
testDocInSubFolder = createNode(testSubFolder, "testDocInSubFolder", ContentModel.TYPE_CONTENT);
|
createUser(USER_ERNIE);
|
||||||
|
|
||||||
|
AuthenticationUtil.setFullyAuthenticatedUser(USER_ERIC);
|
||||||
|
testDoc_Eric = createNode(testFolder, "ericsDoc", ContentModel.TYPE_CONTENT);
|
||||||
|
AuthenticationUtil.setFullyAuthenticatedUser(USER_ERNIE);
|
||||||
|
testDoc_Ernie = createNode(testFolder, "erniesDoc", ContentModel.TYPE_CONTENT);
|
||||||
|
|
||||||
|
// And back to admin
|
||||||
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onTearDownInTransaction() throws Exception
|
||||||
|
{
|
||||||
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||||
|
deleteUser(USER_ERIC);
|
||||||
|
deleteUser(USER_ERNIE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NodeRef createNode(NodeRef parentNode, String name, QName type)
|
private NodeRef createNode(NodeRef parentNode, String name, QName type)
|
||||||
@@ -127,7 +149,7 @@ public class RatingServiceIntegrationTest extends BaseAlfrescoSpringTest
|
|||||||
int[] illegalRatings = new int[]{0, 2};
|
int[] illegalRatings = new int[]{0, 2};
|
||||||
for (int illegalRating : illegalRatings)
|
for (int illegalRating : illegalRatings)
|
||||||
{
|
{
|
||||||
applyIllegalRating(testDocInFolder, illegalRating, LIKES_SCHEME_NAME);
|
applyIllegalRating(testDoc_Admin, illegalRating, LIKES_SCHEME_NAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,24 +167,25 @@ public class RatingServiceIntegrationTest extends BaseAlfrescoSpringTest
|
|||||||
|
|
||||||
public void testApplyUpdateDeleteRatings_SingleUserMultipleSchemes() throws Exception
|
public void testApplyUpdateDeleteRatings_SingleUserMultipleSchemes() throws Exception
|
||||||
{
|
{
|
||||||
|
// We'll do all this as user 'eric'.
|
||||||
|
AuthenticationUtil.setFullyAuthenticatedUser(USER_ERIC);
|
||||||
|
|
||||||
//Before we start, let's ensure the read behaviour on a pristine node is correct.
|
//Before we start, let's ensure the read behaviour on a pristine node is correct.
|
||||||
final RatingScheme likesRatingScheme = ratingService.getRatingScheme(LIKES_SCHEME_NAME);
|
Rating nullRating = ratingService.getRatingByCurrentUser(testDoc_Admin, LIKES_SCHEME_NAME);
|
||||||
Rating nullRating = ratingService.getRatingByCurrentUser(testDocInFolder, likesRatingScheme);
|
|
||||||
assertNull("Expected a null rating,", nullRating);
|
assertNull("Expected a null rating,", nullRating);
|
||||||
assertNull("Expected a null remove result.", ratingService.removeRatingByCurrentUser(testDocInFolder, likesRatingScheme));
|
assertNull("Expected a null remove result.", ratingService.removeRatingByCurrentUser(testDoc_Admin, LIKES_SCHEME_NAME));
|
||||||
|
|
||||||
final int likesScore = 1;
|
final int likesScore = 1;
|
||||||
final int fiveStarScore = 5;
|
final int fiveStarScore = 5;
|
||||||
|
|
||||||
// Both of these ratings will be applied by the same user: the 'current' user.
|
ratingService.applyRating(testDoc_Admin, likesScore, LIKES_SCHEME_NAME);
|
||||||
ratingService.applyRating(testDocInFolder, likesScore, LIKES_SCHEME_NAME);
|
ratingService.applyRating(testDoc_Admin, fiveStarScore, FIVE_STAR_SCHEME_NAME);
|
||||||
ratingService.applyRating(testDocInFolder, fiveStarScore, FIVE_STAR_SCHEME_NAME);
|
|
||||||
|
|
||||||
// Some basic node structure tests.
|
// Some basic node structure tests.
|
||||||
assertTrue(ContentModel.ASPECT_RATEABLE + " aspect missing.",
|
assertTrue(ContentModel.ASPECT_RATEABLE + " aspect missing.",
|
||||||
nodeService.hasAspect(testDocInFolder, ContentModel.ASPECT_RATEABLE));
|
nodeService.hasAspect(testDoc_Admin, ContentModel.ASPECT_RATEABLE));
|
||||||
|
|
||||||
List<ChildAssociationRef> allChildren = nodeService.getChildAssocs(testDocInFolder,
|
List<ChildAssociationRef> allChildren = nodeService.getChildAssocs(testDoc_Admin,
|
||||||
ContentModel.ASSOC_RATINGS, RegexQNamePattern.MATCH_ALL);
|
ContentModel.ASSOC_RATINGS, RegexQNamePattern.MATCH_ALL);
|
||||||
|
|
||||||
// It's one cm:rating node per user
|
// It's one cm:rating node per user
|
||||||
@@ -176,10 +199,9 @@ public class RatingServiceIntegrationTest extends BaseAlfrescoSpringTest
|
|||||||
|
|
||||||
|
|
||||||
// Now to check the persisted ratings data are ok.
|
// Now to check the persisted ratings data are ok.
|
||||||
Rating likeRating = ratingService.getRatingByCurrentUser(testDocInFolder, likesRatingScheme);
|
Rating likeRating = ratingService.getRatingByCurrentUser(testDoc_Admin, LIKES_SCHEME_NAME);
|
||||||
|
|
||||||
final RatingScheme fiveStarRatingScheme = ratingService.getRatingScheme(FIVE_STAR_SCHEME_NAME);
|
Rating fiveStarRating = ratingService.getRatingByCurrentUser(testDoc_Admin, FIVE_STAR_SCHEME_NAME);
|
||||||
Rating fiveStarRating = ratingService.getRatingByCurrentUser(testDocInFolder, fiveStarRatingScheme);
|
|
||||||
|
|
||||||
assertNotNull("'like' rating was null.", likeRating);
|
assertNotNull("'like' rating was null.", likeRating);
|
||||||
assertEquals("Wrong score for rating", likesScore, likeRating.getScore());
|
assertEquals("Wrong score for rating", likesScore, likeRating.getScore());
|
||||||
@@ -195,10 +217,10 @@ public class RatingServiceIntegrationTest extends BaseAlfrescoSpringTest
|
|||||||
|
|
||||||
// Now we'll update a rating
|
// Now we'll update a rating
|
||||||
final int updatedFiveStarScore = 3;
|
final int updatedFiveStarScore = 3;
|
||||||
ratingService.applyRating(testDocInFolder, updatedFiveStarScore, FIVE_STAR_SCHEME_NAME);
|
ratingService.applyRating(testDoc_Admin, updatedFiveStarScore, FIVE_STAR_SCHEME_NAME);
|
||||||
|
|
||||||
// Some basic node structure tests.
|
// Some basic node structure tests.
|
||||||
allChildren = nodeService.getChildAssocs(testDocInFolder,
|
allChildren = nodeService.getChildAssocs(testDoc_Admin,
|
||||||
ContentModel.ASSOC_RATINGS, RegexQNamePattern.MATCH_ALL);
|
ContentModel.ASSOC_RATINGS, RegexQNamePattern.MATCH_ALL);
|
||||||
|
|
||||||
// Still one cm:rating node
|
// Still one cm:rating node
|
||||||
@@ -210,7 +232,7 @@ public class RatingServiceIntegrationTest extends BaseAlfrescoSpringTest
|
|||||||
|
|
||||||
|
|
||||||
// Now to check the updated ratings data are ok.
|
// Now to check the updated ratings data are ok.
|
||||||
Rating updatedFiveStarRating = ratingService.getRatingByCurrentUser(testDocInFolder, fiveStarRatingScheme);
|
Rating updatedFiveStarRating = ratingService.getRatingByCurrentUser(testDoc_Admin, FIVE_STAR_SCHEME_NAME);
|
||||||
|
|
||||||
// 'like' rating data should be unchanged.
|
// 'like' rating data should be unchanged.
|
||||||
assertNotNull("'like' rating was null.", likeRating);
|
assertNotNull("'like' rating was null.", likeRating);
|
||||||
@@ -226,7 +248,7 @@ public class RatingServiceIntegrationTest extends BaseAlfrescoSpringTest
|
|||||||
assertDateIsCloseToNow(updatedFiveStarRating.getAppliedAt());
|
assertDateIsCloseToNow(updatedFiveStarRating.getAppliedAt());
|
||||||
|
|
||||||
// Now we'll delete the 'likes' rating.
|
// Now we'll delete the 'likes' rating.
|
||||||
Rating deletedLikesRating = ratingService.removeRatingByCurrentUser(testDocInFolder, likesRatingScheme);
|
Rating deletedLikesRating = ratingService.removeRatingByCurrentUser(testDoc_Admin, LIKES_SCHEME_NAME);
|
||||||
// 'like' rating data should be unchanged.
|
// 'like' rating data should be unchanged.
|
||||||
assertNotNull("'like' rating was null.", deletedLikesRating);
|
assertNotNull("'like' rating was null.", deletedLikesRating);
|
||||||
assertEquals("Wrong score for rating", likesScore, deletedLikesRating.getScore());
|
assertEquals("Wrong score for rating", likesScore, deletedLikesRating.getScore());
|
||||||
@@ -234,7 +256,7 @@ public class RatingServiceIntegrationTest extends BaseAlfrescoSpringTest
|
|||||||
assertEquals("Wrong date for rating", likeRatingAppliedAt, deletedLikesRating.getAppliedAt());
|
assertEquals("Wrong date for rating", likeRatingAppliedAt, deletedLikesRating.getAppliedAt());
|
||||||
|
|
||||||
// And delete the 'five star' rating.
|
// And delete the 'five star' rating.
|
||||||
Rating deletedStarRating = ratingService.removeRatingByCurrentUser(testDocInFolder, fiveStarRatingScheme);
|
Rating deletedStarRating = ratingService.removeRatingByCurrentUser(testDoc_Admin, FIVE_STAR_SCHEME_NAME);
|
||||||
// 'five star' rating data should be unchanged.
|
// 'five star' rating data should be unchanged.
|
||||||
assertNotNull("'5*' rating was null.", deletedStarRating);
|
assertNotNull("'5*' rating was null.", deletedStarRating);
|
||||||
assertEquals("Wrong score for rating", updatedFiveStarScore, deletedStarRating.getScore());
|
assertEquals("Wrong score for rating", updatedFiveStarScore, deletedStarRating.getScore());
|
||||||
@@ -256,6 +278,65 @@ public class RatingServiceIntegrationTest extends BaseAlfrescoSpringTest
|
|||||||
final long millisTolerance = 5000l; // 5 seconds
|
final long millisTolerance = 5000l; // 5 seconds
|
||||||
assertTrue("Date was not within " + millisTolerance + "ms of 'now'.", now.getTime() - d.getTime() < millisTolerance);
|
assertTrue("Date was not within " + millisTolerance + "ms of 'now'.", now.getTime() - d.getTime() < millisTolerance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testApplyRating_MultipleUsers() throws Exception
|
||||||
|
{
|
||||||
|
// 2 different users rating the same piece of content in the same rating scheme
|
||||||
|
AuthenticationUtil.setFullyAuthenticatedUser(USER_ERNIE);
|
||||||
|
ratingService.applyRating(testDoc_Admin, 4, FIVE_STAR_SCHEME_NAME);
|
||||||
|
|
||||||
//TODO Multiple users applying ratings to a doc.
|
AuthenticationUtil.setFullyAuthenticatedUser(USER_ERIC);
|
||||||
|
ratingService.applyRating(testDoc_Admin, 2, FIVE_STAR_SCHEME_NAME);
|
||||||
|
|
||||||
|
float meanRating = ratingService.getAverageRating(testDoc_Admin, FIVE_STAR_SCHEME_NAME);
|
||||||
|
assertEquals("Document had wrong mean rating.", 3f, meanRating);
|
||||||
|
|
||||||
|
int totalRating = ratingService.getTotalRating(testDoc_Admin, FIVE_STAR_SCHEME_NAME);
|
||||||
|
assertEquals("Document had wrong total rating.", 6, totalRating);
|
||||||
|
|
||||||
|
int ratingsCount = ratingService.getRatingsCount(testDoc_Admin, FIVE_STAR_SCHEME_NAME);
|
||||||
|
assertEquals("Document had wrong ratings count.", 2, ratingsCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testUsersCantRateTheirOwnContent() throws Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AuthenticationUtil.setFullyAuthenticatedUser(USER_ERNIE);
|
||||||
|
ratingService.applyRating(testDoc_Ernie, 4, FIVE_STAR_SCHEME_NAME);
|
||||||
|
} catch (RatingServiceException expected)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fail("Expected exception not thrown");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createUser(String userName)
|
||||||
|
{
|
||||||
|
if (! authenticationService.authenticationExists(userName))
|
||||||
|
{
|
||||||
|
authenticationService.createAuthentication(userName, "PWD".toCharArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! personService.personExists(userName))
|
||||||
|
{
|
||||||
|
PropertyMap ppOne = new PropertyMap(4);
|
||||||
|
ppOne.put(ContentModel.PROP_USERNAME, userName);
|
||||||
|
ppOne.put(ContentModel.PROP_FIRSTNAME, "firstName");
|
||||||
|
ppOne.put(ContentModel.PROP_LASTNAME, "lastName");
|
||||||
|
ppOne.put(ContentModel.PROP_EMAIL, "email@email.com");
|
||||||
|
ppOne.put(ContentModel.PROP_JOBTITLE, "jobTitle");
|
||||||
|
|
||||||
|
personService.createPerson(ppOne);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteUser(String userName)
|
||||||
|
{
|
||||||
|
if (personService.personExists(userName))
|
||||||
|
{
|
||||||
|
personService.deletePerson(userName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,18 @@ import org.alfresco.service.PublicService;
|
|||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Rating service. TODO
|
* Interface for public and internal rating operations.
|
||||||
|
* <p/>
|
||||||
|
* The RatingService can be used to manage ratings on any content node in the repository.
|
||||||
|
* These ratings are defined by {@link RatingScheme rating schemes}
|
||||||
|
* which are injected via spring (see <code>rating-service-context.xml</code>). The rating
|
||||||
|
* schemes define a minimum and a maximum score value for that scheme.
|
||||||
|
* <p/>
|
||||||
|
* Ratings can be {@link RatingService#applyRating(NodeRef, int, String) applied},
|
||||||
|
* {@link RatingService#applyRating(NodeRef, int, String) updated} and
|
||||||
|
* {@link RatingService#removeRatingByCurrentUser(NodeRef, RatingScheme) removed}.
|
||||||
|
*
|
||||||
|
* TODO Get average/total
|
||||||
*
|
*
|
||||||
* @author Neil McErlean
|
* @author Neil McErlean
|
||||||
* @since 3.4
|
* @since 3.4
|
||||||
@@ -68,6 +79,24 @@ public interface RatingService
|
|||||||
@NotAuditable
|
@NotAuditable
|
||||||
void applyRating(NodeRef targetNode, int rating, String ratingSchemeName) throws RatingServiceException;
|
void applyRating(NodeRef targetNode, int rating, String ratingSchemeName) throws RatingServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets the number of individual ratings which have been applied to
|
||||||
|
* the specified node in the specified {@link RatingScheme}.
|
||||||
|
*
|
||||||
|
* @param targetNode the node on which the rating is sought.
|
||||||
|
* @param ratingScheme the rating scheme to use.
|
||||||
|
*
|
||||||
|
* @return the number of individual ratings applied to this node.
|
||||||
|
* @see RatingService#getRatingSchemes()
|
||||||
|
* @see RatingScheme
|
||||||
|
*/
|
||||||
|
@NotAuditable
|
||||||
|
int getRatingsCount(NodeRef targetNode, String ratingSchemeName);
|
||||||
|
|
||||||
|
int getTotalRating(NodeRef targetNode, String ratingSchemeName);
|
||||||
|
|
||||||
|
float getAverageRating(NodeRef targetNode, String ratingSchemeName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method gets the {@link Rating} applied by the current user to the specified node in the specified
|
* This method gets the {@link Rating} applied by the current user to the specified node in the specified
|
||||||
* {@link RatingScheme} - if there is one.
|
* {@link RatingScheme} - if there is one.
|
||||||
@@ -80,10 +109,7 @@ public interface RatingService
|
|||||||
* @see RatingScheme
|
* @see RatingScheme
|
||||||
*/
|
*/
|
||||||
@NotAuditable
|
@NotAuditable
|
||||||
|
Rating getRatingByCurrentUser(NodeRef targetNode, String ratingSchemeName);
|
||||||
// TODO Get average/total ratings on node
|
|
||||||
|
|
||||||
Rating getRatingByCurrentUser(NodeRef targetNode, RatingScheme ratingScheme);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method removes any {@link Rating} applied by the current user to the specified node in the specified
|
* This method removes any {@link Rating} applied by the current user to the specified node in the specified
|
||||||
@@ -97,5 +123,5 @@ public interface RatingService
|
|||||||
* @see RatingScheme
|
* @see RatingScheme
|
||||||
*/
|
*/
|
||||||
@NotAuditable
|
@NotAuditable
|
||||||
Rating removeRatingByCurrentUser(NodeRef targetNode, RatingScheme ratingScheme);
|
Rating removeRatingByCurrentUser(NodeRef targetNode, String ratingSchemeName);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user