/*
 * #%L
 * Alfresco Repository
 * %%
 * Copyright (C) 2005 - 2016 Alfresco Software Limited
 * %%
 * This file is part of the Alfresco software. 
 * If the software was purchased under a paid Alfresco license, the terms of 
 * the paid license agreement will prevail.  Otherwise, the software is 
 * provided under the following open source license terms:
 * 
 * Alfresco is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Alfresco is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with Alfresco. If not, see .
 * #L%
 */
package org.alfresco.repo.audit;
import java.io.Serializable;
import java.net.URL;
import java.util.Date;
import java.util.Map;
import junit.framework.TestCase;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.audit.model.AuditModelRegistryImpl;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.repo.transaction.TransactionServiceImpl;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.audit.AuditQueryParameters;
import org.alfresco.service.cmr.audit.AuditService;
import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper;
import org.apache.commons.lang.mutable.MutableInt;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.util.ResourceUtils;
/**
 * Tests AuditMethodInterceptor
 * 
 * @see AuditMethodInterceptor
 * @author alex.mukha
 * @since 4.2.3
 */
public class AuditMethodInterceptorTest extends TestCase
{
    private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
    private AuditModelRegistryImpl auditModelRegistry;
    private TransactionServiceImpl transactionServiceImpl;
    private NodeService nodeService;
    private ServiceRegistry serviceRegistry;
    private AuditComponent auditComponent;
    private AuditService auditService;
    private TransactionService transactionService;
    private NodeRef nodeRef;
    private static String APPLICATION_NAME = "alfresco-mnt-11072";
    private static final Log logger = LogFactory.getLog(AuditMethodInterceptorTest.class);
    @Override
    public void setUp() throws Exception
    {
        auditModelRegistry = (AuditModelRegistryImpl) ctx.getBean("auditModel.modelRegistry");
        serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
        auditComponent = (AuditComponent) ctx.getBean("auditComponent");
        auditService = serviceRegistry.getAuditService();
        transactionService = serviceRegistry.getTransactionService();
        transactionServiceImpl = (TransactionServiceImpl) ctx.getBean("transactionService");
        nodeService = serviceRegistry.getNodeService();
        AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName());
        nodeRef = nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
        // Register the model
        URL modelUrl = ResourceUtils.getURL("classpath:alfresco/testaudit/alfresco-audit-test-mnt-11072.xml");
        auditModelRegistry.registerModel(modelUrl);
        auditModelRegistry.loadAuditModels();
    }
    @Override
    public void tearDown()
    {
        auditService.clearAudit(APPLICATION_NAME, null, null);
        auditModelRegistry.destroy();
        AuthenticationUtil.clearCurrentSecurityContext();
    }
    /**
     * Test for MNT-11072 
     * Use NodeService, as it is wrapped by the AuditMethodInterceptor, to get node props in read-only server mode.
     * 
     * @throws Exception
     */
    public void testAuditInReadOnly() throws Exception
    {
        // Run as admin
        AuthenticationUtil.setAdminUserAsFullyAuthenticatedUser();
        QName veto = QName.createQName(NamespaceService.APP_MODEL_1_0_URI, "TestVeto");
        transactionServiceImpl.setAllowWrite(false, veto);
        try
        {
            // Access the node in read-only transaction
            Map props = transactionService.getRetryingTransactionHelper()
                    .doInTransaction(new RetryingTransactionCallback