/**
* 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.web.controller;
import org.joda.time.DateTime;
import org.jtalks.jcommune.model.entity.JCUser;
import org.jtalks.jcommune.model.entity.ObjectsFactory;
import org.jtalks.jcommune.service.UserService;
import org.jtalks.jcommune.service.exceptions.ImageProcessException;
import org.jtalks.jcommune.web.util.ImageControllerUtils;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.springframework.context.MessageSource;
import org.springframework.http.HttpHeaders;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.concurrent.TimeUnit;
import static org.jtalks.jcommune.web.controller.ImageUploadController.HTTP_HEADER_DATETIME_PATTERN;
import static org.jtalks.jcommune.web.controller.ImageUploadController.IF_MODIFIED_SINCE_HEADER;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;
import static org.mockito.MockitoAnnotations.initMocks;
import static org.testng.Assert.*;
/**
* @author Alexandre Teterin
* @author Anuar_Nurmakanov
*/
public class AvatarControllerTest {
private static final String USER_NAME = "username";
private static final String FIRST_NAME = "first name";
private static final String LAST_NAME = "last name";
private static final String EMAIL = "mail@mail.com";
private static final String PASSWORD = "password";
private static final String IMAGE_BYTE_ARRAY_IN_BASE_64_STRING = "it's dummy string";
//
@Mock
private UserService userService;
@Mock
private MessageSource messageSource;
@Mock
private ImageControllerUtils imageControllerUtils;
//
private AvatarController avatarController;
private byte[] validAvatar = new byte[]{-119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0,
0, 0, 4, 0, 0, 0, 4, 1, 0, 0, 0, 0, -127, -118, -93, -45, 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, 22, 73, 68, 65, 84, 120, -38, 98, -40, -49, -60, -64, -92,
-64, -60, 0, 0, 0, 0, -1, -1, 3, 0, 5, -71, 0, -26, -35, -7, 32, 96, 0, 0, 0, 0, 73, 69, 78, 68,
-82, 66, 96, -126
};
@BeforeMethod
public void setUp() throws Exception {
initMocks(this);
avatarController = new AvatarController(userService, imageControllerUtils, messageSource);
}
@Test
@SuppressWarnings("unchecked")
public void uploadAvatarForOperaAndIe_mustReturnPreviewInResponse() throws Exception {
MultipartFile file = new MockMultipartFile("qqfile", validAvatar);
avatarController.uploadAvatar(file);
verify(imageControllerUtils).prepareResponse(eq(file), any(HttpHeaders.class), any(HashMap.class));
}
@Test
@SuppressWarnings("unchecked")
public void uploadAvatarForChromeAndFf_mustReturnPreviewInResponse() throws ImageProcessException {
MockHttpServletResponse response = new MockHttpServletResponse();
avatarController.uploadAvatar(validAvatar, response);
verify(imageControllerUtils).prepareResponse(eq(validAvatar), eq(response), any(Map.class));
}
@Test
public void renderAvatarShouldReturnModifiedAvatarInResponse() throws Exception {
MockHttpServletResponse response = new MockHttpServletResponse();
JCUser user = getUser();
user.setAvatar(validAvatar);
user.setAvatarLastModificationTime(new DateTime(1000));
when(userService.get(anyLong())).thenReturn(user);
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader(IF_MODIFIED_SINCE_HEADER, new Date(0));
avatarController.renderAvatar(request, response, 0L);
assertEquals(response.getContentType(), "image/jpeg");
assertEquals(response.getContentLength(), validAvatar.length);
assertEquals(response.getContentAsByteArray(), validAvatar);
assertEquals(response.getHeader("Pragma"), "public");
List<String> cacheControlHeaders = response.getHeaders("Cache-Control");
assertTrue(cacheControlHeaders.contains("public"));
assertNotNull(response.getHeader("Last-Modified"));// depends on current timezone
}
@Test
public void renderAvatarShouldNotReturnNotModifiedAvatarInResponse() throws Exception {
JCUser user = getUser();
user.setAvatar(validAvatar);
user.setAvatarLastModificationTime(new DateTime(0));
when(userService.get(anyLong())).thenReturn(user);
MockHttpServletResponse response = new MockHttpServletResponse();
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader(IF_MODIFIED_SINCE_HEADER, new Date(1000));
avatarController.renderAvatar(request, response, 0L);
assertNotSame(response.getContentAsByteArray(), validAvatar);
assertEquals(response.getHeader("Pragma"), "public");
List<String> cacheControlHeaders = response.getHeaders("Cache-Control");
assertTrue(cacheControlHeaders.contains("public"));
assertNotNull(response.getHeader("Last-Modified"));// depends on current timezone
}
private JCUser getUser() {
JCUser newUser = new JCUser(USER_NAME, EMAIL, PASSWORD);
newUser.setFirstName(FIRST_NAME);
newUser.setLastName(LAST_NAME);
return newUser;
}
@SuppressWarnings("unchecked")
@Test
public void getDefaultAvatarShouldReturnDefaultAvatarInBase64String() throws Exception {
String expectedJSON = "{\"team\": \"larks\"}";
when(imageControllerUtils.getDefaultImage()).thenReturn(validAvatar);
when(imageControllerUtils.convertImageToIcoInString64(validAvatar)).thenReturn(IMAGE_BYTE_ARRAY_IN_BASE_64_STRING);
when(imageControllerUtils.getResponceJSONString(Matchers.anyMap())).thenReturn(expectedJSON);
String actualJSON = avatarController.getDefaultAvatar();
assertEquals(actualJSON, expectedJSON);
}
@Test
public void renderAvatar_mustReturnNotModifiedStatus_ifAvatarWasNeverModified() throws Exception {
JCUser user = ObjectsFactory.getRandomUser();
user.setAvatarLastModificationTime(null);
doReturn(user).when(userService).get(1L);
MockHttpServletResponse response = new MockHttpServletResponse();
avatarController.renderAvatar(new MockHttpServletRequest(), response, 1L);
assertEquals(response.getStatus(), HttpServletResponse.SC_NOT_MODIFIED);
}
@Test
public void renderAvatar_mustReturnNotModifiedStatus_ifAvatarWasNotChangedSinceLastTime() throws Exception {
JCUser user = ObjectsFactory.getRandomUser();
doReturn(user).when(userService).get(1L);
MockHttpServletResponse response = new MockHttpServletResponse();
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader(
IF_MODIFIED_SINCE_HEADER,
user.getAvatarLastModificationTime().toString(HTTP_HEADER_DATETIME_PATTERN, Locale.US));
avatarController.renderAvatar(request, response, 1L);
assertEquals(response.getStatus(), HttpServletResponse.SC_NOT_MODIFIED);
}
@Test
public void renderAvatar_mustReturnModifiedStatus_ifAvatarChangedSinceLastTime() throws Exception {
JCUser user = ObjectsFactory.getRandomUser();
doReturn(user).when(userService).get(1L);
MockHttpServletResponse response = new MockHttpServletResponse();
MockHttpServletRequest request = new MockHttpServletRequest();
String modifiedSinceIsBeforeAvatarModification = user.getAvatarLastModificationTime().minusSeconds(1)
.toString(HTTP_HEADER_DATETIME_PATTERN, Locale.US);
request.addHeader(IF_MODIFIED_SINCE_HEADER, modifiedSinceIsBeforeAvatarModification);
avatarController.renderAvatar(request, response, 1L);
assertEquals(response.getStatus(), HttpServletResponse.SC_OK);
}
@Test
public void renderAvatar_mustCacheFor30Days() throws Exception {
JCUser user = ObjectsFactory.getRandomUser();
doReturn(user).when(userService).get(1L);
MockHttpServletResponse response = new MockHttpServletResponse();
avatarController.renderAvatar(new MockHttpServletRequest(), response, 1L);
long actualMaxAge = Long.parseLong(response.getHeaders("Cache-Control").get(1).replace("max-age=", ""));
long actualCacheExpiration = Long.parseLong(response.getHeader("Expires"));
assertEquals(actualMaxAge, 30L * 24 * 60 * 60);
assertTrue(actualCacheExpiration - (System.currentTimeMillis() + TimeUnit.DAYS.toSeconds(30) * 1000) < 1000);
}
}