/*
* $HeadURL$
* $Id$
* Copyright (c) 2006-2012 by Public Library of Science http://plos.org http://ambraproject.org
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.ambraproject.action.article;
import com.opensymphony.xwork2.Action;
import org.ambraproject.action.BaseActionSupport;
import org.ambraproject.models.Annotation;
import org.ambraproject.models.AnnotationType;
import org.ambraproject.models.Article;
import org.ambraproject.models.ArticleAsset;
import org.ambraproject.models.ArticleRelationship;
import org.ambraproject.models.ArticleView;
import org.ambraproject.models.Trackback;
import org.ambraproject.models.UserProfile;
import org.ambraproject.service.user.UserService;
import org.ambraproject.views.AnnotationView;
import org.ambraproject.views.AuthorView;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertEqualsNoOrder;
import static org.testng.Assert.assertFalse;
/**
* @author Alex Kudlick 2/16/12
*/
public class FetchArticleTabsActionTest extends FetchActionTest {
@Autowired
protected FetchArticleTabsAction action;
@Autowired
protected UserService userService;
@Override
protected BaseActionSupport getAction() {
return action;
}
@DataProvider(name = "articleAffiliations")
public Object[][] getArticleAffiliations(){
//multiple affiliates with only some having authors contained
String doi = "info:doi/10.1371/journal.pmed.0020073";
Article a = new Article(doi);
//add the asset record for the XML. The fileService needs this
List<ArticleAsset> assetsForArticle1 = new LinkedList<ArticleAsset>();
ArticleAsset asset1ForArticle1 = new ArticleAsset();
asset1ForArticle1.setContentType("XML");
asset1ForArticle1.setContextElement("Fake ContextElement for asset1ForArticle1");
asset1ForArticle1.setDoi("info:doi/10.1371/journal.pmed.0020073");
asset1ForArticle1.setExtension("XML");
asset1ForArticle1.setSize(1000001l);
asset1ForArticle1.setCreated(new Date());
asset1ForArticle1.setLastModified(new Date());
assetsForArticle1.add(asset1ForArticle1);
a.setAssets(assetsForArticle1);
dummyDataStore.store(a);
//LinkedHashMap for ordering
Map<String, List<AuthorView>> affiliationSets = new LinkedHashMap<String, List<AuthorView>>() {{
put("Program in Cancer Biology and Genetics, Memorial Sloan-Kettering Cancer Center, New York, New York, United States of America",
new ArrayList<AuthorView>() {{
add(AuthorView.builder()
.setGivenNames("William")
.setSurnames("Pao")
.build());
}});
put("Thoracic Oncology Service, Department of Medicine, Memorial Sloan-Kettering Cancer Center, New York, New York, United States of America",
new ArrayList<AuthorView>(){{
add(AuthorView.builder()
.setGivenNames("William")
.setSurnames("Pao")
.build());
}});
}};
return new Object[][]{{doi, affiliationSets}};
}
/**
* Check if article has expression of concern
* @throws Exception
*/
@Test
public void testArticleInfoForEoc() throws Exception {
Article eocArticle = new Article();
eocArticle.setDoi("id:doi-object-of-concern-relationship-article");
eocArticle.setState(Article.STATE_ACTIVE);
eocArticle.setTitle("foo");
Set<String> typesForEocArticle = new HashSet<String>();
typesForEocArticle.add("http://rdf.plos.org/RDF/articleType/Expression%20of%20Concern");
eocArticle.setTypes(typesForEocArticle);
List<ArticleRelationship> articleRelationships = new ArrayList<ArticleRelationship>(1);
//Expression of Concern relationship
ArticleRelationship eocRelationship = new ArticleRelationship();
eocRelationship.setParentArticle(getArticleToFetch());
eocRelationship.setOtherArticleID(Long.valueOf(dummyDataStore.store(eocArticle)));
eocRelationship.setType("expressed-concern");
eocRelationship.setOtherArticleDoi(eocArticle.getDoi());
articleRelationships.add(eocRelationship);
getArticleToFetch().setRelatedArticles(articleRelationships);
dummyDataStore.store(articleRelationships);
action.setExpressionOfConcern("Dummy Expression of Concern");
action.setArticleURI(getArticleToFetch().getDoi());
action.fetchArticle();
String eoc = action.getExpressionOfConcern();
assertEquals(eoc,"Dummy Expression of Concern","eoc didn't match in fetch tab" );
}
/**
* Make sure article affiliations are listed in order in which they appear in xml
*
* @param doi
* @param affiliationSets
*/
@Test(dataProvider = "articleAffiliations")
public void testGetAffiliations(String doi, Map<String, List<AuthorView>> affiliationSets) throws Exception {
//get action class conjiggered
action.setArticleURI(doi);
action.fetchArticle();
//perhaps a sub-optimal implementation of duo iteration, but otherwise it seems like a lot of boilerplate
//for just a test
Iterator testData = affiliationSets.entrySet().iterator();
for (Map.Entry<String, List<AuthorView>> mutEntry : action.getAuthorsByAffiliation()) {
Map.Entry<String, List<AuthorView>> testDatum = (Map.Entry<String, List<AuthorView>>) testData.next();
assertEquals(mutEntry.getKey(),testDatum.getKey(), "Article affiliation names don't match");
Iterator testAuthors = testDatum.getValue().iterator();
for(AuthorView mutAuthor : mutEntry.getValue()){
AuthorView testAuthor = (AuthorView)testAuthors.next();
assertEquals(mutAuthor.getFullName(), testAuthor.getFullName(),"Author names don't match");
}
//make sure we've covered all test data
assertFalse(testAuthors.hasNext(),"Not all test authors accounted for");
}
//make sure we've covered all test data
assertFalse(testData.hasNext(), "Not all test affiliations accounted for");
}
@Test
public void testFetchArticle() throws Exception {
UserProfile user = userService.getUserByAuthId(DEFAULT_ADMIN_AUTHID);
login(user);
//store some annotations on the article
dummyDataStore.deleteAll(Annotation.class);
Annotation comment = new Annotation(user, AnnotationType.COMMENT, getArticleToFetch().getID());
comment.setTitle("comment title");
dummyDataStore.store(comment);
//replies don't get counted as a comment
Annotation reply = new Annotation(user, AnnotationType.REPLY, getArticleToFetch().getID());
reply.setTitle("reply title");
reply.setParentID(comment.getID());
dummyDataStore.store(reply);
//check that an article view gets recorded
int numArticleViews = dummyDataStore.getAll(ArticleView.class).size();
action.setArticleURI(getArticleToFetch().getDoi());
String result = action.fetchArticle();
assertEquals(result, Action.SUCCESS, "Action didn't return success");
compareArticles(action.getArticleInfoX(), getArticleToFetch());
assertEquals(dummyDataStore.getAll(ArticleView.class).size(), numArticleViews + 1,
"Action didn't record this as an article view");
//check the comments
assertEquals(action.getCommentary(), new AnnotationView[] {
new AnnotationView(comment, getArticleToFetch().getDoi(), getArticleToFetch().getTitle(), null)
}, "Action returned incorrect commentary");
assertFalse(action.getIsResearchArticle(), "Expected article a research article");
//TODO: Check the transformed html
}
@Test
public void testFetchArticleComments() {
UserProfile user = userService.getUserByAuthId(DEFAULT_ADMIN_AUTHID);
login(user);
Calendar lastYear = Calendar.getInstance();
lastYear.add(Calendar.YEAR, -1);
//store some annotations on the article
dummyDataStore.deleteAll(Annotation.class);
//corrections shouldn't get listed
Annotation comment = new Annotation(user, AnnotationType.COMMENT, getArticleToFetch().getID());
comment.setTitle("comment title");
comment.setCreated(lastYear.getTime());
dummyDataStore.store(comment);
//replies don't get counted as a comment
Annotation reply = new Annotation(user, AnnotationType.REPLY, getArticleToFetch().getID());
reply.setTitle("reply title");
reply.setParentID(comment.getID());
dummyDataStore.store(reply);
action.setArticleURI(getArticleToFetch().getDoi());
String result = action.fetchArticleComments();
assertEquals(result, Action.SUCCESS, "Action didn't return success");
//order his hard to check, we do it in annotation service test.
assertEqualsNoOrder(action.getCommentary(), new AnnotationView[]{
new AnnotationView(comment, getArticleToFetch().getDoi(), getArticleToFetch().getTitle(), null)
}, "Action returned incorrect comments");
//check that the reply got loaded up
assertEquals(action.getCommentary()[0].getReplies().length, 1, "Reply to comment didn't get loaded up");
assertEquals(action.getCommentary()[0].getReplies()[0],
new AnnotationView(reply, getArticleToFetch().getDoi(), getArticleToFetch().getTitle(), null),
"Action returned incorrect reply");
assertEquals(action.getNumComments(), 1, "Action didn't count comments");
}
@Test
public void testFetchArticleRelated() {
action.setArticleURI(getArticleToFetch().getDoi());
String result = action.fetchArticleRelated();
assertEquals(result, Action.SUCCESS, "Action didn't return success");
}
@Test
public void testFetchArticleMetrics() {
//keep these url the same as the ones in the testFetchArticleRelated, so we don't create extra trackbacks, and we always know the number of trackbacks,
//regardless of the order in which the tests are run
Trackback trackback1 = new Trackback(getArticleToFetch().getID(), "http://coolblog.net");
trackback1.setBlogName("My Cool Blog");
trackback1.setTitle("Blog title 1");
trackback1.setExcerpt("Once upon a time....");
dummyDataStore.store(trackback1);
Trackback trackback2 = new Trackback(getArticleToFetch().getID(), "http://coolblog.net/foo");
trackback2.setBlogName("My Cool Blog");
trackback2.setTitle("Blog title 2");
trackback2.setExcerpt("There was a prince....");
dummyDataStore.store(trackback2);
action.setArticleURI(getArticleToFetch().getDoi());
String result = action.fetchArticleMetrics();
assertEquals(result, Action.SUCCESS, "Action didn't return success");
assertEquals(action.getTrackbackCount(), 2, "Action returned incorrect trackback count");
UserProfile user = userService.getUserByAuthId(DEFAULT_ADMIN_AUTHID);
login(user);
Calendar lastYear = Calendar.getInstance();
lastYear.add(Calendar.YEAR, -1);
//store some annotations on the article
dummyDataStore.deleteAll(Annotation.class);
Annotation comment = new Annotation(user, AnnotationType.COMMENT, getArticleToFetch().getID());
comment.setTitle("comment title");
comment.setCreated(lastYear.getTime());
dummyDataStore.store(comment);
//replies don't get counted as a comment
Annotation reply = new Annotation(user, AnnotationType.REPLY, getArticleToFetch().getID());
reply.setTitle("reply title");
reply.setParentID(comment.getID());
dummyDataStore.store(reply);
action.setArticleURI(getArticleToFetch().getDoi());
String resultComments = action.fetchArticleComments();
assertEquals(resultComments, Action.SUCCESS, "Action didn't return success");
assertEquals(action.getNumComments(), 1, "Action returned incorrect comments count");
}
}