content: /**
   * Copyright@2011 wro4j
   */
  package ro.isdc.wro.manager.factory;
  
  import static org.junit.Assert.assertEquals;
  import static org.mockito.Mockito.verify;
  
  import java.util.concurrent.Callable;
  
  import javax.servlet.FilterConfig;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  
  import org.junit.After;
  import org.junit.AfterClass;
  import org.junit.Assert;
  import org.junit.Before;
  import org.junit.BeforeClass;
  import org.junit.Ignore;
  import org.junit.Test;
  import org.mockito.Mock;
  import org.mockito.Mockito;
  import org.mockito.MockitoAnnotations;
  
  import ro.isdc.wro.cache.CacheKey;
  import ro.isdc.wro.cache.CacheStrategy;
  import ro.isdc.wro.cache.CacheValue;
  import ro.isdc.wro.config.Context;
  import ro.isdc.wro.config.support.ContextPropagatingCallable;
  import ro.isdc.wro.manager.WroManager;
  import ro.isdc.wro.manager.callback.LifecycleCallback;
  import ro.isdc.wro.manager.callback.LifecycleCallbackSupport;
  import ro.isdc.wro.model.WroModel;
  import ro.isdc.wro.model.factory.WroModelFactory;
  import ro.isdc.wro.model.factory.XmlModelFactory;
  import ro.isdc.wro.model.group.processor.InjectorBuilder;
  import ro.isdc.wro.model.resource.support.naming.NoOpNamingStrategy;
  import ro.isdc.wro.util.ObjectFactory;
  import ro.isdc.wro.util.WroTestUtils;
  import ro.isdc.wro.util.WroUtil;
  
  
  /**
   * @author Alex Objelean
   */
  public class TestBaseWroManagerFactory {
    @Mock
    private HttpServletRequest mockRequest;
    @Mock
    private HttpServletResponse mockResponse;
    @Mock
    private FilterConfig mockFilterConfig;
    @Mock
    private WroModelFactory mockModelFactory;
    @Mock
    private CacheStrategy<CacheKey, CacheValue> mockCacheStrategy;
    private BaseWroManagerFactory victim;
    
    @BeforeClass
    public static void onBeforeClass() {
      assertEquals(0, Context.countActive());
    }
    
    @AfterClass
    public static void onAfterClass() {
      assertEquals(0, Context.countActive());
    }
    
    @Before
    public void setUp() {
      MockitoAnnotations.initMocks(this);
      Context.set(Context.webContext(mockRequest, mockResponse, mockFilterConfig));
      victim = new BaseWroManagerFactory();
    }
    
    @After
    public void tearDown() {
      Context.unset();
    }
    
    @Test
    public void defaultModelFactoryIsXml() {
      new BaseWroManagerFactory() {
        @Override
        protected WroModelFactory newModelFactory() {
          final WroModelFactory modelFactory = super.newModelFactory();
          Assert.assertEquals(XmlModelFactory.class, modelFactory.getClass());
          return modelFactory;
        }
      };
    }
    
    @Test
    public void shouldCreateManager()
        throws Exception {
      final WroManager manager = victim.create();
      Assert.assertNotNull(manager);
      Assert.assertEquals(NoOpNamingStrategy.class, manager.getNamingStrategy().getClass());
    }
    
    @Test
    public void shouldSetCallback()
        throws Exception {
      final LifecycleCallback callback = Mockito.spy(new LifecycleCallbackSupport());
      victim = new BaseWroManagerFactory().setModelFactory(WroUtil.factoryFor(new WroModel()));
      final WroManager manager = victim.create();
      InjectorBuilder.create(victim).build().inject(manager);
      
      manager.registerCallback(new ObjectFactory<LifecycleCallback>() {
        public LifecycleCallback create() {
          return callback;
        }
      });
      manager.getModelFactory().create();
      
      Mockito.verify(callback).onBeforeModelCreated();
      Mockito.verify(callback).onAfterModelCreated();
    }
    
    @Test
    public void shouldNotFailWhenReloadingModelOutsideOfContext()
        throws Exception {
      Context.unset();
      victim.onModelPeriodChanged(0);
    }
    
    @Test
    public void shouldNotFailWhenReloadingCacheOutsideOfContext()
        throws Exception {
      Context.unset();
      victim.onCachePeriodChanged(0);
    }
    
    @Test
    public void shouldReloadOnlyModelWhenClearModelIsInvoked()
        throws Exception {
      victim = new BaseWroManagerFactory().setModelFactory(mockModelFactory).setCacheStrategy(mockCacheStrategy);
      final WroManager manager = victim.create();
      
      manager.onModelPeriodChanged(0);
      
      Context.get().getConfig().reloadModel();
      verify(mockModelFactory, Mockito.times(1)).destroy();
      verify(mockCacheStrategy, Mockito.never()).clear();
    }
    
    @Test
    public void shouldReloadOnlyCacheWhenClearCacheIsInvoked()
        throws Exception {
      victim = new BaseWroManagerFactory().setModelFactory(mockModelFactory).setCacheStrategy(mockCacheStrategy);
      final WroManager manager = victim.create();
      
      manager.onCachePeriodChanged(0);
      
      Context.get().getConfig().reloadCache();
      verify(mockModelFactory, Mockito.never()).destroy();
      verify(mockCacheStrategy, Mockito.times(1)).clear();
    }
    
    /**
     * TODO find a way to test manager thread safety
     * 
     * @throws Exception
     */
    @Ignore
    @Test
    public void shouldBeThreadSafe()
        throws Exception {
      // Mockito.when(mockRequest.getRequestURI()).thenReturn("/a/resource.js");
      final WroManagerFactory managerFactory = new BaseWroManagerFactory();
      WroTestUtils.runConcurrently(new ContextPropagatingCallable<Void>(new Callable<Void>() {
        public Void call()
            throws Exception {
          // Context.set(Context.webContext(mockRequest, mockResponse, mockFilterConfig));
          managerFactory.create().process();
          // Context.unset();
          return null;
        }
      }));
    }
  }
  