package com.celements.navigation;
import static org.easymock.EasyMock.*;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.easymock.IExpectationSetters;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.model.reference.WikiReference;
import org.xwiki.query.Query;
import org.xwiki.query.QueryException;
import org.xwiki.query.QueryManager;
import com.celements.common.cache.CacheLoadingException;
import com.celements.common.cache.IDocumentReferenceCache;
import com.celements.common.test.AbstractBridgedComponentTestCase;
import com.celements.query.IQueryExecutionServiceRole;
import com.google.common.collect.ImmutableSet;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.objects.BaseObject;
import com.xpn.xwiki.web.Utils;
public class NavigationCacheTest extends AbstractBridgedComponentTestCase {
private NavigationCache cache;
private QueryManager queryManagerMock;
private IQueryExecutionServiceRole queryExecServiceMock;
@Before
public void setUp_NavigationCacheTest() {
cache = (NavigationCache) Utils.getComponent(IDocumentReferenceCache.class,
NavigationCache.NAME);
queryManagerMock = createMockAndAddToDefault(QueryManager.class);
cache.injectQueryManager(queryManagerMock);
queryExecServiceMock = createMockAndAddToDefault(IQueryExecutionServiceRole.class);
cache.injectQueryExecService(queryExecServiceMock);
}
@After
public void tearDown_NavigationCacheTest() {
cache.injectQueryManager(Utils.getComponent(QueryManager.class));
cache.injectQueryExecService(Utils.getComponent(IQueryExecutionServiceRole.class));
}
@Test
public void testGetCachedDocRefs() throws Exception {
WikiReference wikiRef = new WikiReference("wiki");
String space1 = "menuSpace1";
String space2 = "menuSpace2";
String space3 = "menuSpace3";
DocumentReference docRef1 = new DocumentReference(wikiRef.getName(), "space", "nav1");
DocumentReference docRef2 = new DocumentReference(wikiRef.getName(), "space", "nav2");
expectXWQL(wikiRef, Arrays.asList(docRef1, docRef2));
expectMenuSpace(docRef1, space1, 0);
expectMenuSpace(docRef2, space2, 0);
replayDefault();
assertEquals(ImmutableSet.of(docRef1), cache.getCachedDocRefs(wikiRef, space1));
assertEquals(ImmutableSet.of(docRef2), cache.getCachedDocRefs(wikiRef, space2));
assertEquals(ImmutableSet.of(), cache.getCachedDocRefs(wikiRef, space3));
assertEquals(ImmutableSet.of(docRef1, docRef2), cache.getCachedDocRefs(wikiRef));
verifyDefault();
}
@Test
public void testGetCachedDocRefs_multiple() throws Exception {
WikiReference wikiRef = new WikiReference("wiki");
String space = "menuSpace";
DocumentReference docRef1 = new DocumentReference(wikiRef.getName(), "space", "nav1");
DocumentReference docRef2 = new DocumentReference(wikiRef.getName(), "space", "nav2");
expectXWQL(wikiRef, Arrays.asList(docRef1, docRef2));
expectMenuSpace(docRef1, space, 0);
expectMenuSpace(docRef2, space, 0);
replayDefault();
assertEquals(ImmutableSet.of(docRef1, docRef2), cache.getCachedDocRefs(wikiRef, space));
assertEquals(ImmutableSet.of(docRef1, docRef2), cache.getCachedDocRefs(wikiRef));
verifyDefault();
}
@Test
public void testGetCachedDocRefs_withNullObj() throws Exception {
WikiReference wikiRef = new WikiReference("wiki");
String space = "menuSpace";
DocumentReference docRef = new DocumentReference(wikiRef.getName(), "space", "nav");
expectXWQL(wikiRef, Arrays.asList(docRef));
expectMenuSpace(docRef, space, 1);
replayDefault();
assertEquals(ImmutableSet.of(docRef), cache.getCachedDocRefs(wikiRef, space));
verifyDefault();
}
@Test
public void testGetCachedDocRefs_empty() throws Exception {
WikiReference wikiRef = new WikiReference("wiki");
String space = "menuSpace";
expectXWQL(wikiRef, Collections.<DocumentReference>emptyList());
replayDefault();
assertEquals(ImmutableSet.of(), cache.getCachedDocRefs(wikiRef, space));
verifyDefault();
}
@Test
public void testGetCachedDocRefs_multiWiki() throws Exception {
WikiReference wikiRef1 = new WikiReference("wiki1");
String space1 = "menuSpace1";
DocumentReference docRef1 = new DocumentReference(wikiRef1.getName(), "space", "nav1");
WikiReference wikiRef2 = new WikiReference("wiki2");
String space2 = "menuSpace2";
DocumentReference docRef2 = new DocumentReference(wikiRef2.getName(), "space", "nav2");
String space3 = "menuSpace3";
expectXWQL(wikiRef1, Arrays.asList(docRef1));
expectMenuSpace(docRef1, space1, 0);
expectXWQL(wikiRef2, Arrays.asList(docRef2));
expectMenuSpace(docRef2, space2, 0);
replayDefault();
assertEquals(ImmutableSet.of(docRef1), cache.getCachedDocRefs(wikiRef1, space1));
assertEquals(ImmutableSet.of(docRef2), cache.getCachedDocRefs(wikiRef2, space2));
assertEquals(ImmutableSet.of(), cache.getCachedDocRefs(wikiRef1, space3));
assertEquals(ImmutableSet.of(), cache.getCachedDocRefs(wikiRef2, space3));
assertEquals(ImmutableSet.of(docRef1), cache.getCachedDocRefs(wikiRef1));
assertEquals(ImmutableSet.of(docRef2), cache.getCachedDocRefs(wikiRef2));
verifyDefault();
}
@Test
public void testGetCachedDocRefs_nullKey() throws Exception {
WikiReference wikiRef = new WikiReference("wiki");
DocumentReference docRef = new DocumentReference(wikiRef.getName(), "space", "nav");
expectXWQL(wikiRef, Arrays.asList(docRef));
expectMenuSpace(docRef, "", 0);
replayDefault();
assertEquals(ImmutableSet.of(), cache.getCachedDocRefs(wikiRef));
verifyDefault();
}
@Test
public void testGetCachedDocRefs_QueryException() throws Exception {
WikiReference wikiRef = new WikiReference("wiki");
String space = "menuSpace";
expectXWQL(wikiRef, null);
replayDefault();
try {
cache.getCachedDocRefs(wikiRef, space);
fail("expecting CacheLoadingException");
} catch (CacheLoadingException exc) {
// expected
}
verifyDefault();
}
@Test
public void testGetCachedDocRefs_XWikiException() throws Exception {
WikiReference wikiRef = new WikiReference("wiki");
String space = "menuSpace";
DocumentReference docRef = new DocumentReference(wikiRef.getName(), "space", "nav1");
expectXWQL(wikiRef, Arrays.asList(docRef));
expect(getWikiMock().getDocument(eq(docRef), same(getContext()))).andThrow(
new XWikiException()).once();
replayDefault();
try {
cache.getCachedDocRefs(wikiRef, space);
fail("expecting CacheLoadingException");
} catch (CacheLoadingException exc) {
// expected
}
verifyDefault();
}
@Test
public void testFlush() throws Exception {
WikiReference wikiRef = new WikiReference("wiki");
String space = "menuSpace";
DocumentReference docRef = new DocumentReference(wikiRef.getName(), "space", "nav");
WikiReference otherWikiRef = new WikiReference("otherWiki");
expectXWQL(wikiRef, Arrays.asList(docRef));
expectMenuSpace(docRef, space, 0);
expectXWQL(wikiRef, Arrays.asList(docRef));
expectMenuSpace(docRef, space, 0);
replayDefault();
assertEquals(ImmutableSet.of(docRef), cache.getCachedDocRefs(wikiRef, space));
cache.flush(wikiRef); // this flushes docRef
assertEquals(ImmutableSet.of(docRef), cache.getCachedDocRefs(wikiRef, space));
cache.flush(otherWikiRef); // this doesnt flush docRef
assertEquals(ImmutableSet.of(docRef), cache.getCachedDocRefs(wikiRef, space));
verifyDefault();
}
private void expectXWQL(WikiReference wikiRef, List<DocumentReference> ret) throws Exception {
Query queryMock = createMockAndAddToDefault(Query.class);
String xwql = "select distinct doc.fullName from Document doc, doc.object("
+ "Celements2.NavigationConfigClass) as obj";
expect(queryManagerMock.createQuery(eq(xwql), eq(Query.XWQL))).andReturn(queryMock).once();
expect(queryMock.setWiki(eq(wikiRef.getName()))).andReturn(queryMock).once();
IExpectationSetters<List<DocumentReference>> expSetter = expect(
queryExecServiceMock.executeAndGetDocRefs(same(queryMock)));
if (ret != null) {
expSetter.andReturn(ret).once();
} else {
expSetter.andThrow(new QueryException("", null, null)).once();
}
}
private void expectMenuSpace(DocumentReference docRef, String space, int nb) throws Exception {
XWikiDocument doc = new XWikiDocument(docRef);
BaseObject obj = new BaseObject();
obj.setXClassReference(Utils.getComponent(
INavigationClassConfig.class).getNavigationConfigClassRef(docRef.getWikiReference()));
obj.setStringValue(INavigationClassConfig.MENU_SPACE_FIELD, space);
doc.setXObject(nb, obj);
expect(getWikiMock().getDocument(eq(docRef), same(getContext()))).andReturn(doc).once();
}
}