/** * Copyright (C) 2011 JTalks.org Team * This library 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 library 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package org.jtalks.jcommune.service.nontransactional; import org.apache.commons.io.IOUtils; import org.jtalks.common.model.entity.Property; import org.jtalks.jcommune.model.dao.PropertyDao; import org.jtalks.jcommune.model.entity.JCommuneProperty; import org.jtalks.jcommune.service.exceptions.ImageFormatException; import org.jtalks.jcommune.service.exceptions.ImageProcessException; import org.jtalks.jcommune.service.exceptions.ImageSizeException; import org.mockito.Mock; import org.springframework.mock.web.MockMultipartFile; import org.springframework.web.multipart.MultipartFile; import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; public class ImageServiceTest { private static final String PROPERTY_NAME = "property"; private static final int IMAGE_MAX_SIZE = 1000; private JCommuneProperty imageSizeProperty = JCommuneProperty.AVATAR_MAX_SIZE; @Mock private ImageConverter imageConverter; @Mock private Base64Wrapper base64Wrapper; @Mock private PropertyDao propertyDao; // private ImageService imageService; @BeforeMethod public void setUp() { initMocks(this); imageSizeProperty.setName(PROPERTY_NAME); imageSizeProperty.setPropertyDao(propertyDao); when(propertyDao.getByName(PROPERTY_NAME)) .thenReturn(new Property(PROPERTY_NAME, String.valueOf(IMAGE_MAX_SIZE))); imageService = new ImageService( imageConverter, base64Wrapper, "org/jtalks/jcommune/service/avatar.gif", imageSizeProperty); } @Test public void getDefaultImageShouldReturnNotEmptyImage() { byte[] avatar = imageService.getDefaultImage(); assertTrue(avatar.length > 0); } @Test(dataProvider = "validImageBytesValues") public void convertBytesToBase64StringShouldNormalConvertAvatar( byte[] originalImageBytes, BufferedImage inputImage, byte[] processedImageBytes, String expectedBase64String) throws ImageProcessException { when(imageConverter.convertByteArrayToImage(originalImageBytes)).thenReturn(inputImage); when(imageConverter.preprocessImage(inputImage)).thenReturn(processedImageBytes); when(base64Wrapper.encodeB64Bytes(processedImageBytes)).thenReturn(expectedBase64String); String resultBase64String = imageService.preProcessAndEncodeInString64(originalImageBytes); verify(imageConverter).convertByteArrayToImage(originalImageBytes); verify(imageConverter).preprocessImage(inputImage); verify(base64Wrapper).encodeB64Bytes(processedImageBytes); assertEquals(resultBase64String, expectedBase64String); } @DataProvider public Object[][] validImageBytesValues() throws IOException, ImageProcessException { byte[] originalImageBytes = new byte[]{-119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 5, 0, 0, 0, 5, 8, 2, 0, 0, 0, 2, 13, -79, -78, 0, 0, 0, 9, 112, 72, 89, 115, 0, 0, 1, -118, 0, 0, 1, -118, 1, 51, -105, 48, 88, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0, 122, 37, 0, 0, -128, -125, 0, 0, -7, -1, 0, 0, -128, -23, 0, 0, 117, 48, 0, 0, -22, 96, 0, 0, 58, -104, 0, 0, 23, 111, -110, 95, -59, 70, 0, 0, 0, 54, 73, 68, 65, 84, 120, -38, 76, -55, -79, 21, -128, 32, 0, -60, -48, 28, 14, 32, -52, -30, -2, -93, 121, -79, -112, -126, 116, -1, 37, 42, 71, 3, -72, -41, 4, -110, -88, -88, 42, 79, -37, 110, 3, 109, -81, 12, -33, -26, -1, 73, -88, 36, -33, 0, -62, -31, 36, 71, 49, 115, -89, 85, 0, 0, 0, 0, 73, 69, 78, 68, -82, 66, 96, -126 }; ImageConverter imageConverter = new ImageConverter("jpeg", BufferedImage.TYPE_INT_RGB, 100, 100); BufferedImage inputImage = imageConverter.convertByteArrayToImage(originalImageBytes); byte[] processedImageBytes = imageConverter.preprocessImage(inputImage); String expectedBase64String = new Base64Wrapper().encodeB64Bytes(processedImageBytes); return new Object[][]{ {originalImageBytes, inputImage, processedImageBytes, expectedBase64String} }; } @Test(expectedExceptions = ImageProcessException.class) public void convertBytesToBase64StringShouldNotContinueWhenPassedImageByteArrayIsIncorrect() throws ImageProcessException { byte[] imageBytes = {8, 2}; when(imageConverter.convertByteArrayToImage(imageBytes)).thenReturn(null); imageService.preProcessAndEncodeInString64(imageBytes); verify(imageConverter).convertByteArrayToImage(imageBytes); } @Test(expectedExceptions = {IllegalArgumentException.class}) public void convertBytesToBase64StringShouldNotWorkWithPassedNull() throws ImageProcessException { imageService.preProcessAndEncodeInString64(null); } @Test(expectedExceptions = ImageFormatException.class, dataProvider = "invalidFormatValues") public void validateImageFormatShouldNotConsiderIncorrectFormatsAsValid(MultipartFile file) throws ImageFormatException { imageService.validateImageFormat(file); } @DataProvider public Object[][] invalidFormatValues() { return new Object[][]{ {new MockMultipartFile("test_image", "test_image", "image/bmp", new byte[10])}, {new MockMultipartFile("test_image", "test_image", "image/tiff", new byte[10])}, {new MockMultipartFile("test_image", "test_image", "text/plain", new byte[10])}, {new MockMultipartFile("test_image", "test_image", "audio/mpeg", new byte[10])}, {new MockMultipartFile("test_image", "test_image", "audio/x-wav", new byte[10])}, {new MockMultipartFile("test_image", "test_image", "text/plain", new byte[10])}, {new MockMultipartFile("test_image", "test_image", "text/html", new byte[10])}, {new MockMultipartFile("test_image", "test_image", "video/mpeg", new byte[10])} }; } @Test(dataProvider = "validFormatValues") public void validateImageFormatShouldConsiderCorrectFormatsFromOperaAndIEAsValid(MultipartFile file) throws ImageFormatException { imageService.validateImageFormat(file); } @DataProvider public Object[][] validFormatValues() { Set<String> validFormats = new HashSet<String>(); validFormats.add("image/jpeg"); validFormats.add("image/png"); validFormats.add("image/gif"); List<MultipartFile> files = new ArrayList<MultipartFile>(validFormats.size()); for (String contentType : validFormats) { files.add(new MockMultipartFile("test_image", "test_image", contentType, new byte[10])); } Object[][] result = new Object[files.size()][]; for (int i = 0; i < result.length; i++) { result[i] = new Object[]{files.get(i)}; } return result; } @Test(expectedExceptions = {IllegalArgumentException.class}) public void validateImageFormatInFileShouldNotWorkWithPassedNull() throws ImageFormatException { MultipartFile nullMultipartFile = null; imageService.validateImageFormat(nullMultipartFile); } @Test(expectedExceptions = {IllegalArgumentException.class}) public void validateImageFormatInByteArrayShouldNotWorkWithPassedNull() throws ImageFormatException { byte[] nullByteArray = null; imageService.validateImageFormat(nullByteArray); } @Test(dataProvider = "validFormatValuesForChromeFF") public void validateImageFormatShouldProcessValidValuesForChromeFF(byte[] bytes) throws ImageFormatException { imageService.validateImageFormat(bytes); } @DataProvider public Object[][] validFormatValuesForChromeFF() throws IOException { String root = "/org/jtalks/jcommune/service/testdata/avatar/valid/format/"; Object[][] result = new Object[3][]; result[0] = new Object[]{IOUtils.toByteArray(this.getClass().getResourceAsStream(root + "avatar.gif"))}; result[1] = new Object[]{IOUtils.toByteArray(this.getClass().getResourceAsStream(root + "avatar.jpg"))}; result[2] = new Object[]{IOUtils.toByteArray(this.getClass().getResourceAsStream(root + "avatar.png"))}; return result; } @Test(dataProvider = "invalidFormatValuesForChromeFF", expectedExceptions = ImageFormatException.class) public void validateImageFormatShouldNotProcessInvalidValuesForChromeFF(byte[] bytes) throws ImageFormatException { imageService.validateImageFormat(bytes); } @DataProvider public Object[][] invalidFormatValuesForChromeFF() throws Exception { String root = "/org/jtalks/jcommune/service/testdata/avatar/invalid/format/"; Object[][] result = new Object[4][]; result[0] = new Object[]{IOUtils.toByteArray(this.getClass().getResourceAsStream(root + "avatar.bmp"))}; result[1] = new Object[]{IOUtils.toByteArray(this.getClass().getResourceAsStream(root + "avatar.pcx"))}; result[2] = new Object[]{IOUtils.toByteArray(this.getClass().getResourceAsStream(root + "avatar.pdf"))}; result[3] = new Object[]{IOUtils.toByteArray(this.getClass().getResourceAsStream(root + "avatar.tif"))}; return result; } @Test(expectedExceptions = IllegalArgumentException.class) public void validateImageSizeSholdNotContinueWithPassedNullValue() throws ImageSizeException { imageService.validateImageSize(null); } @Test(expectedExceptions = ImageSizeException.class) public void validateImageSizeShouldNotConsiderAvatarWithIncorrectSizeAsValid() throws Exception { byte[] bytes = new byte[IMAGE_MAX_SIZE * 2]; imageService.validateImageSize(bytes); } @Test public void validateImageSizeShouldConsiderAvatarWithCorrectSizeAsValid() throws ImageSizeException { byte[] bytes = new byte[IMAGE_MAX_SIZE]; imageService.validateImageSize(bytes); } @Test public void serviceShouldReturnPrefixOfImageConverter() { when(imageConverter.getHtmlSrcImagePrefix()).thenReturn("tiff"); String prefix = imageService.getHtmlSrcImagePrefix(); assertEquals(prefix, "tiff"); } }