/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This 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 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software 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 this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package com.xpn.xwiki.web;

import java.io.File;
import java.io.IOException;

import junit.framework.Assert;

import org.jmock.Expectations;
import org.junit.Before;
import org.junit.Test;
import org.xwiki.container.ApplicationContext;
import org.xwiki.container.Container;
import org.xwiki.context.ExecutionContext;
import org.xwiki.context.ExecutionContextManager;

import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.test.AbstractBridgedComponentTestCase;

/**
 * Unit tests for {@link TempResourceAction}.
 * 
 * @version $Id$
 */
public class TempResourceActionTest extends AbstractBridgedComponentTestCase
{
    /**
     * The action being tested.
     */
    private TempResourceAction action;

    /**
     * The base directory.
     */
    private File base;

    /**
     * {@inheritDoc}
     * 
     * @see AbstractBridgedComponentTestCase#registerComponents()
     */
    @Override
    protected void registerComponents() throws Exception
    {
        super.registerComponents();

        final Container mockContainer = registerMockComponent(Container.class);
        final ApplicationContext mockAppContext = registerMockComponent(ApplicationContext.class);
        final ExecutionContextManager mockExecutionContextManager =
            registerMockComponent(ExecutionContextManager.class);

        getMockery().checking(new Expectations()
        {
            {
                allowing(mockExecutionContextManager).initialize(with(any(ExecutionContext.class)));
                ignoring(mockContainer).setApplicationContext(with(any(ApplicationContext.class)));
                allowing(mockContainer).getApplicationContext();
                will(returnValue(mockAppContext));
                allowing(mockAppContext).getTemporaryDirectory();
                will(returnValue(base));
            }
        });
    }

    /**
     * {@inheritDoc}
     * 
     * @see AbstractBridgedComponentTestCase#setUp()
     */
    @Override
    @Before
    public void setUp() throws Exception
    {
        base = new File(getClass().getResource("/").toURI());

        super.setUp();

        action = new TempResourceAction();
    }

    /**
     * Creates an empty file at the specified path.
     * 
     * @param path the file path
     * @throws IOException if creating the empty file fails
     */
    private void createEmptyFile(String path) throws IOException
    {
        File emptyFile = new File(base, path);
        emptyFile.getParentFile().mkdirs();
        emptyFile.createNewFile();
    }

    /**
     * {@link TempResourceAction#getTemporaryFile(String, XWikiContext)} should return {@code null} if the given URI
     * doesn't match the known pattern.
     */
    @Test
    public void testGetTemporaryFileForBadURI() throws Exception
    {
        createEmptyFile("temp/secret.txt");
        Assert.assertNull(action.getTemporaryFile("/xwiki/bin/temp/secret.txt", getContext()));
    }

    /**
     * {@link TempResourceAction#getTemporaryFile(String, XWikiContext)} should prevent access to files outside the
     * temporary directory by ignoring relative URIs (i.e. which use ".." to move to the parent folder).
     */
    @Test
    public void testGetTemporaryFileForRelativeURI() throws Exception
    {
        createEmptyFile("temp/secret.txt");
        Assert.assertNull(action.getTemporaryFile("/xwiki/bin/temp/../../module/secret.txt", getContext()));
    }

    /**
     * Tests {@link TempResourceAction#getTemporaryFile(String, XWikiContext)} when the file is missing.
     */
    @Test
    public void testGetTemporaryFileMissing() throws Exception
    {
        Assert.assertFalse(new File(base, "temp/module/xwiki/Space/Page/file.txt").exists());
        Assert.assertNull(action.getTemporaryFile("/xwiki/bin/temp/Space/Page/module/file.txt", getContext()));
    }

    /**
     * Tests {@link TempResourceAction#getTemporaryFile(String, XWikiContext)} when the file is present.
     */
    @Test
    public void testGetTemporaryFile() throws Exception
    {
        getContext().setDatabase("wiki");
        createEmptyFile("temp/module/wiki/Space/Page/file.txt");
        Assert.assertNotNull(action.getTemporaryFile("/xwiki/bin/temp/Space/Page/module/file.txt", getContext()));
    }

    /**
     * Tests {@link TempResourceAction#getTemporaryFile(String, XWikiContext)} when the URL is over encoded.
     */
    @Test
    public void testGetTemporaryFileForOverEncodedURL() throws Exception
    {
        createEmptyFile("temp/officeviewer/xwiki/Sp*ace/Pa-ge/presentation.odp/presentation-slide0.jpg");
        Assert.assertNotNull(action.getTemporaryFile(
            "/xwiki/bin/temp/Sp%2Aace/Pa%2Dge/officeviewer/presentation.odp/presentation-slide0.jpg", getContext()));
    }
}

@@ -1032,33 +1032,8 @@
 ns;%0A
-import org.junit.Before;%0A
 impo
@@ -1051,16 +1051,16 @@
 t.Test;%0A
+
 import o
@@ -1136,16 +1136,52 @@
 tainer;%0A
+import org.xwiki.context.Execution;%0A
 import o
@@ -1679,114 +1679,51 @@
     
-/**%0A     * %7B@inheritDoc%7D%0A     * %0A     * @see AbstractBridgedComponentTestCase#registerComponents()%0A     */
+private ExecutionContext executionContext;%0A
 %0A   
@@ -1829,24 +1829,89 @@
 ponents();%0A%0A
+        this.executionContext = new ExecutionContext();%0A        %0A
         fina
@@ -2211,17 +2211,105 @@
 class);%0A
+        final Execution mockExecution = registerMockComponent(Execution.class);%0A        
 %0A
-
         
@@ -2466,32 +2466,182 @@
 ntext.class)));%0A
+%0A                allowing(mockExecution).getContext(); will(returnValue(executionContext));%0A                allowing(mockExecution).removeContext();%0A%0A
                 
@@ -2720,24 +2720,25 @@
 t.class)));%0A
+%0A
             
@@ -2833,32 +2833,33 @@
 ckAppContext));%0A
+%0A
                 
@@ -2990,126 +2990,16 @@
     
-/**%0A     * %7B@inheritDoc%7D%0A     * %0A     * @see AbstractBridgedComponentTestCase#setUp()%0A     */%0A    @Override%0A    @Befor
+@Overrid
 e%0A  

Fix test