diff --git a/source/java/org/alfresco/util/test/junitrules/TemporaryNodes.java b/source/java/org/alfresco/util/test/junitrules/TemporaryNodes.java index 685485e01a..c9ae5a681b 100644 --- a/source/java/org/alfresco/util/test/junitrules/TemporaryNodes.java +++ b/source/java/org/alfresco/util/test/junitrules/TemporaryNodes.java @@ -19,7 +19,9 @@ */ package org.alfresco.util.test.junitrules; +import java.io.File; import java.io.Serializable; +import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -27,6 +29,7 @@ import java.util.Map; import org.alfresco.model.ContentModel; import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.repo.content.transform.AbstractContentTransformerTest; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.site.SiteModel; @@ -49,7 +52,8 @@ import org.junit.rules.ExternalResource; import org.springframework.context.ApplicationContext; /** - * A JUnit rule designed to help with the automatic cleanup of temporary test nodes. + * A JUnit rule designed to help with the automatic cleanup of temporary test nodes and to ake it easier to + * create common test content with JUnit code. * * @author Neil Mc Erlean * @since 4.1 @@ -228,4 +232,119 @@ public class TemporaryNodes extends ExternalResource this.temporaryNodeRefs.add(newNodeRef); return newNodeRef; } + + /** + * This method creates a cm:folder NodeRef and adds it to the internal list of NodeRefs to be tidied up by the rule. + * This method will be run in its own transaction and will be run with the specified user as the fully authenticated user, + * thus ensuring the named user is the cm:creator of the new node. + * + * @param parentNode the parent node + * @param nodeCmName the cm:name of the new node + * @param nodeCreator the username of the person who will create the node + * @return the newly created NodeRef. + */ + public NodeRef createFolder(final NodeRef parentNode, final String nodeCmName, final String nodeCreator) + { + final RetryingTransactionHelper transactionHelper = (RetryingTransactionHelper) appContextRule.getApplicationContext().getBean("retryingTransactionHelper"); + + AuthenticationUtil.pushAuthentication(); + AuthenticationUtil.setFullyAuthenticatedUser(nodeCreator); + + NodeRef newNodeRef = transactionHelper.doInTransaction(new RetryingTransactionCallback() + { + public NodeRef execute() throws Throwable + { + final NodeRef result = createNode(nodeCmName, parentNode, ContentModel.TYPE_FOLDER); + + return result; + } + }); + + AuthenticationUtil.popAuthentication(); + + this.temporaryNodeRefs.add(newNodeRef); + return newNodeRef; + } + + /** + * This method creates a cm:content NodeRef whose content is taken from an Alfresco 'quick' file and adds it to the internal + * list of NodeRefs to be tidied up by the rule. + * This method will be run in its own transaction and will be run with the specified user as the fully authenticated user, + * thus ensuring the named user is the cm:creator of the new node. + * + * @param mimetype the MimeType of the content to put in the new node. + * @param parentNode the parent node + * @param nodeCmName the cm:name of the new node + * @param nodeCreator the username of the person who will create the node + * @return the newly created NodeRef. + */ + public NodeRef createQuickFile(final String mimetype, final NodeRef parentNode, final String nodeCmName, final String nodeCreator) + { + final RetryingTransactionHelper transactionHelper = (RetryingTransactionHelper) appContextRule.getApplicationContext().getBean("retryingTransactionHelper"); + + AuthenticationUtil.pushAuthentication(); + AuthenticationUtil.setFullyAuthenticatedUser(nodeCreator); + + NodeRef newNodeRef = transactionHelper.doInTransaction(new RetryingTransactionCallback() + { + public NodeRef execute() throws Throwable + { + final NodeRef result = createNode(nodeCmName, parentNode, ContentModel.TYPE_CONTENT); + + File quickFile = loadQuickFile(mimetype); + + ContentService contentService = appContextRule.getApplicationContext().getBean("contentService", ContentService.class); + ContentWriter writer = contentService.getWriter(result, ContentModel.PROP_CONTENT, true); + writer.setMimetype(mimetype); + writer.setEncoding("UTF-8"); + writer.putContent(quickFile); + + return result; + } + }); + + AuthenticationUtil.popAuthentication(); + + this.temporaryNodeRefs.add(newNodeRef); + return newNodeRef; + } + + private NodeRef createNode(String cmName, NodeRef parentNode, QName nodeType) + { + final NodeService nodeService = (NodeService) appContextRule.getApplicationContext().getBean("nodeService"); + + Map props = new HashMap(); + props.put(ContentModel.PROP_NAME, cmName); + ChildAssociationRef childAssoc = nodeService.createNode(parentNode, + ContentModel.ASSOC_CONTAINS, + ContentModel.ASSOC_CONTAINS, + nodeType, + props); + + return childAssoc.getChildRef(); + } + + private File loadQuickFile(String mimetype) + { + final MimetypeMap mimetypeService = (MimetypeMap) appContextRule.getApplicationContext().getBean("mimetypeService"); + final String extension = mimetypeService.getExtension(mimetype); + + if (extension == null) + { + throw new UnsupportedOperationException("No 'quick' file for unrecognised mimetype: " + mimetype); + } + + URL url = AbstractContentTransformerTest.class.getClassLoader().getResource("quick/quick." + extension); + + if (url == null) + { + throw new UnsupportedOperationException("No 'quick' file for extension: " + extension); + } + File file = new File(url.getFile()); + if (!file.exists()) + { + throw new UnsupportedOperationException("No 'quick' file for extension: " + extension); + } + return file; + } } diff --git a/source/java/org/alfresco/util/test/junitrules/TemporaryNodesTest.java b/source/java/org/alfresco/util/test/junitrules/TemporaryNodesTest.java index af5648c465..d73a22a7fe 100644 --- a/source/java/org/alfresco/util/test/junitrules/TemporaryNodesTest.java +++ b/source/java/org/alfresco/util/test/junitrules/TemporaryNodesTest.java @@ -20,6 +20,7 @@ package org.alfresco.util.test.junitrules; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -30,6 +31,7 @@ import java.util.List; import java.util.Map; import org.alfresco.model.ContentModel; +import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.model.Repository; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.transaction.RetryingTransactionHelper; @@ -237,4 +239,66 @@ public class TemporaryNodesTest } }); } + + @Test public void testCreateFolderAndQuickFile() throws Throwable + { + // Note that because we need to test that the Rule's 'after' behaviour has worked correctly, we cannot + // use the Rule that has been declared in the normal way - otherwise nothing would be cleaned up until + // after our test method. + // Therefore we have to manually poke the Rule to get it to cleanup during test execution. + // NOTE! This is *not* how a JUnit Rule would normally be used. + TemporaryNodes myTemporaryNodes = new TemporaryNodes(APP_CONTEXT_INIT); + + // Currently this is a no-op, but just in case that changes. + myTemporaryNodes.before(); + + + + // Create the temporary nodes relevant for this test. + // + // Create a target folder + final NodeRef folder = myTemporaryNodes.createFolder(COMPANY_HOME, "testFolder", AuthenticationUtil.getAdminUserName()); + + // create a 'quick' node under it. + final NodeRef quickTxt = myTemporaryNodes.createQuickFile(MimetypeMap.MIMETYPE_TEXT_PLAIN, folder, "quickFile", AuthenticationUtil.getAdminUserName()); + + TRANSACTION_HELPER.doInTransaction(new RetryingTransactionCallback() + { + public Void execute() throws Throwable + { + // Check the nodes were created ok + assertTrue(NODE_SERVICE.exists(folder)); + assertTrue(NODE_SERVICE.exists(quickTxt)); + + assertEquals(ContentModel.TYPE_FOLDER, NODE_SERVICE.getType(folder)); + assertEquals(ContentModel.TYPE_CONTENT, NODE_SERVICE.getType(quickTxt)); + + assertEquals(AuthenticationUtil.getAdminUserName(), NODE_SERVICE.getProperty(folder, ContentModel.PROP_CREATOR)); + assertEquals(AuthenticationUtil.getAdminUserName(), NODE_SERVICE.getProperty(quickTxt, ContentModel.PROP_CREATOR)); + + ContentReader reader = CONTENT_SERVICE.getReader(quickTxt, ContentModel.PROP_CONTENT); + assertEquals(MimetypeMap.MIMETYPE_TEXT_PLAIN, reader.getMimetype()); + + assertEquals(235, reader.getSize()); // 235 chars in the quick.txt file + final String content = reader.getContentString(); + assertTrue(content.contains("quick brown fox")); + + return null; + } + }); + + // Now trigger the Rule's cleanup behaviour. + myTemporaryNodes.after(); + + // and ensure that the temporary nodes are gone. + TRANSACTION_HELPER.doInTransaction(new RetryingTransactionCallback() + { + public Void execute() throws Throwable + { + assertFalse(NODE_SERVICE.exists(folder)); + assertFalse(NODE_SERVICE.exists(quickTxt)); + return null; + } + }); + } }