/*
 * Copyright (c) 2008. All rights reserved.
 */
package ro.isdc.wro.model.resource.processor;

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.net.URL;

import junit.framework.Assert;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;

import ro.isdc.wro.config.Context;
import ro.isdc.wro.model.resource.Resource;
import ro.isdc.wro.model.resource.ResourceType;
import ro.isdc.wro.model.resource.processor.impl.css.CssUrlRewritingProcessor;
import ro.isdc.wro.util.WroTestUtils;


/**
 * Test for {@link CssUrlRewritingProcessor} class.
 *
 * @author Alex Objelean
 * @created Created on Nov 3, 2008
 */
public class TestCssUrlRewritingProcessor {
  private CssUrlRewritingProcessor processor;

  private static final String CSS_INPUT_NAME = "cssUrlRewriting.css";


  @Before
  public void setUp() {
    Context.set(Context.standaloneContext());
    processor = new CssUrlRewritingProcessor() {
      @Override
      protected String getUrlPrefix() {
        return "[WRO-PREFIX]?id=";
      }
    };
    WroTestUtils.createInjector().inject(processor);
  }

  @Test
  public void testFromFolder()
      throws Exception {
    final URL url = getClass().getResource("cssUrlRewriting");

    final File testFolder = new File(url.getFile(), "test");
    final File expectedFolder = new File(url.getFile(), "expected");
    WroTestUtils.compareFromDifferentFoldersByExtension(testFolder, expectedFolder, "css",
        (ResourcePreProcessor) processor);
  }

  /**
   * When background url contains a dataUri, the rewriting should have no effect.
   */
  @Test
  public void processResourceWithDataUriEncodedValue()
    throws IOException {
    final String resourceUri = "classpath:cssUrlRewriting-dataUri.css";
    WroTestUtils.compareProcessedResourceContents(resourceUri, resourceUri, new ResourcePostProcessor() {
      public void process(final Reader reader, final Writer writer)
        throws IOException {
        processor.process(createMockResource(resourceUri), reader, writer);
      }
    });
  }


  /**
   * Test a classpath css resource.
   */
  @Test
  public void processClasspathResourceType()
    throws IOException {
    final String resourceUri = "classpath:" + CSS_INPUT_NAME;
    WroTestUtils.compareProcessedResourceContents(resourceUri, "classpath:cssUrlRewriting-classpath-outcome.css",
      new ResourcePostProcessor() {
        public void process(final Reader reader, final Writer writer)
          throws IOException {
          processor.process(createMockResource(resourceUri), reader, writer);
        }
      });
  }


  /**
   * @param resourceUri the resource should return.
   * @return mocked {@link Resource} object.
   */
  private Resource createMockResource(final String resourceUri) {
    final Resource resource = Mockito.mock(Resource.class);
    Mockito.when(resource.getUri()).thenReturn(resourceUri);
    return resource;
  }


  /**
   * Test a servletContext css resource.
   */
  @Test
  public void processServletContextResourceType()
    throws IOException {
    WroTestUtils.compareProcessedResourceContents("classpath:" + CSS_INPUT_NAME,
      "classpath:cssUrlRewriting-servletContext-outcome.css", new ResourcePostProcessor() {
        public void process(final Reader reader, final Writer writer)
          throws IOException {
          processor.process(createMockResource("/static/img/" + CSS_INPUT_NAME), reader, writer);
        }
      });
  }

  /**
   * Test a servletContext css resource.
   */
  @Test
  public void processServletContextResourceTypeWithAggregatedFolderSet()
    throws IOException {
    Context.get().setAggregatedFolderPath("wro/css");
    WroTestUtils.compareProcessedResourceContents("classpath:" + CSS_INPUT_NAME,
      "classpath:cssUrlRewriting-servletContext-aggregatedFolderSet-outcome.css", new ResourcePostProcessor() {
        public void process(final Reader reader, final Writer writer)
          throws IOException {
          processor.process(createMockResource("/static/img/" + CSS_INPUT_NAME), reader, writer);
        }
      });
  }


  /**
   * Test a resource which is located inside WEB-INF protected folder.
   */
  @Test
  public void processWEBINFServletContextResourceType()
    throws IOException {
    WroTestUtils.compareProcessedResourceContents("classpath:" + CSS_INPUT_NAME,
      "classpath:cssUrlRewriting-WEBINFservletContext-outcome.css", new ResourcePostProcessor() {
        public void process(final Reader reader, final Writer writer)
          throws IOException {
          processor.process(createMockResource("/WEB-INF/" + CSS_INPUT_NAME), reader, writer);
        }
      });
  }

  /**
   * Test a url css resource.
   */
  @Test
  public void processUrlResourceType()
    throws IOException {
    WroTestUtils.compareProcessedResourceContents("classpath:" + CSS_INPUT_NAME,
      "classpath:cssUrlRewriting-url-outcome.css", new ResourcePostProcessor() {
        public void process(final Reader reader, final Writer writer)
          throws IOException {
          processor.process(createMockResource("http://www.site.com/static/css/" + CSS_INPUT_NAME), reader, writer);
        }
      });
  }

  @Test
  public void checkUrlIsAllowed() throws Exception {
    processClasspathResourceType();
    Assert.assertFalse(processor.isUriAllowed("/WEB-INF/web.xml"));
    Assert.assertTrue(processor.isUriAllowed("classpath:folder/img.gif"));
  }
  
  @Test
  public void shouldSupportOnlyCssResources() {
    WroTestUtils.assertProcessorSupportResourceTypes(processor, ResourceType.CSS);
  }
}

@@ -216,16 +216,81 @@
 et.URL;%0D
+%0Aimport java.util.Random;%0D%0Aimport java.util.concurrent.Callable;%0D
 %0A%0D%0Aimpor
@@ -5846,11 +5846,897 @@
 ;%0D%0A  %7D%0D%0A
+  %0D%0A  /**%0D%0A   * Tests that the Context injected into processor is thread safe and uses the values of set by the thread which runs%0D%0A   * the processor.%0D%0A   */%0D%0A  @Test%0D%0A  public void shouldUseCorrectAggregatedFolderSetEvenWhenContextIsChangedInAnotherThread()%0D%0A      throws Exception %7B%0D%0A    WroTestUtils.runConcurrently(new Callable%3CVoid%3E() %7B%0D%0A      public Void call()%0D%0A          throws Exception %7B%0D%0A        Context.set(Context.standaloneContext());%0D%0A        WroTestUtils.createInjector().inject(processor);%0D%0A        if (new Random().nextBoolean()) %7B%0D%0A          Thread.sleep(150);%0D%0A          processServletContextResourceTypeWithAggregatedFolderSet();%0D%0A        %7D else %7B%0D%0A          // ensure that a thread uses null aggregatedFolderPath which is injected into processor.%0D%0A          Context.get().setAggregatedFolderPath(null);%0D%0A        %7D%0D%0A        return null;%0D%0A      %7D%0D%0A    %7D, 20);%0D%0A  %7D%0D%0A
 %7D%0D%0A

create the unit test which reproduce the problem