package com.celements.store; import static com.celements.common.test.CelementsTestUtils.*; import static org.easymock.EasyMock.*; import static org.junit.Assert.*; import org.easymock.Capture; import org.junit.Before; import org.junit.Test; import org.xwiki.model.reference.DocumentReference; import com.celements.common.test.AbstractComponentTest; import com.xpn.xwiki.doc.XWikiDocument; import com.xpn.xwiki.store.XWikiStoreInterface; import com.xpn.xwiki.web.Utils; public class DocumentCacheStoreTest extends AbstractComponentTest { private static final String MOCK_STORE_HINT = "mockStoreHint"; private DocumentCacheStore docCacheStore; private XWikiStoreInterface mockStore; @Before public void setUp_DocumentCacheStoreTest() throws Exception { mockStore = registerComponentMock(XWikiStoreInterface.class, MOCK_STORE_HINT); getConfigurationSource().setProperty(DocumentCacheStore.BACKING_STORE_STRATEGY, MOCK_STORE_HINT); expect(getWikiMock().Param(eq(DocumentCacheStore.PARAM_EXIST_CACHE_CAPACITY))).andReturn( "100").anyTimes(); expect(getWikiMock().Param(eq(DocumentCacheStore.PARAM_DOC_CACHE_CAPACITY))).andReturn( "100").anyTimes(); docCacheStore = (DocumentCacheStore) Utils.getComponent(XWikiStoreInterface.class, DocumentCacheStore.COMPONENT_NAME); } @Test public void testSaveXWikiDoc() throws Exception { DocumentReference docRef = new DocumentReference("wiki", "space", "page"); XWikiDocument savedDoc = new XWikiDocument(docRef); savedDoc.setNew(false); savedDoc.setOriginalDocument(savedDoc.clone()); Capture<XWikiDocument> querySaveDocCapture = new Capture<>(); expect(mockStore.loadXWikiDoc(capture(querySaveDocCapture), same(getContext()))).andReturn( savedDoc).once(); Capture<XWikiDocument> savingDocCapture = new Capture<>(); mockStore.saveXWikiDoc(capture(savingDocCapture), same(getContext()), eq(true)); expectLastCall().once(); replayDefault(); docCacheStore.initalize(); XWikiDocument inputParamDoc = new XWikiDocument(docRef); XWikiDocument existingDocument = docCacheStore.loadXWikiDoc(inputParamDoc, getContext()); XWikiDocument querySaveDoc = querySaveDocCapture.getValue(); assertNotSame(inputParamDoc, querySaveDoc); assertEquals(inputParamDoc.getDocumentReference(), querySaveDoc.getDocumentReference()); assertEquals(inputParamDoc.getLanguage(), querySaveDoc.getLanguage()); // Save a document docCacheStore.saveXWikiDoc(existingDocument, getContext()); XWikiDocument existingDocSaved = savingDocCapture.getValue(); assertSame(existingDocument, existingDocSaved); String key = docCacheStore.getKeyWithLang(existingDocument); assertNull("on saving doc must be removed from Cache", docCacheStore.getDocFromCache(key)); verifyDefault(); } @Test public void testSaveXWikiDoc_noTransaction() throws Exception { DocumentReference docRef = new DocumentReference("wiki", "space", "page"); XWikiDocument savedDoc = new XWikiDocument(docRef); savedDoc.setNew(false); savedDoc.setOriginalDocument(savedDoc.clone()); Capture<XWikiDocument> querySaveDocCapture = new Capture<>(); boolean bTransaction = false; expect(mockStore.loadXWikiDoc(capture(querySaveDocCapture), same(getContext()))).andReturn( savedDoc).once(); Capture<XWikiDocument> savingDocCapture = new Capture<>(); mockStore.saveXWikiDoc(capture(savingDocCapture), same(getContext()), eq(bTransaction)); expectLastCall().once(); replayDefault(); docCacheStore.initalize(); XWikiDocument inputParamDoc = new XWikiDocument(docRef); XWikiDocument existingDocument = docCacheStore.loadXWikiDoc(inputParamDoc, getContext()); XWikiDocument querySaveDoc = querySaveDocCapture.getValue(); assertNotSame(inputParamDoc, querySaveDoc); assertEquals(inputParamDoc.getDocumentReference(), querySaveDoc.getDocumentReference()); assertEquals(inputParamDoc.getLanguage(), querySaveDoc.getLanguage()); // Save a document docCacheStore.saveXWikiDoc(existingDocument, getContext(), bTransaction); XWikiDocument existingDocSaved = savingDocCapture.getValue(); assertSame(existingDocument, existingDocSaved); String key = docCacheStore.getKeyWithLang(existingDocument); assertNull("on saving doc must be removed from Cache", docCacheStore.getDocFromCache(key)); verifyDefault(); } @Test public void testGetKey() { getContext().setDatabase("wiki"); DocumentReference docRef = new DocumentReference("wiki", "space", "page"); XWikiDocument testDoc = new XWikiDocument(docRef); assertEquals("wiki:space.page", docCacheStore.getKey(docRef)); assertEquals("wiki:space.page", docCacheStore.getKeyWithLang(testDoc)); } @Test public void testGetKey_differentDb() { getContext().setDatabase("wikitest"); DocumentReference docRef = new DocumentReference("wiki", "space", "page"); XWikiDocument testDoc = new XWikiDocument(docRef); assertEquals("wikitest:space.page", docCacheStore.getKey(docRef)); assertEquals("wikitest:space.page", docCacheStore.getKeyWithLang(testDoc)); } @Test public void testGetKey_lang() { getContext().setDatabase("wiki"); DocumentReference docRef = new DocumentReference("wiki", "space", "page"); XWikiDocument testDoc = new XWikiDocument(docRef); testDoc.setLanguage("en"); assertEquals("wiki:space.page:en", docCacheStore.getKeyWithLang(testDoc)); } @Test public void testGetKey_docRef_deflang() { getContext().setDatabase("wiki"); DocumentReference docRef = new DocumentReference("wiki", "space", "page"); assertEquals("wiki:space.page", docCacheStore.getKeyWithLang(docRef, "")); } @Test public void testGetKey_docRef_lang() { getContext().setDatabase("wiki"); DocumentReference docRef = new DocumentReference("wiki", "space", "page"); assertEquals("wiki:space.page:fr", docCacheStore.getKeyWithLang(docRef, "fr")); } @Test public void testInvalidateCacheFromClusterEvent_docExists() throws Exception { getContext().setDatabase("wiki"); DocumentReference docRef = new DocumentReference("wiki", "space", "page"); XWikiDocument savedDoc = new XWikiDocument(docRef); savedDoc.setNew(false); savedDoc.setOriginalDocument(savedDoc.clone()); expect(mockStore.loadXWikiDoc(isA(XWikiDocument.class), same(getContext()))).andReturn( savedDoc).once(); replayDefault(); docCacheStore.initalize(); XWikiDocument inputParamDoc = new XWikiDocument(docRef); XWikiDocument existingDocument = docCacheStore.loadXWikiDoc(inputParamDoc, getContext()); assertTrue(existingDocument.isFromCache()); String key = docCacheStore.getKeyWithLang(existingDocument); assertNotNull("doc expected in cache", docCacheStore.getDocFromCache(key)); assertTrue("doc expected in exists cache", docCacheStore.exists(existingDocument, getContext())); docCacheStore.removeDocFromCache(existingDocument, true); assertNull("doc not in cache anymore", docCacheStore.getDocFromCache(key)); verifyDefault(); } @Test public void testInvalidateCacheFromClusterEvent_docNOTExists() throws Exception { DocumentReference docRef = new DocumentReference("wiki", "space", "page"); XWikiDocument savedDoc = new XWikiDocument(docRef); savedDoc.setNew(false); savedDoc.setOriginalDocument(savedDoc.clone()); expect(mockStore.loadXWikiDoc(isA(XWikiDocument.class), same(getContext()))).andReturn( savedDoc).once(); replayDefault(); docCacheStore.initalize(); XWikiDocument inputParamDoc = new XWikiDocument(docRef); XWikiDocument existingDocument = docCacheStore.loadXWikiDoc(inputParamDoc, getContext()); assertTrue(existingDocument.isFromCache()); String key = docCacheStore.getKeyWithLang(existingDocument); assertNotNull("doc expected in cache", docCacheStore.getDocFromCache(key)); assertTrue("doc expected in exists cache", docCacheStore.exists(existingDocument, getContext())); docCacheStore.removeDocFromCache(existingDocument, false); assertNull("doc not in cache anymore", docCacheStore.getDocFromCache(key)); verifyDefault(); } @Test public void testInvalidateCacheFromClusterEventString() throws Exception { DocumentReference docRef = new DocumentReference("wiki", "space", "page"); XWikiDocument savedDoc = new XWikiDocument(docRef); savedDoc.setNew(false); savedDoc.setOriginalDocument(savedDoc.clone()); expect(mockStore.loadXWikiDoc(isA(XWikiDocument.class), same(getContext()))).andReturn( savedDoc).once(); replayDefault(); docCacheStore.initalize(); XWikiDocument inputParamDoc = new XWikiDocument(docRef); XWikiDocument existingDocument = docCacheStore.loadXWikiDoc(inputParamDoc, getContext()); assertTrue(existingDocument.isFromCache()); String key = docCacheStore.getKeyWithLang(existingDocument); assertNotNull("doc expected in cache", docCacheStore.getDocFromCache(key)); assertTrue("doc expected in exists cache", docCacheStore.exists(existingDocument, getContext())); docCacheStore.invalidateDocCache(key); assertNull("doc not in cache anymore", docCacheStore.getDocFromCache(key)); verifyDefault(); } @Test public void testLoadXWikiDoc() throws Exception { DocumentReference docRef = new DocumentReference("wiki", "space", "page"); XWikiDocument savedDoc = new XWikiDocument(docRef); savedDoc.setNew(false); savedDoc.setOriginalDocument(savedDoc.clone()); Capture<XWikiDocument> querySaveDocCapture = new Capture<>(); expect(mockStore.loadXWikiDoc(capture(querySaveDocCapture), same(getContext()))).andReturn( savedDoc).once(); replayDefault(); docCacheStore.initalize(); XWikiDocument inputParamDoc = new XWikiDocument(docRef); XWikiDocument existingDocument = docCacheStore.loadXWikiDoc(inputParamDoc, getContext()); XWikiDocument querySaveDoc = querySaveDocCapture.getValue(); assertNotSame(inputParamDoc, querySaveDoc); assertEquals(inputParamDoc.getDocumentReference(), querySaveDoc.getDocumentReference()); assertEquals(inputParamDoc.getLanguage(), querySaveDoc.getLanguage()); assertFalse(existingDocument.isNew()); assertTrue(existingDocument.isFromCache()); String key = docCacheStore.getKeyWithLang(existingDocument); assertNotNull("doc expected in cache", docCacheStore.getDocFromCache(key)); assertTrue(docCacheStore.exists(existingDocument, getContext())); assertSame(existingDocument, docCacheStore.loadXWikiDoc(inputParamDoc, getContext())); verifyDefault(); } @Test public void testLoadXWikiDoc_noOverwriteExistsCache() throws Exception { DocumentReference docRef = new DocumentReference("wiki", "space", "page"); XWikiDocument savedDoc = new XWikiDocument(docRef); savedDoc.setNew(false); savedDoc.setLanguage(""); savedDoc.setDefaultLanguage(""); savedDoc.setTranslation(0); savedDoc.setOriginalDocument(savedDoc.clone()); Capture<XWikiDocument> querySaveDocCapture = new Capture<>(); expect(mockStore.loadXWikiDoc(capture(querySaveDocCapture), same(getContext()))).andReturn( savedDoc).once(); Capture<XWikiDocument> queryNotExistDocCapture = new Capture<>(); XWikiDocument notExistsDoc = new XWikiDocument(docRef); notExistsDoc.setNew(true); notExistsDoc.setLanguage("de"); notExistsDoc.setDefaultLanguage(""); notExistsDoc.setTranslation(0); notExistsDoc.setOriginalDocument(savedDoc.clone()); expect(mockStore.loadXWikiDoc(capture(queryNotExistDocCapture), same(getContext()))).andReturn( notExistsDoc).once(); replayDefault(); docCacheStore.initalize(); XWikiDocument inputParamDoc = new XWikiDocument(docRef); inputParamDoc.setLanguage(""); XWikiDocument existingDocument = docCacheStore.loadXWikiDoc(inputParamDoc, getContext()); XWikiDocument querySaveDoc = querySaveDocCapture.getValue(); assertNotSame(inputParamDoc, querySaveDoc); assertEquals(inputParamDoc.getDocumentReference(), querySaveDoc.getDocumentReference()); assertEquals(inputParamDoc.getLanguage(), querySaveDoc.getLanguage()); assertFalse(existingDocument.isNew()); assertTrue(existingDocument.isFromCache()); String key = docCacheStore.getKeyWithLang(existingDocument); assertNotNull("doc expected in cache", docCacheStore.getDocFromCache(key)); assertTrue(docCacheStore.exists(existingDocument, getContext())); assertTrue("result must be in exists cache", docCacheStore.exists(inputParamDoc, getContext())); assertSame(existingDocument, docCacheStore.loadXWikiDoc(inputParamDoc, getContext())); // second loading with default language XWikiDocument inputParamDoc2 = new XWikiDocument(docRef); inputParamDoc2.setLanguage("de"); XWikiDocument notExistsDocument = docCacheStore.loadXWikiDoc(inputParamDoc2, getContext()); assertTrue("may not overwrite existing noTrans entry", docCacheStore.exists(existingDocument, getContext())); assertTrue(notExistsDocument.isNew()); assertFalse(notExistsDocument.isFromCache()); verifyDefault(); } @Test public void testDeleteXWikiDoc() throws Exception { DocumentReference docRef = new DocumentReference("wiki", "space", "page"); XWikiDocument savedDoc = new XWikiDocument(docRef); savedDoc.setNew(false); savedDoc.setOriginalDocument(savedDoc.clone()); Capture<XWikiDocument> querySavedDocCapture = new Capture<>(); expect(mockStore.loadXWikiDoc(capture(querySavedDocCapture), same(getContext()))).andReturn( savedDoc).once(); Capture<XWikiDocument> deletingDocCapture = new Capture<>(); mockStore.deleteXWikiDoc(capture(deletingDocCapture), same(getContext())); expectLastCall().once(); replayDefault(); docCacheStore.initalize(); XWikiDocument inputParamDoc = new XWikiDocument(docRef); XWikiDocument existingDocument = docCacheStore.loadXWikiDoc(inputParamDoc, getContext()); XWikiDocument querySavedDoc = querySavedDocCapture.getValue(); assertNotSame(inputParamDoc, querySavedDoc); assertEquals(inputParamDoc.getDocumentReference(), querySavedDoc.getDocumentReference()); assertEquals(inputParamDoc.getLanguage(), querySavedDoc.getLanguage()); // delete a document docCacheStore.deleteXWikiDoc(existingDocument, getContext()); XWikiDocument existingDocDeleted = deletingDocCapture.getValue(); assertSame(existingDocument, existingDocDeleted); String key = docCacheStore.getKeyWithLang(existingDocument); assertNull("on deleting doc must be removed from Cache", docCacheStore.getDocFromCache(key)); verifyDefault(); } @Test public void testExists_true() throws Exception { DocumentReference docRef = new DocumentReference("wiki", "space", "page"); Capture<XWikiDocument> querySaveDocCapture = new Capture<>(); boolean docExists = true; expect(mockStore.exists(capture(querySaveDocCapture), same(getContext()))).andReturn( docExists).once(); replayDefault(); docCacheStore.initalize(); XWikiDocument inputParamDoc = new XWikiDocument(docRef); boolean existsDoc = docCacheStore.exists(inputParamDoc, getContext()); assertEquals(docExists, existsDoc); XWikiDocument querySaveDoc = querySaveDocCapture.getValue(); assertSame(inputParamDoc, querySaveDoc); assertEquals(inputParamDoc.getDocumentReference(), querySaveDoc.getDocumentReference()); assertEquals(inputParamDoc.getLanguage(), querySaveDoc.getLanguage()); assertEquals("result must be in exists cache", docExists, docCacheStore.exists(inputParamDoc, getContext())); verifyDefault(); } @Test public void testExists_false() throws Exception { DocumentReference docRef = new DocumentReference("wiki", "space", "page"); Capture<XWikiDocument> querySaveDocCapture = new Capture<>(); boolean docExists = false; expect(mockStore.exists(capture(querySaveDocCapture), same(getContext()))).andReturn( docExists).once(); replayDefault(); docCacheStore.initalize(); XWikiDocument inputParamDoc = new XWikiDocument(docRef); boolean existsDoc = docCacheStore.exists(inputParamDoc, getContext()); assertEquals(docExists, existsDoc); XWikiDocument querySaveDoc = querySaveDocCapture.getValue(); assertSame(inputParamDoc, querySaveDoc); assertEquals(inputParamDoc.getDocumentReference(), querySaveDoc.getDocumentReference()); assertEquals(inputParamDoc.getLanguage(), querySaveDoc.getLanguage()); assertEquals("result must be in exists cache", docExists, docCacheStore.exists(inputParamDoc, getContext())); verifyDefault(); } }