/* * This program is part of the OpenLMIS logistics management information system platform software. * Copyright © 2013 VillageReach * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. *   * This program 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 Affero General Public License for more details. * You should have received a copy of the GNU Affero General Public License along with this program.  If not, see http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.  */ package org.openlmis.web.controller; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.mockito.ArgumentMatcher; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import org.mockito.runners.MockitoJUnitRunner; import org.openlmis.authentication.web.UserAuthenticationSuccessHandler; import org.openlmis.core.domain.Product; import org.openlmis.core.message.OpenLmisMessage; import org.openlmis.core.service.MessageService; import org.openlmis.core.upload.ProductPersistenceHandler; import org.openlmis.db.categories.UnitTests; import org.openlmis.db.service.DbService; import org.openlmis.upload.RecordHandler; import org.openlmis.upload.model.AuditFields; import org.openlmis.upload.model.ModelClass; import org.openlmis.upload.parser.CSVParser; import org.openlmis.web.model.UploadBean; import org.openlmis.core.web.OpenLmisResponse; import org.springframework.http.ResponseEntity; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpSession; import org.springframework.mock.web.MockMultipartFile; import org.springframework.web.multipart.MultipartFile; import java.io.InputStream; import java.util.Date; import java.util.HashMap; import java.util.Map; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.*; import static org.mockito.MockitoAnnotations.initMocks; import static org.openlmis.web.controller.UploadController.INCORRECT_FILE_FORMAT; import static org.openlmis.web.controller.UploadController.UPLOAD_FILE_SUCCESS; @Category(UnitTests.class) @RunWith(MockitoJUnitRunner.class) public class UploadControllerTest { public static final Long USER = 1L; @Mock CSVParser csvParser; @Mock DbService dbService; @Mock MessageService messageService; RecordHandler handler = new ProductPersistenceHandler(); private MockHttpServletRequest request; private UploadBean productUploadBean = new UploadBean("product", handler, Product.class); @Spy Map<String, UploadBean> uploadBeansMap = new HashMap<String, UploadBean>() {{ put("product", productUploadBean); }}; @InjectMocks UploadController controller; private Date currentTimestamp; AuditFields auditFields; @Before public void setUp() throws Exception { initMocks(this); request = new MockHttpServletRequest(); MockHttpSession session = new MockHttpSession(); session.setAttribute(UserAuthenticationSuccessHandler.USER_ID, USER); request.setSession(session); currentTimestamp = new Date(); when(dbService.getCurrentTimestamp()).thenReturn(currentTimestamp); auditFields = new AuditFields(USER, currentTimestamp); } @Test public void shouldThrowErrorIfUnsupportedModelIsSupplied() throws Exception { MultipartFile multipartFile = mock(MultipartFile.class); OpenLmisMessage message = new OpenLmisMessage(UploadController.INCORRECT_FILE); when(messageService.message(message)).thenReturn("Incorrect file"); ResponseEntity<OpenLmisResponse> uploadResponse = controller.upload(multipartFile, "Random", request); assertThat(uploadResponse.getBody().getErrorMsg(), is("Incorrect file")); } @Test public void shouldThrowErrorIfFileIsEmpty() throws Exception { byte[] content = new byte[0]; MockMultipartFile multiPartMock = new MockMultipartFile("csvFile", "mock.csv", null, content); OpenLmisMessage message = new OpenLmisMessage(UploadController.FILE_IS_EMPTY); when(messageService.message(message)).thenReturn("File is empty"); ResponseEntity<OpenLmisResponse> uploadResponse = controller.upload(multiPartMock, "product", request); assertThat(uploadResponse.getBody().getErrorMsg(), is("File is empty")); } @Test public void shouldParseIfFileIsCsv() throws Exception { byte[] content = new byte[1]; MockMultipartFile multiPartMock = new MockMultipartFile("csvFile", "mock.csv", null, content); String uploadSuccessMessage = "File uploaded successfully. " + "'Number of records processed: 0'"; when(messageService.message(UPLOAD_FILE_SUCCESS, 0)).thenReturn(uploadSuccessMessage); ResponseEntity<OpenLmisResponse> uploadResponse = controller.upload(multiPartMock, "product", request); assertThat(uploadResponse.getBody().getSuccessMsg(), is(uploadSuccessMessage)); } @Test public void shouldUseCsvParserService() throws Exception { byte[] content = new byte[1]; MultipartFile mockMultiPart = spy(new MockMultipartFile("csvFile", "mock.csv", null, content)); InputStream mockInputStream = mock(InputStream.class); when(mockMultiPart.getInputStream()).thenReturn(mockInputStream); String uploadSuccessMessage = "File uploaded successfully. " + "'Number of records processed: 0'"; when(messageService.message(UPLOAD_FILE_SUCCESS, 0)).thenReturn(uploadSuccessMessage); ResponseEntity<OpenLmisResponse> uploadResponse = controller.upload(mockMultiPart, "product", request); assertThat(uploadResponse.getBody().getSuccessMsg(), is(uploadSuccessMessage)); verify(csvParser).process(eq(mockMultiPart.getInputStream()), argThat(modelMatcher(Product.class)), eq(handler), eq(auditFields)); } private ArgumentMatcher<ModelClass> modelMatcher(final Class clazz) { return new ArgumentMatcher<ModelClass>() { @Override public boolean matches(Object item) { ModelClass modelClass = (ModelClass) item; return modelClass.getClazz().equals(clazz); } }; } @Test public void shouldGiveErrorIfFileNotOfTypeCsv() throws Exception { byte[] content = new byte[1]; MockMultipartFile multiPartMock = new MockMultipartFile("mock.doc", content); String errorMsg = "Incorrect file format. Please upload product data as a '.csv' file."; String uploadType = "product data"; when(messageService.message(productUploadBean.getDisplayName())).thenReturn(uploadType); when(messageService.message(INCORRECT_FILE_FORMAT, uploadType)).thenReturn(errorMsg); when(messageService.message(new OpenLmisMessage(errorMsg))).thenReturn(errorMsg); ResponseEntity<OpenLmisResponse> uploadResponse = controller.upload(multiPartMock, "product", request); assertThat(uploadResponse.getBody().getErrorMsg(), is(errorMsg)); } @Test public void shouldGetListOfUploadsSupported() throws Exception { ResponseEntity<OpenLmisResponse> responseEntity = controller.getSupportedUploads(); Map<String, UploadBean> result = (Map<String, UploadBean>) responseEntity.getBody().getData().get("supportedUploads"); assertThat(result.size(), is(uploadBeansMap.size())); } @Test public void shouldGetCountOfRecordsForRespectiveModelTable() throws Exception { byte[] content = new byte[1]; MultipartFile mockMultiPartFile = spy(new MockMultipartFile("csvFile", "mock.csv", null, content)); InputStream mockInputStream = mock(InputStream.class); when(mockMultiPartFile.getInputStream()).thenReturn(mockInputStream); when(csvParser.process(eq(mockMultiPartFile.getInputStream()), argThat(modelMatcher(Product.class)), eq(handler), eq(auditFields))).thenReturn(20); String uploadSuccessMessage = "File uploaded successfully. " + "'Number of records processed: 20'"; when(messageService.message(UPLOAD_FILE_SUCCESS, 20)).thenReturn(uploadSuccessMessage); ResponseEntity<OpenLmisResponse> uploadResponse = controller.upload(mockMultiPartFile, "product", request); assertThat(uploadResponse.getBody().getSuccessMsg(), is(uploadSuccessMessage)); } @Test public void shouldGetCurrentDbTimestampAndProcessCSVFileWithIt() throws Exception { byte[] content = new byte[1]; MultipartFile mockMultiPartFile = spy(new MockMultipartFile("csvFile", "mock.csv", null, content)); InputStream mockInputStream = mock(InputStream.class); when(mockMultiPartFile.getInputStream()).thenReturn(mockInputStream); when(csvParser.process(eq(mockMultiPartFile.getInputStream()), argThat(modelMatcher(Product.class)), eq(handler), eq(auditFields))).thenReturn(20); controller.upload(mockMultiPartFile, "product", request); verify(csvParser).process(eq(mockInputStream), argThat(modelMatcher(Product.class)), eq(handler), eq(auditFields)); verify(dbService).getCurrentTimestamp(); } }