/***************************************************************************
* Copyright (C) 2003-2009 eXo Platform SAS.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see<http://www.gnu.org/licenses/>.
*
**************************************************************************/
package org.exoplatform.services.ecm.dms.voting;
import java.io.IOException;
import java.util.Arrays;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.Value;
import org.exoplatform.services.cms.CmsService;
import org.exoplatform.services.cms.JcrInputProperty;
import org.exoplatform.services.cms.i18n.MultiLanguageService;
import org.exoplatform.services.cms.voting.VotingService;
import org.exoplatform.services.wcm.BaseWCMTestCase;
/**
* Created by eXo Platform
* Author : Nguyen Manh Cuong
* manhcuongpt@gmail.com
* Jun 17, 2009
*/
/**
* Unit test for VotingService
* Methods need to test
* 1. Vote method
* 2. Get Vote Total method
*/
public class TestVotingService extends BaseWCMTestCase {
private final static String I18NMixin = "mix:i18n";
private final static String VOTEABLE = "mix:votable";
private final static String VOTER_PROP = "exo:voter";
private final static String VOTER_VOTEVALUE_PROP = "exo:voterVoteValues";
private final static String VOTE_TOTAL_PROP = "exo:voteTotal";
private final static String VOTING_RATE_PROP = "exo:votingRate";
private final static String VOTE_TOTAL_LANG_PROP = "exo:voteTotalOfLang";
private final static String ARTICLE = "exo:article";
private final static String CONTENT = "jcr:content";
private final static String MIMETYPE = "jcr:mimeType";
private final static String DATA = "jcr:data";
private final static String LASTMODIFIED = "jcr:lastModified";
private final static String FILE = "nt:file";
private final static String RESOURCE = "nt:resource";
private final static String TITLE = "exo:title";
private final static String SUMMARY = "exo:summary";
private final static String TEXT = "exo:text";
private VotingService votingService = null;
private MultiLanguageService multiLanguageService = null;
public void setUp() throws Exception {
super.setUp();
votingService = (VotingService) container.getComponentInstanceOfType(VotingService.class);
multiLanguageService = (MultiLanguageService) container.getComponentInstanceOfType(MultiLanguageService.class);
applySystemSession();
}
/**
* Test Method: vote()
* Input: Test node is set English default language, but not set MultiLanguage.
* Voter: root, rate: 1.0, voter's language is default language.
* marry, rate: 4.0, voter's language is default language.
* john, rate: 5.0, voter's language is default language.
* Expected:
* Value of VOTER_PROP property of test node contains "root"
* Vote total of test with default language = 3
* votingRate = (1 + 4 + 5)/3 = 3.33
*/
@SuppressWarnings("unchecked")
public void testVote() throws Exception {
Node test = session.getRootNode().addNode("Test");
if (test.canAddMixin(I18NMixin)) {
test.addMixin(I18NMixin);
}
session.save();
votingService.vote(test, 1, "root", multiLanguageService.getDefault(test));
votingService.vote(test, 4, "marry", multiLanguageService.getDefault(test));
votingService.vote(test, 5, "john", multiLanguageService.getDefault(test));
List voters = Arrays.asList(new String[] {"root", "marry", "john"});
Value[] value = test.getProperty(VOTER_VOTEVALUE_PROP).getValues();
for (int i = 0; i < 3; i++) {
assertTrue(value[i].getString().startsWith(voters.get(i) + ""));
}
assertEquals(3, test.getProperty(VOTE_TOTAL_LANG_PROP).getValue().getLong());
assertEquals(3.33, test.getProperty(VOTING_RATE_PROP).getValue().getDouble());
}
/**
* Test Method: vote()
* Input: test node is set English default language.
* adding vote for test node by French
* first vote : userName = null, rate = 3.0, language = "fr"
* second vote: userName = null, rate = 1.0, language = "fr"
* third vote : userName = null, rate = 4.0, language = "fr"
* Expected:
* user is not voter, value of VOTER_PRO doesn't exist.
* votingRate = (3 + 1 + 4)/3 = 2.67
* total of vote: 3.
*/
public void testVote1() throws Exception {
Node test = initNode();
votingService.vote(test, 3, null, "fr");
votingService.vote(test, 1, null, "fr");
votingService.vote(test, 4, null, "fr");
Node fr = multiLanguageService.getLanguage(test, "fr");
assertEquals(0, fr.getProperty(VOTER_VOTEVALUE_PROP).getValues().length);
assertEquals(2.67, fr.getProperty(VOTING_RATE_PROP).getValue().getDouble());
assertEquals(3, fr.getProperty(VOTE_TOTAL_LANG_PROP).getValue().getLong());
}
/**
* Test Method: vote()
* Input: Test node is set default language not equals voter's language
* In this case: voter's language is fr
* Example
* first vote : root, rate: 2.0, language = fr,
* second vote: root, rate: 3.0, language = fr,
* third vote : root, rate: 4.0, language = fr
* Expected:
* Voter that uses fr language is "root", "marry", "john"
* Total of vote of French is 3
* votingRate = (2 + 3 + 4)/3
*/
@SuppressWarnings("unchecked")
public void testVote2() throws Exception {
Node test = initNode();
votingService.vote(test, 2, "root", "fr");
votingService.vote(test, 3, "marry", "fr");
votingService.vote(test, 4, "john", "fr");
Node fr = multiLanguageService.getLanguage(test, "fr");
List voters = Arrays.asList(new String[] { "root", "marry", "john"});
Property voterProperty = fr.getProperty(VOTER_VOTEVALUE_PROP);
Value[] value = voterProperty.getValues();
for (int i = 0; i < 3; i++) {
assertTrue(value[i].getString().startsWith(voters.get(i) + ""));
}
assertEquals(3.0, fr.getProperty(VOTING_RATE_PROP).getValue().getDouble());
assertEquals(3, fr.getProperty(VOTE_TOTAL_LANG_PROP).getValue().getLong());
}
/**
* Test Method: vote()
* Input: Test node is set default language and is not equals voter's language.
* first vote : root, rate: 3.0, language fr
* second vote: marry, rate: 2.0, language fr
* second vote: john, rate: 5.0, language fr
* Expected:
* Each language add "jcr:contest" node and their data is equals data of "jcr:content" of test node.
* Voters who use fr language is "root", "marry", "john"
* Total of vote of fr is 3
* votingRate = 3.33
*/
@SuppressWarnings("unchecked")
public void testVote3() throws Exception {
Node test = session.getRootNode().addNode("Test", FILE);
Node testFile = test.addNode(CONTENT, RESOURCE);
testFile.setProperty(DATA, "test");
testFile.setProperty(MIMETYPE, "text/xml");
testFile.setProperty(LASTMODIFIED, new GregorianCalendar());
if (test.canAddMixin(I18NMixin)) {
test.addMixin(I18NMixin);
}
if (test.canAddMixin(VOTEABLE)) {
test.addMixin(VOTEABLE);
}
session.save();
multiLanguageService.addLanguage(test, createFileInput(), "fr", false, "jcr:content");
multiLanguageService.addLanguage(test, createFileInput(), "en", false, "jcr:content");
multiLanguageService.addLanguage(test, createFileInput(), "vi", false, "jcr:content");
votingService.vote(test, 3, "root", "fr");
votingService.vote(test, 2, "marry", "fr");
votingService.vote(test, 5, "john", "fr");
Node viLangNode = multiLanguageService.getLanguage(test, "vi");
Node enLangNode = multiLanguageService.getLanguage(test, "en");
Node frLangNode = multiLanguageService.getLanguage(test, "fr");
assertEquals(testFile.getProperty(MIMETYPE).getString(), frLangNode.getNode(CONTENT).getProperty(MIMETYPE).getString());
assertEquals(testFile.getProperty(DATA).getValue(), frLangNode.getNode(CONTENT).getProperty(DATA).getValue());
assertEquals(testFile.getProperty(MIMETYPE).getString(), viLangNode.getNode(CONTENT).getProperty(MIMETYPE).getString());
assertEquals(testFile.getProperty(DATA).getValue(), viLangNode.getNode(CONTENT).getProperty(DATA).getValue());
assertEquals(3.33, frLangNode.getProperty(VOTING_RATE_PROP).getValue().getDouble());
assertEquals(3, frLangNode.getProperty(VOTE_TOTAL_LANG_PROP).getValue().getLong());
}
/**
* Test Method: getVoteTotal()
* Input: Test node is set English default language and doesn't have MultiLanguage
* Voter's language equals default language.
* Expected:
* Total of test's vote = value of VOTE_TOTAL_LANG_PROP property.
*/
public void testGetVoteTotal() throws Exception{
Node test = session.getRootNode().addNode("Test");
if (test.canAddMixin(I18NMixin)) {
test.addMixin(I18NMixin);
}
session.save();
votingService.vote(test, 3, "root", multiLanguageService.getDefault(test));
long voteTotal = votingService.getVoteTotal(test);
assertEquals(voteTotal, test.getProperty(VOTE_TOTAL_LANG_PROP).getValue().getLong());
}
/**
* Test Method: getVoteTotal()
* Input: test node is set English default language and has MultiLanguage
* test node is voted 4 times: root votes 1 times using default language.
* john votes 1 times using default language.
* marry votes 3 times using both fr, vi, and en language.
* Expected:
* Total of votes of test node = value of VOTE_TOTAL_PROP property of test node.
* In this case:
* total = total of voters with default language + total of voter with other languages.
*/
public void testGetVoteTotal1() throws Exception{
Node test = initNode();
String DefaultLang = multiLanguageService.getDefault(test);
votingService.vote(test, 5, "root", DefaultLang);
votingService.vote(test, 4, "john", DefaultLang);
votingService.vote(test, 4, "marry", "en");
votingService.vote(test, 3, "marry", "fr");
votingService.vote(test, 2, "marry", "vi");
long voteTotal = votingService.getVoteTotal(test);
assertEquals(voteTotal, test.getProperty(VOTE_TOTAL_PROP).getValue().getLong());
}
/**
* Test Method: IsVoted()
* Input: test node is set English default language and has MultiLanguage
* test node is voted 1 time: root votes 1 times using default language.
* Expected: root voted test node and mary didn't
* @throws Exception
*/
public void testIsVoted() throws Exception{
Node test = session.getRootNode().addNode("Test");
if (test.canAddMixin(I18NMixin)) {
test.addMixin(I18NMixin);
}
session.save();
votingService.vote(test, 3, "root", multiLanguageService.getDefault(test));
assertTrue(votingService.isVoted(test, "root", multiLanguageService.getDefault(test)));
assertFalse(votingService.isVoted(test, "mary", multiLanguageService.getDefault(test)));
}
/**
* Test Method: getVoteTotal()
* Input: test node is set English default language and has MultiLanguage
* test node is voted 4 times: root votes 1 times using default language.
* john votes 1 times using default language.
* marry votes 3 times using both fr, vi, and en language.
* Expected:
* Total of votes of test node = value of VOTE_TOTAL_PROP property of test node.
* In this case:
* total = total of voters with default language + total of voter with other languages.
*/
public void testGetVoteValueOfUser() throws Exception{
Node test = initNode();
String DefaultLang = multiLanguageService.getDefault(test);
votingService.vote(test, 5, "root", DefaultLang);
votingService.vote(test, 4, "john", DefaultLang);
votingService.vote(test, 4, "john", "en");
votingService.vote(test, 3, "john", "fr");
votingService.vote(test, 2, "john", "vi");
assertEquals(5.0, votingService.getVoteValueOfUser(test, "root", DefaultLang));
assertEquals(4.0, votingService.getVoteValueOfUser(test, "john", DefaultLang));
assertEquals(4.0, votingService.getVoteValueOfUser(test, "john", "en"));
assertEquals(3.0, votingService.getVoteValueOfUser(test, "john", "fr"));
assertEquals(2.0, votingService.getVoteValueOfUser(test, "john", "vi"));
}
/**
* Clean data test
*/
public void tearDown() throws Exception {
if (session.itemExists("/Test")) {
Node test = session.getRootNode().getNode("Test");
test.remove();
session.save();
}
super.tearDown();
}
/**
* Create a map to use for MultilLanguageService
*/
private Map<String, JcrInputProperty> createMapInput() {
Map<String, JcrInputProperty> map = new HashMap<String, JcrInputProperty>();
String titlePath = CmsService.NODE + "/" + TITLE;
String summaryPath = CmsService.NODE + "/" + SUMMARY;
String textPath = CmsService.NODE + "/" + TEXT;
JcrInputProperty inputProperty = new JcrInputProperty();
inputProperty.setJcrPath(CmsService.NODE);
inputProperty.setValue("test");
map.put(CmsService.NODE, inputProperty);
inputProperty = new JcrInputProperty();
inputProperty.setJcrPath(titlePath);
inputProperty.setValue("this is title");
map.put(titlePath, inputProperty);
inputProperty = new JcrInputProperty();
inputProperty.setJcrPath(summaryPath);
inputProperty.setValue("this is summary");
map.put(summaryPath, inputProperty);
inputProperty = new JcrInputProperty();
inputProperty.setJcrPath(textPath);
inputProperty.setValue("this is article content");
map.put(textPath, inputProperty);
return map;
}
/**
* Create binary data
*/
private Map<String, JcrInputProperty> createFileInput() throws IOException {
Map<String, JcrInputProperty> map = new HashMap<String, JcrInputProperty>();
String data = CmsService.NODE + "/" + CONTENT + "/" + DATA;
String mimeType = CmsService.NODE + "/" + CONTENT + "/" + MIMETYPE;
JcrInputProperty inputProperty = new JcrInputProperty();
inputProperty.setJcrPath(data);
inputProperty.setValue("test");
map.put(data, inputProperty);
inputProperty = new JcrInputProperty();
inputProperty.setJcrPath(mimeType);
inputProperty.setValue("text/xml");
map.put(mimeType, inputProperty);
return map;
}
/**
* This method will create a node which is added MultiLanguage
*/
private Node initNode() throws Exception{
Node test = session.getRootNode().addNode("Test", ARTICLE);
if (test.canAddMixin(I18NMixin)) {
test.addMixin(I18NMixin);
}
if (test.canAddMixin(VOTEABLE)) {
test.addMixin(VOTEABLE);
}
test.setProperty(TITLE, "sport");
test.setProperty(SUMMARY, "report of season");
test.setProperty(TEXT, "sport is exciting");
session.save();
multiLanguageService.addLanguage(test, createMapInput(), "en", false);
multiLanguageService.addLanguage(test, createMapInput(), "vi", false);
multiLanguageService.addLanguage(test, createMapInput(), "fr", false);
return test;
}
}