/* * #%L * ACS AEM Commons Bundle * %% * Copyright (C) 2013 Adobe * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ package com.adobe.acs.commons.images.transformers.impl; import static org.junit.Assert.*; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import java.awt.Color; import java.awt.Paint; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; import org.apache.sling.api.resource.ValueMap; import org.apache.sling.api.wrappers.ValueMapDecorator; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import com.day.image.Layer; @RunWith(PowerMockRunner.class) @PrepareForTest(LetterPillarBoxImageTransformerImpl.class) public class LetterPillarBoxImageTransformerImplTest { LetterPillarBoxImageTransformerImpl transformer; @Mock Layer layer; Map<String, Object> map = null; private static final int START_WIDTH = 1600; private static final int START_HEIGHT = 900; @Before public void setUp() throws Exception { map = new HashMap<String, Object>(); transformer = new LetterPillarBoxImageTransformerImpl(); } @After public void tearDown() throws Exception { map = null; reset(layer); } @Test public void testTransform_withColor() throws Exception { final int width = 400; final int height = 225; final String color = "ABCDEF"; final float alpha = 0.5f; final int alphaint = Math.round(255 * alpha); Color expected = new Color(171, 205, 239, alphaint); map.put("width", width); map.put("height", height); map.put("color", color); map.put("alpha", alpha); ValueMap properties = new ValueMapDecorator(map); final Layer mockLayer = mock(Layer.class); final AtomicReference<Layer> resultLayer = new AtomicReference<Layer>(); PowerMockito.whenNew(Layer.class).withParameterTypes(int.class, int.class, Paint.class) .withArguments(anyInt(), anyInt(), Matchers.eq(expected)).thenAnswer(new Answer<Layer>() { @Override public Layer answer(InvocationOnMock invocation) throws Throwable { resultLayer.set(mockLayer); return mockLayer; } }); when(layer.getWidth()).thenReturn(START_WIDTH, START_WIDTH, width); when(layer.getHeight()).thenReturn(START_HEIGHT, START_HEIGHT, height); doNothing().when(mockLayer).blit(any(Layer.class), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); transformer.transform(layer, properties); assertNotNull("Layer constructor was not intercepted.", resultLayer.get()); verify(layer, times(3)).getWidth(); verify(layer, times(3)).getHeight(); verify(layer, times(1)).resize(width, height); verify(mockLayer, times(1)).blit(layer, 0, 0, width, height, 0, 0); verifyNoMoreInteractions(layer); verifyNoMoreInteractions(mockLayer); } @Test public void testTransform_withLetterBoxing() throws Exception { final int width = 600; final int height = 600; final int calcHeight = 338; final int startPos = (width - calcHeight) / 2; map.put("width", width); map.put("height", height); ValueMap properties = new ValueMapDecorator(map); final Layer mockLayer = mock(Layer.class); final AtomicReference<Layer> resultLayer = setupMockLayer(mockLayer); when(layer.getWidth()).thenReturn(START_WIDTH, START_WIDTH, width); when(layer.getHeight()).thenReturn(START_HEIGHT, START_HEIGHT, calcHeight); doNothing().when(mockLayer).blit(any(Layer.class), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); transformer.transform(layer, properties); assertNotNull("Layer constructor was not intercepted.", resultLayer.get()); verify(layer, times(3)).getWidth(); verify(layer, times(3)).getHeight(); verify(layer, times(1)).resize(width, calcHeight); verify(mockLayer, times(1)).blit(layer, 0, startPos, width, calcHeight, 0, 0); verifyNoMoreInteractions(layer); verifyNoMoreInteractions(mockLayer); } @Test public void testTransform_withPillarBoxing() throws Exception { final int width = 600; final int height = 600; final int calcWidth = 338; final int startPos = (width - calcWidth) / 2; map.put("width", width); map.put("height", height); ValueMap properties = new ValueMapDecorator(map); final Layer mockLayer = mock(Layer.class); final AtomicReference<Layer> resultLayer = setupMockLayer(mockLayer); // Don't get confused, switching the dimensions forces Pillar boxing. when(layer.getWidth()).thenReturn(START_HEIGHT, START_HEIGHT, calcWidth); when(layer.getHeight()).thenReturn(START_WIDTH, START_WIDTH, height); doNothing().when(mockLayer).blit(any(Layer.class), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); transformer.transform(layer, properties); assertNotNull("Layer constructor was not intercepted.", resultLayer.get()); verify(layer, times(3)).getWidth(); verify(layer, times(3)).getHeight(); verify(layer, times(1)).resize(calcWidth, height); verify(mockLayer, times(1)).blit(layer, startPos, 0, calcWidth, height, 0, 0); verifyNoMoreInteractions(layer); verifyNoMoreInteractions(mockLayer); } @Test public void testTransform() throws Exception { final int width = 400; final int height = 225; map.put("width", width); map.put("height", height); ValueMap properties = new ValueMapDecorator(map); final Layer mockLayer = mock(Layer.class); final AtomicReference<Layer> resultLayer = setupMockLayer(mockLayer); when(layer.getWidth()).thenReturn(START_WIDTH, START_WIDTH, width); when(layer.getHeight()).thenReturn(START_HEIGHT, START_HEIGHT, height); doNothing().when(mockLayer).blit(any(Layer.class), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); transformer.transform(layer, properties); assertNotNull("Layer constructor was not intercepted.", resultLayer.get()); verify(layer, times(3)).getWidth(); verify(layer, times(3)).getHeight(); verify(layer, times(1)).resize(width, height); verify(mockLayer, times(1)).blit(layer, 0, 0, width, height, 0, 0); verifyNoMoreInteractions(layer); verifyNoMoreInteractions(mockLayer); } @Test public void testTransform_onlyWidth() throws Exception { final int width = 400; final int height = 225; map.put("width", width); ValueMap properties = new ValueMapDecorator(map); final Layer mockLayer = mock(Layer.class); final AtomicReference<Layer> resultLayer = setupMockLayer(mockLayer); when(layer.getWidth()).thenReturn(START_WIDTH, START_WIDTH, width); when(layer.getHeight()).thenReturn(START_HEIGHT, START_HEIGHT, height); doNothing().when(mockLayer).blit(any(Layer.class), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); transformer.transform(layer, properties); assertNotNull("Layer constructor was not intercepted.", resultLayer.get()); verify(layer, times(3)).getWidth(); verify(layer, times(3)).getHeight(); verify(layer, times(1)).resize(width, height); verify(mockLayer, times(1)).blit(layer, 0, 0, width, height, 0, 0); verifyNoMoreInteractions(layer); verifyNoMoreInteractions(mockLayer); } @Test public void testTransform_onlyHeight() throws Exception { final int width = 400; final int height = 225; map.put("height", height); ValueMap properties = new ValueMapDecorator(map); final Layer mockLayer = mock(Layer.class); final AtomicReference<Layer> resultLayer = setupMockLayer(mockLayer); when(layer.getWidth()).thenReturn(START_WIDTH, START_WIDTH, width); when(layer.getHeight()).thenReturn(START_HEIGHT, START_HEIGHT, height); doNothing().when(mockLayer).blit(any(Layer.class), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); transformer.transform(layer, properties); assertNotNull("Layer constructor was not intercepted.", resultLayer.get()); verify(layer, times(3)).getWidth(); verify(layer, times(3)).getHeight(); verify(layer, times(1)).resize(width, height); verify(mockLayer, times(1)).blit(layer, 0, 0, width, height, 0, 0); verifyNoMoreInteractions(layer); verifyNoMoreInteractions(mockLayer); } @Test public void testTransform_invalidHeightAndWidth() throws Exception { final int width = -100; final int height = -200; map.put("width", width); map.put("height", height); ValueMap properties = new ValueMapDecorator(map); final Layer mockLayer = mock(Layer.class); final AtomicReference<Layer> resultLayer = setupMockLayer(mockLayer); when(layer.getWidth()).thenReturn(START_WIDTH); when(layer.getHeight()).thenReturn(START_HEIGHT); doNothing().when(mockLayer).blit(any(Layer.class), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); transformer.transform(layer, properties); assertNotNull("Layer constructor was not intercepted.", resultLayer.get()); verify(layer, times(3)).getWidth(); verify(layer, times(3)).getHeight(); verify(layer, times(1)).resize(START_WIDTH, START_HEIGHT); verify(mockLayer, times(1)).blit(layer, 0, 0, START_WIDTH, START_HEIGHT, 0, 0); verifyNoMoreInteractions(layer); verifyNoMoreInteractions(mockLayer); } @Test public void testTransform_invalidWifth() throws Exception { final int width = -100; final int height = 225; final int targetWidth = 400; map.put("width", width); map.put("height", height); ValueMap properties = new ValueMapDecorator(map); final Layer mockLayer = mock(Layer.class); final AtomicReference<Layer> resultLayer = setupMockLayer(mockLayer); when(layer.getWidth()).thenReturn(START_WIDTH, START_WIDTH, targetWidth); when(layer.getHeight()).thenReturn(START_HEIGHT, START_HEIGHT, height); doNothing().when(mockLayer).blit(any(Layer.class), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); transformer.transform(layer, properties); assertNotNull("Layer constructor was not intercepted.", resultLayer.get()); verify(layer, times(3)).getWidth(); verify(layer, times(3)).getHeight(); verify(layer, times(1)).resize(targetWidth, height); verify(mockLayer, times(1)).blit(layer, 0, 0, targetWidth, height, 0, 0); verifyNoMoreInteractions(layer); verifyNoMoreInteractions(mockLayer); } @Test public void testTransform_invalidHeight() throws Exception { final int width = 400; final int height = -100; final int targetheight = 225; map.put("width", width); map.put("height", height); ValueMap properties = new ValueMapDecorator(map); final Layer mockLayer = mock(Layer.class); final AtomicReference<Layer> resultLayer = setupMockLayer(mockLayer); when(layer.getWidth()).thenReturn(START_WIDTH, START_WIDTH, width); when(layer.getHeight()).thenReturn(START_HEIGHT, START_HEIGHT, targetheight); doNothing().when(mockLayer).blit(any(Layer.class), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); transformer.transform(layer, properties); assertNotNull("Layer constructor was not intercepted.", resultLayer.get()); verify(layer, times(3)).getWidth(); verify(layer, times(3)).getHeight(); verify(layer, times(1)).resize(width, targetheight); verify(mockLayer, times(1)).blit(layer, 0, 0, width, targetheight, 0, 0); verifyNoMoreInteractions(layer); verifyNoMoreInteractions(mockLayer); } @Test public void testTransform_emptyParams() throws Exception { ValueMap properties = new ValueMapDecorator(map); transformer.transform(layer, properties); verifyZeroInteractions(layer); } @Test public void testTransform_nullParams() throws Exception { transformer.transform(layer, null); verifyZeroInteractions(layer); } private AtomicReference<Layer> setupMockLayer(final Layer mockLayer) throws Exception { final AtomicReference<Layer> resultLayer = new AtomicReference<Layer>(); PowerMockito.whenNew(Layer.class).withParameterTypes(int.class, int.class, Paint.class) .withArguments(anyInt(), anyInt(), Matchers.isA(Paint.class)).thenAnswer(new Answer<Layer>() { @Override public Layer answer(InvocationOnMock invocation) throws Throwable { resultLayer.set(mockLayer); return mockLayer; } }); return resultLayer; } }