package com.celements.nextfreedoc;
import static com.celements.common.test.CelementsTestUtils.*;
import static org.easymock.EasyMock.*;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.model.reference.SpaceReference;
import org.xwiki.model.reference.WikiReference;
import org.xwiki.query.Query;
import org.xwiki.query.QueryException;
import org.xwiki.query.QueryExecutor;
import org.xwiki.query.QueryManager;
import org.xwiki.query.internal.DefaultQuery;
import com.celements.common.test.AbstractComponentTest;
import com.celements.model.access.XWikiDocumentCreator;
import com.xpn.xwiki.XWiki;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.doc.XWikiLock;
import com.xpn.xwiki.store.XWikiStoreInterface;
import com.xpn.xwiki.web.Utils;
public class NextFreeDocServiceTest extends AbstractComponentTest {
private XWikiContext context;
private XWiki xwiki;
private NextFreeDocService nextFreeDocService;
private QueryManager queryManagerMock;
private QueryExecutor queryExecutorMock;
private XWikiStoreInterface storeMock;
@Before
@Override
public void setUp() throws Exception {
super.setUp();
registerComponentMock(XWikiDocumentCreator.class);
context = getContext();
xwiki = getWikiMock();
nextFreeDocService = (NextFreeDocService) Utils.getComponent(INextFreeDocRole.class);
queryManagerMock = createMockAndAddToDefault(QueryManager.class);
nextFreeDocService.injectQueryManager(queryManagerMock);
queryExecutorMock = createMockAndAddToDefault(QueryExecutor.class);
storeMock = createMockAndAddToDefault(XWikiStoreInterface.class);
expect(xwiki.getStore()).andReturn(storeMock).anyTimes();
}
@Test
public void testGetNextTitledPageDocRef() throws Exception {
SpaceReference spaceRef = new SpaceReference("mySpace", new WikiReference(
context.getDatabase()));
String title = "asdf";
nextFreeDocService.injectNum(spaceRef, title, 5);
DocumentReference docRef1 = new DocumentReference(title + 5, spaceRef);
expect(xwiki.exists(eq(docRef1), same(context))).andReturn(true).atLeastOnce();
DocumentReference docRef2 = new DocumentReference(title + 6, spaceRef);
expect(xwiki.exists(eq(docRef2), same(context))).andReturn(false).atLeastOnce();
XWikiDocument doc2 = new XWikiDocument(docRef2);
expect(getMock(XWikiDocumentCreator.class).create(eq(docRef2))).andReturn(doc2);
expect(storeMock.loadLock(eq(doc2.getId()), same(context), eq(true))).andReturn(null).once();
storeMock.saveLock(anyObject(XWikiLock.class), same(context), eq(true));
expectLastCall().once();
replayDefault();
DocumentReference ret = nextFreeDocService.getNextTitledPageDocRef(spaceRef, title);
verifyDefault();
assertEquals(docRef2, ret);
}
@Test
public void testGetNextTitledPageDocRef_nullSpace() throws Exception {
SpaceReference spaceRef = null;
String title = "asdf";
replayDefault();
try {
nextFreeDocService.getNextTitledPageDocRef(spaceRef, title);
fail();
} catch (IllegalArgumentException exp) {
// expected
}
verifyDefault();
}
@Test
public void testGetNextTitledPageDocRef_nullTitle() throws Exception {
SpaceReference spaceRef = new SpaceReference("mySpace", new WikiReference(
context.getDatabase()));
String title = "";
replayDefault();
try {
nextFreeDocService.getNextTitledPageDocRef(spaceRef, title);
fail();
} catch (IllegalArgumentException exp) {
// expected
}
verifyDefault();
}
@Test
public void testGetNextUntitledPageDocRef() throws Exception {
SpaceReference spaceRef = new SpaceReference("mySpace", new WikiReference(
context.getDatabase()));
nextFreeDocService.injectNum(spaceRef, INextFreeDocRole.UNTITLED_NAME, 5);
DocumentReference docRef1 = new DocumentReference(INextFreeDocRole.UNTITLED_NAME + 5, spaceRef);
expect(xwiki.exists(eq(docRef1), same(context))).andReturn(true).once();
DocumentReference docRef2 = new DocumentReference(INextFreeDocRole.UNTITLED_NAME + 6, spaceRef);
expect(xwiki.exists(eq(docRef2), same(context))).andReturn(false).once();
XWikiDocument doc2 = new XWikiDocument(docRef2);
expect(getMock(XWikiDocumentCreator.class).create(eq(docRef2))).andReturn(doc2);
expect(storeMock.loadLock(eq(doc2.getId()), same(context), eq(true))).andReturn(null).once();
storeMock.saveLock(anyObject(XWikiLock.class), same(context), eq(true));
expectLastCall().once();
replayDefault();
DocumentReference ret = nextFreeDocService.getNextUntitledPageDocRef(spaceRef);
verifyDefault();
assertEquals(docRef2, ret);
}
@Test
public void testGetNextUntitledPageDocRef_nullSpace() throws Exception {
SpaceReference spaceRef = null;
replayDefault();
try {
nextFreeDocService.getNextUntitledPageDocRef(spaceRef);
fail();
} catch (IllegalArgumentException exp) {
// expected
}
verifyDefault();
}
@Test
public void testGetHighestNum_fromCache() {
SpaceReference spaceRef = new SpaceReference("mySpace", new WikiReference("myWiki"));
String name = "asdf";
DocumentReference baseDocRef = new DocumentReference(name, spaceRef);
nextFreeDocService.injectNum(spaceRef, name, 5);
replayDefault();
long ret = nextFreeDocService.getHighestNum(baseDocRef);
verifyDefault();
assertEquals(5, ret);
}
@Test
public void testGetHighestNum() throws Exception {
SpaceReference spaceRef = new SpaceReference("mySpace", new WikiReference("myWiki"));
String name = "asdf";
DocumentReference baseDocRef = new DocumentReference(name, spaceRef);
Query query = new DefaultQuery("statement", null, queryExecutorMock);
expect(queryManagerMock.createQuery(eq(nextFreeDocService.getHighestNumHQL()), eq(
"hql"))).andReturn(query).once();
expect(queryExecutorMock.execute(same(query))).andReturn(Arrays.<Object>asList(name + "NoDigit",
name + 5, name + 4)).once();
replayDefault();
long ret = nextFreeDocService.getHighestNum(baseDocRef);
verifyDefault();
assertEquals(6, ret);
assertEquals(0, query.getOffset());
assertEquals(8, query.getLimit());
assertEquals(spaceRef.getParent().getName(), query.getWiki());
assertEquals(2, query.getNamedParameters().size());
assertEquals(spaceRef.getName(), query.getNamedParameters().get("space"));
assertEquals(name + "%", query.getNamedParameters().get("name"));
}
@Test
public void testGetHighestNum_emptyResult() throws Exception {
SpaceReference spaceRef = new SpaceReference("mySpace", new WikiReference("myWiki"));
String name = "asdf";
DocumentReference baseDocRef = new DocumentReference(name, spaceRef);
Query query = new DefaultQuery("statement", null, queryExecutorMock);
expect(queryManagerMock.createQuery(eq(nextFreeDocService.getHighestNumHQL()), eq(
"hql"))).andReturn(query).once();
expect(queryExecutorMock.execute(same(query))).andReturn(Collections.emptyList()).once();
replayDefault();
long ret = nextFreeDocService.getHighestNum(baseDocRef);
verifyDefault();
assertEquals(1, ret);
assertEquals(0, query.getOffset());
assertEquals(8, query.getLimit());
assertEquals(spaceRef.getParent().getName(), query.getWiki());
assertEquals(2, query.getNamedParameters().size());
assertEquals(spaceRef.getName(), query.getNamedParameters().get("space"));
assertEquals(name + "%", query.getNamedParameters().get("name"));
}
@Test
public void testGetHighestNum_QueryException_createQuery() throws Exception {
SpaceReference spaceRef = new SpaceReference("mySpace", new WikiReference("myWiki"));
String name = "asdf";
DocumentReference baseDocRef = new DocumentReference(name, spaceRef);
expect(queryManagerMock.createQuery(eq(nextFreeDocService.getHighestNumHQL()), eq(
"hql"))).andThrow(new QueryException("", null, null)).once();
replayDefault();
long ret = nextFreeDocService.getHighestNum(baseDocRef);
verifyDefault();
assertEquals(1, ret);
}
@Test
public void testGetHighestNum_QueryException_execute() throws Exception {
SpaceReference spaceRef = new SpaceReference("mySpace", new WikiReference("myWiki"));
String name = "asdf";
DocumentReference baseDocRef = new DocumentReference(name, spaceRef);
Query query = new DefaultQuery("statement", null, queryExecutorMock);
expect(queryManagerMock.createQuery(eq(nextFreeDocService.getHighestNumHQL()), eq(
"hql"))).andReturn(query).once();
expect(queryExecutorMock.execute(same(query))).andThrow(new QueryException("", query,
null)).once();
replayDefault();
long ret = nextFreeDocService.getHighestNum(baseDocRef);
verifyDefault();
assertEquals(1, ret);
assertEquals(0, query.getOffset());
assertEquals(8, query.getLimit());
assertEquals(spaceRef.getParent().getName(), query.getWiki());
assertEquals(2, query.getNamedParameters().size());
assertEquals(spaceRef.getName(), query.getNamedParameters().get("space"));
assertEquals(name + "%", query.getNamedParameters().get("name"));
}
@Test
public void testGetHighestNum_multiQuery() throws Exception {
SpaceReference spaceRef = new SpaceReference("mySpace", new WikiReference("myWiki"));
String name = "asdf";
DocumentReference baseDocRef = new DocumentReference(name, spaceRef);
Query query1 = new DefaultQuery("statement", null, queryExecutorMock);
expect(queryManagerMock.createQuery(eq(nextFreeDocService.getHighestNumHQL()), eq(
"hql"))).andReturn(query1).once();
List<Object> noDigit = Arrays.<Object>asList(name + "NoDigit", name + "Muh");
expect(queryExecutorMock.execute(same(query1))).andReturn(noDigit).once();
Query query2 = new DefaultQuery("statement", null, queryExecutorMock);
expect(queryManagerMock.createQuery(eq(nextFreeDocService.getHighestNumHQL()), eq(
"hql"))).andReturn(query2).once();
noDigit = new ArrayList<>(noDigit);
noDigit.add(name); // to make sure offset depends on return size
expect(queryExecutorMock.execute(same(query2))).andReturn(noDigit).once();
Query query3 = new DefaultQuery("statement", null, queryExecutorMock);
expect(queryManagerMock.createQuery(eq(nextFreeDocService.getHighestNumHQL()), eq(
"hql"))).andReturn(query3).once();
expect(queryExecutorMock.execute(same(query3))).andReturn(Arrays.<Object>asList(name
+ "5")).once();
replayDefault();
long ret = nextFreeDocService.getHighestNum(baseDocRef);
verifyDefault();
assertEquals(6, ret);
assertEquals(0, query1.getOffset());
assertEquals(8, query1.getLimit());
assertEquals(spaceRef.getParent().getName(), query1.getWiki());
assertEquals(2, query1.getNamedParameters().size());
assertEquals(spaceRef.getName(), query1.getNamedParameters().get("space"));
assertEquals(name + "%", query1.getNamedParameters().get("name"));
assertEquals(2, query2.getOffset());
assertEquals(16, query2.getLimit());
assertEquals(spaceRef.getParent().getName(), query2.getWiki());
assertEquals(2, query2.getNamedParameters().size());
assertEquals(spaceRef.getName(), query2.getNamedParameters().get("space"));
assertEquals(name + "%", query2.getNamedParameters().get("name"));
assertEquals(5, query3.getOffset());
assertEquals(32, query3.getLimit());
assertEquals(spaceRef.getParent().getName(), query3.getWiki());
assertEquals(2, query3.getNamedParameters().size());
assertEquals(spaceRef.getName(), query3.getNamedParameters().get("space"));
assertEquals(name + "%", query3.getNamedParameters().get("name"));
}
@Test
public void testGetNumFromName() {
String prefix = "asdf";
List<Object> results = Arrays.<Object>asList(prefix + "NoDigit", prefix + "1234", prefix + "6");
assertEquals(new Long(1235), nextFreeDocService.extractNumFromResults(prefix, results));
}
@Test
public void testGetNumFromName_noDigit() {
String prefix = "asdf";
List<Object> results = Arrays.<Object>asList(prefix + "NoDigit", prefix + "StillNoDigit",
"notStartingWithPrefix");
assertNull(nextFreeDocService.extractNumFromResults(prefix, results));
}
@Test
public void testGetNumFromName_emptyList() {
String prefix = "asdf";
List<Object> results = Collections.emptyList();
assertNull(nextFreeDocService.extractNumFromResults(prefix, results));
}
@Test
public void testGetHighestNumHQL() {
assertEquals("SELECT doc.name FROM XWikiDocument doc WHERE doc.space=:space "
+ "AND doc.name LIKE :name ORDER BY LENGTH(doc.name) DESC, doc.name DESC",
nextFreeDocService.getHighestNumHQL());
}
}