/* * 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 org.xwiki.lesscss.internal.compiler; import javax.inject.Provider; import org.apache.commons.lang3.StringUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.xwiki.lesscss.compiler.LESSCompilerException; import org.xwiki.lesscss.internal.LESSContext; import org.xwiki.lesscss.internal.cache.LESSResourcesCache; import org.xwiki.lesscss.internal.colortheme.ColorThemeReference; import org.xwiki.lesscss.internal.colortheme.ColorThemeReferenceFactory; import org.xwiki.lesscss.internal.colortheme.CurrentColorThemeGetter; import org.xwiki.lesscss.internal.colortheme.NamedColorThemeReference; import org.xwiki.lesscss.internal.skin.FSSkinReference; import org.xwiki.lesscss.internal.skin.SkinReference; import org.xwiki.lesscss.internal.skin.SkinReferenceFactory; import org.xwiki.lesscss.resources.LESSResourceReference; import org.xwiki.test.mockito.MockitoComponentMockingRule; import com.xpn.xwiki.XWiki; import com.xpn.xwiki.XWikiContext; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; /** * @version $Id: 85e0bc65c14828f8cf890c84d0eaa881f006dd58 $ */ public class DefaultLESSCompilerTest { @Rule public MockitoComponentMockingRule<DefaultLESSCompiler> mocker = new MockitoComponentMockingRule<>(DefaultLESSCompiler.class); private LESSResourcesCache cache; private CachedLESSCompiler cachedLESSCompiler; private Provider<XWikiContext> xcontextProvider; private CurrentColorThemeGetter currentColorThemeGetter; private SkinReferenceFactory skinReferenceFactory; private ColorThemeReferenceFactory colorThemeReferenceFactory; private LESSContext lessContext; private XWikiContext xcontext; private XWiki xwiki; private LESSResourceReference lessResourceReference; private SkinReference skinReference = new FSSkinReference("skin"); private ColorThemeReference colorThemeReference = new NamedColorThemeReference("colorTheme"); @Before public void setUp() throws Exception { cache = mocker.getInstance(LESSResourcesCache.class); cachedLESSCompiler = mocker.getInstance(CachedLESSCompiler.class); currentColorThemeGetter = mocker.getInstance(CurrentColorThemeGetter.class); skinReferenceFactory = mocker.getInstance(SkinReferenceFactory.class); colorThemeReferenceFactory = mocker.getInstance(ColorThemeReferenceFactory.class); lessContext = mocker.getInstance(LESSContext.class); xcontextProvider = mocker.registerMockComponent(XWikiContext.TYPE_PROVIDER); xcontext = mock(XWikiContext.class); when(xcontextProvider.get()).thenReturn(xcontext); xwiki = mock(XWiki.class); when(xcontext.getWiki()).thenReturn(xwiki); when(xwiki.getSkin(xcontext)).thenReturn("skin"); when(currentColorThemeGetter.getCurrentColorTheme(true, "default")).thenReturn("colorTheme"); when(skinReferenceFactory.createReference("skin")).thenReturn(skinReference); when(colorThemeReferenceFactory.createReference("colorTheme")).thenReturn(colorThemeReference); lessResourceReference = mock(LESSResourceReference.class); when(cache.getMutex(eq(lessResourceReference), eq(new FSSkinReference("skin")), eq(new NamedColorThemeReference("colorTheme")))).thenReturn("mutex"); } @Test public void compileWhenInCache() throws Exception { // Mocks when(cache.get(eq(lessResourceReference), eq(new FSSkinReference("skin")), eq(new NamedColorThemeReference("colorTheme")))).thenReturn("cached output"); // Test assertEquals("cached output", mocker.getComponentUnderTest().compile(lessResourceReference, false, false, false)); // Verify verify(cache, never()).set(eq(lessResourceReference), eq(skinReference), eq(colorThemeReference), eq("cache output")); } @Test public void compileWhenNotInCache() throws Exception { // Mocks when(cachedLESSCompiler.compute(eq(lessResourceReference), eq(false), eq(false), eq(true), eq("skin"))). thenReturn("compiled output"); // Test assertEquals("compiled output", mocker.getComponentUnderTest().compile(lessResourceReference, false, false, false)); // Verify verify(cache).set(eq(lessResourceReference), eq(skinReference), eq(colorThemeReference), eq("compiled output")); } @Test public void compileWhenInCacheButForced() throws Exception { // Mocks when(cachedLESSCompiler.compute(eq(lessResourceReference), eq(false), eq(false), eq(true), eq("skin"))). thenReturn("compiled output"); // Test assertEquals("compiled output", mocker.getComponentUnderTest().compile( lessResourceReference, false, false, "skin", true)); // Verify verify(cache, times(1)).set(any(LESSResourceReference.class), any(SkinReference.class), any(ColorThemeReference.class), any()); verify(cache, never()).get(eq(lessResourceReference), eq(skinReference), eq(colorThemeReference)); } @Test public void compileSkinFileWhenInCacheButCacheDisabled() throws Exception { // Mock when(lessContext.isCacheDisabled()).thenReturn(true); when(cachedLESSCompiler.compute(eq(lessResourceReference), eq(false), eq(false),eq(true), eq("skin"))). thenReturn("compiled output"); // Test assertEquals("compiled output", mocker.getComponentUnderTest().compile(lessResourceReference, false, false, "skin", true)); // Verify that the cache is disabled verifyZeroInteractions(cache); } @Test public void compileWhenInCacheAndHTMLExport() throws Exception { // Mocks when(cache.get(eq(lessResourceReference), eq(skinReference), eq(colorThemeReference))).thenReturn("cached output"); when(lessContext.isHtmlExport()).thenReturn(true); // Test assertEquals("cached output", mocker.getComponentUnderTest().compile(lessResourceReference, false, true, false)); // Verify that the velocity is executed verify(cachedLESSCompiler).compute(eq(lessResourceReference), eq(false), eq(true), eq(false), eq("skin")); // Verify we don't put anything in the cache verify(cache, never()).set(any(LESSResourceReference.class), any(SkinReference.class), any(ColorThemeReference.class), any()); } @Test public void compileWhenError() throws Exception { // Mocks LESSCompilerException expectedException = new LESSCompilerException("an exception"); when(cachedLESSCompiler.compute(any(LESSResourceReference.class), anyBoolean(), anyBoolean(), anyBoolean(), any())).thenThrow(expectedException); // Test String result = mocker.getComponentUnderTest().compile(lessResourceReference, false, false, false); // Asserts assertTrue(StringUtils.startsWith(result, "/* org.xwiki.lesscss.compiler.LESSCompilerException: an exception")); assertTrue(StringUtils.endsWith(result, "*/")); verify(cache).set(eq(lessResourceReference), eq(skinReference), eq(colorThemeReference), eq(result)); verify(mocker.getMockedLogger()).error(eq("Error during the compilation of the resource [{}]."), eq(lessResourceReference), eq(expectedException)); } }