/* * 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.hamcrest.CoreMatchers; import org.hamcrest.Matcher; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.junit.runners.BlockJUnit4ClassRunner; import org.mockito.ArgumentMatcher; import org.mockito.InjectMocks; import org.mockito.Mock; import org.openlmis.authentication.web.UserAuthenticationSuccessHandler; import org.openlmis.core.domain.*; import org.openlmis.core.exception.DataException; import org.openlmis.core.message.OpenLmisMessage; import org.openlmis.core.service.MessageService; import org.openlmis.core.service.StaticReferenceDataService; import org.openlmis.db.categories.UnitTests; import org.openlmis.rnr.domain.*; import org.openlmis.rnr.dto.RnrDTO; import org.openlmis.rnr.search.criteria.RequisitionSearchCriteria; import org.openlmis.rnr.service.*; import org.openlmis.core.web.OpenLmisResponse; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.modules.junit4.PowerMockRunnerDelegate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpSession; import org.springframework.web.servlet.ModelAndView; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import static com.natpryce.makeiteasy.MakeItEasy.*; import static java.util.Arrays.asList; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.*; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; import static org.openlmis.core.domain.RightName.APPROVE_REQUISITION; import static org.openlmis.rnr.builder.RequisitionBuilder.defaultRequisition; import static org.openlmis.rnr.builder.RequisitionSearchCriteriaBuilder.*; import static org.openlmis.rnr.service.RequisitionService.RNR_SUBMITTED_SUCCESSFULLY; import static org.openlmis.web.controller.RequisitionController.*; import static org.powermock.api.mockito.PowerMockito.*; @Category(UnitTests.class) @RunWith(PowerMockRunner.class) @PowerMockRunnerDelegate(BlockJUnit4ClassRunner.class) @PrepareForTest({RnrDTO.class, RequisitionController.class}) public class RequisitionControllerTest { public static final String FACILITY_CODE = "F14"; public static final String FACILITY_NAME = "Facility"; public static final String PROGRAM_NAME = "HIV"; private static final String USER = "user"; private static final Long USER_ID = 1L; private Rnr rnr; private MockHttpServletRequest request; @Mock private RequisitionService requisitionService; @Mock private RnrTemplateService rnrTemplateService; @Mock private MessageService messageService; @Mock private RegimenColumnService regimenColumnService; @Mock private RequisitionStatusChangeService requisitionStatusChangeService; @Mock private StaticReferenceDataService staticReferenceDataService; @Mock private RequisitionPermissionService requisitionPermissionService; @InjectMocks private RequisitionController controller; public static Matcher<RequisitionSearchCriteria> criteriaMatcher(final Long facilityId, final Long programId, final Long periodId) { return new ArgumentMatcher<RequisitionSearchCriteria>() { @Override public boolean matches(Object argument) { RequisitionSearchCriteria searchCriteria = (RequisitionSearchCriteria) argument; return searchCriteria.getFacilityId().equals(facilityId) && searchCriteria.getProgramId().equals(programId) && searchCriteria.getPeriodId().equals( periodId); } }; } @Before public void setUp() throws Exception { initMocks(this); request = new MockHttpServletRequest(); MockHttpSession session = new MockHttpSession(); session.setAttribute(UserAuthenticationSuccessHandler.USER, USER); session.setAttribute(UserAuthenticationSuccessHandler.USER_ID, USER_ID); request.setSession(session); rnr = new Rnr(); } @Test public void shouldInitiateRnr() throws Exception { Facility facility = new Facility(1L); Program program = new Program(2L); ProcessingPeriod period = new ProcessingPeriod(); Rnr initiatedRnr = new Rnr(facility, program, period); when(requisitionService.initiate(facility, program, USER_ID, false, null,"WEB_UI")).thenReturn(initiatedRnr); when(requisitionService.findM(period)).thenReturn(5); ResponseEntity<OpenLmisResponse> response = controller.initiateRnr(1L, 2L, false, request); verify(requisitionService).initiate(facility, program, USER_ID, false, null,"WEB_UI"); verify(requisitionService).findM(period); assertThat((Rnr) response.getBody().getData().get(RNR), is(initiatedRnr)); assertThat((Integer) response.getBody().getData().get(NUMBER_OF_MONTHS), is(5)); assertThat(response.getStatusCode(), is(equalTo(HttpStatus.OK))); } @Test public void shouldGetRequisitionById() throws Exception { Rnr expectedRequisition = new Rnr(); ProcessingPeriod period = new ProcessingPeriod(); expectedRequisition.setPeriod(period); when(requisitionService.getFullRequisitionById(1L)).thenReturn(expectedRequisition); when(requisitionService.findM(period)).thenReturn(5); ResponseEntity<OpenLmisResponse> response = controller.getById(1L, request); assertThat((Rnr) response.getBody().getData().get(RequisitionController.RNR), is(expectedRequisition)); assertThat((Integer) response.getBody().getData().get(NUMBER_OF_MONTHS), is(5)); verify(requisitionService).getFullRequisitionById(1L); verify(requisitionService).findM(period); } @Test public void shouldSetCanApproveFlagTrueIfRequisitionInApprovableState() throws Exception { Rnr rnr = new Rnr(); rnr.setId(1000L); rnr.setStatus(RnrStatus.AUTHORIZED); when(requisitionService.getFullRequisitionById(1000L)).thenReturn(rnr); when(requisitionPermissionService.hasPermission(USER_ID, rnr, APPROVE_REQUISITION)).thenReturn(true); ResponseEntity<OpenLmisResponse> requisitionData = controller.getById(1000L, request); assertTrue((boolean) requisitionData.getBody().getData().get(CAN_APPROVE_RNR)); } @Test public void shouldSetCanApproveFlagFalseIfRequisitionIsNotInApprovableState() throws Exception { Rnr rnr = new Rnr(); rnr.setId(1000L); rnr.setStatus(RnrStatus.RELEASED); when(requisitionService.getFullRequisitionById(1000L)).thenReturn(rnr); when(requisitionPermissionService.hasPermission(1L, rnr, APPROVE_REQUISITION)).thenReturn(true); ResponseEntity<OpenLmisResponse> requisitionData = controller.getById(1000L, request); assertFalse((boolean) requisitionData.getBody().getData().get(CAN_APPROVE_RNR)); } @Test public void shouldSetCanApproveFlagFalseIfUserDoesNotHavePermission() throws Exception { Rnr rnr = new Rnr(); rnr.setId(1000L); rnr.setStatus(RnrStatus.AUTHORIZED); when(requisitionService.getFullRequisitionById(1000L)).thenReturn(rnr); when(requisitionPermissionService.hasPermission(1L, rnr, APPROVE_REQUISITION)).thenReturn(false); ResponseEntity<OpenLmisResponse> requisitionData = controller.getById(1000L, request); assertFalse((boolean) requisitionData.getBody().getData().get(CAN_APPROVE_RNR)); } @Test public void shouldSaveWIPRnr() throws Exception { when(messageService.message(RNR_SAVE_SUCCESS)).thenReturn("R&R submitted successfully!"); controller.saveRnr(rnr, rnr.getId(), request); verify(requisitionService).save(rnr); assertThat(rnr.getModifiedBy(), is(equalTo(USER_ID))); } @Test public void shouldGiveErrorIfInitiatingFails() throws Exception { String errorMessage = "error-message"; doThrow(new DataException(errorMessage)).when(requisitionService).initiate(new Facility(1L), new Program(2L), USER_ID, false, null,"WEB_UI"); ResponseEntity<OpenLmisResponse> response = controller.initiateRnr(1L, 2L, false, request); assertThat(response.getBody().getErrorMsg(), is(equalTo(errorMessage))); } @Test public void shouldAllowSubmittingOfRnrAndTagWithModifiedBy() throws Exception { Rnr rnr = new Rnr(1L); whenNew(Rnr.class).withArguments(1L).thenReturn(rnr); Rnr submittedRnr = make(a(defaultRequisition)); when(requisitionService.submit(rnr)).thenReturn(submittedRnr); OpenLmisMessage message = new OpenLmisMessage(RNR_SUBMITTED_SUCCESSFULLY); when(requisitionService.getSubmitMessageBasedOnSupervisoryNode(submittedRnr.getFacility(), submittedRnr.getProgram())).thenReturn(message); when(messageService.message(message)).thenReturn("R&R submitted successfully!"); ResponseEntity<OpenLmisResponse> response = controller.submit(rnr.getId(), request); assertThat(response.getBody().getSuccessMsg(), is("R&R submitted successfully!")); verify(requisitionService).submit(rnr); verify(requisitionService).getSubmitMessageBasedOnSupervisoryNode(submittedRnr.getFacility(), submittedRnr.getProgram()); assertThat(rnr.getModifiedBy(), is(USER_ID)); } @Test public void shouldReturnErrorMessageIfRnrNotValid() throws Exception { Rnr rnr = new Rnr(1L); whenNew(Rnr.class).withArguments(1L).thenReturn(rnr); OpenLmisMessage errorMessage = new OpenLmisMessage("some error"); when(messageService.message(errorMessage)).thenReturn("some error"); doThrow(new DataException(errorMessage)).when(requisitionService).submit(rnr); ResponseEntity<OpenLmisResponse> response = controller.submit(rnr.getId(), request); assertThat(response.getStatusCode(), is(HttpStatus.BAD_REQUEST)); assertThat(response.getBody().getErrorMsg(), is("some error")); } @Test public void shouldGiveMessageAndAuthorizeRnr() throws Exception { String code = RequisitionService.RNR_AUTHORIZED_SUCCESSFULLY; String message = "R&R authorized successfully!"; Rnr rnr = new Rnr(1L); whenNew(Rnr.class).withArguments(1L).thenReturn(rnr); Rnr authorizedRnr = make(a(defaultRequisition)); when(requisitionService.authorize(rnr)).thenReturn(authorizedRnr); OpenLmisMessage openLmisMessage = new OpenLmisMessage(code); when(requisitionService.getAuthorizeMessageBasedOnSupervisoryNode(authorizedRnr.getFacility(), authorizedRnr.getProgram())).thenReturn(openLmisMessage); when(messageService.message(openLmisMessage)).thenReturn(message); ResponseEntity<OpenLmisResponse> response = controller.authorize(rnr.getId(), request); verify(requisitionService).authorize(rnr); verify(requisitionService).getAuthorizeMessageBasedOnSupervisoryNode(authorizedRnr.getFacility(), authorizedRnr.getProgram()); assertThat(response.getBody().getSuccessMsg(), is(message)); assertThat(response.getStatusCode(), is(HttpStatus.OK)); } @Test public void shouldNotAuthorizeRnrAndGiveErrorMessage() throws Exception { String errorMessage = "some error"; Rnr rnr = new Rnr(1L); whenNew(Rnr.class).withArguments(1L).thenReturn(rnr); doThrow(new DataException(errorMessage)).when(requisitionService).authorize(rnr); ResponseEntity<OpenLmisResponse> response = controller.authorize(rnr.getId(), request); assertThat(response.getBody().getErrorMsg(), is("some error")); } @Test public void shouldGiveErrorResponseIfThereIsAnyExceptionWhileSavingRnr() throws Exception { String errorMessage = "some error"; doThrow(new DataException(new OpenLmisMessage(errorMessage))).when(requisitionService).save(rnr); ResponseEntity<OpenLmisResponse> response = controller.saveRnr(rnr, rnr.getId(), request); verify(requisitionService).save(rnr); assertThat(response.getBody().getErrorMsg(), is(errorMessage)); } @Test public void shouldGiveSuccessResponseIfRnrSavedSuccessfully() throws Exception { when(messageService.message(RNR_SAVE_SUCCESS)).thenReturn("R&R saved successfully!"); ResponseEntity<OpenLmisResponse> response = controller.saveRnr(rnr, rnr.getId(), request); verify(requisitionService).save(rnr); assertThat(response.getBody().getSuccessMsg(), is("R&R saved successfully!")); } @Test public void shouldReturnListOfUserSupervisedRnrForApproval() { final RnrDTO requisition = new RnrDTO(); final List<RnrDTO> requisitions = new ArrayList<RnrDTO>() {{ add(requisition); }}; when(requisitionService.listForApprovalDto(USER_ID)).thenReturn(requisitions); final ResponseEntity<OpenLmisResponse> response = controller.listForApproval(request); assertThat(response.getStatusCode(), is(HttpStatus.OK)); final List<RnrDTO> requisitionsList = (List<RnrDTO>) response.getBody().getData().get(RNR_LIST); verify(requisitionService).listForApprovalDto(USER_ID); } @Test public void shouldApproveRequisitionAndTagWithModifiedBy() throws Exception { Rnr approvedRnr = new Rnr(); when(requisitionService.approve(rnr, null)).thenReturn(approvedRnr); whenNew(Rnr.class).withArguments(rnr.getId()).thenReturn(rnr); OpenLmisMessage message = new OpenLmisMessage("message.key"); when(messageService.message(message)).thenReturn("R&R saved successfully!"); when(requisitionService.getApproveMessageBasedOnParentNode(approvedRnr)).thenReturn(message); final ResponseEntity<OpenLmisResponse> response = controller.approve(rnr.getId(), request); verify(requisitionService).approve(rnr, null); assertThat(rnr.getModifiedBy(), CoreMatchers.is(USER_ID)); assertThat(response.getStatusCode(), is(HttpStatus.OK)); assertThat(response.getBody().getSuccessMsg(), is("R&R saved successfully!")); } @Test public void shouldGiveErrorMessageWhenServiceThrowsSomeExceptionWhileApprovingAnRnr() throws Exception { doThrow(new DataException("some-error")).when(requisitionService).approve(rnr, null); ResponseEntity<OpenLmisResponse> response = controller.approve(rnr.getId(), request); verify(requisitionService).approve(rnr, null); assertThat(response.getStatusCode(), is(HttpStatus.BAD_REQUEST)); assertThat(response.getBody().getErrorMsg(), is("some-error")); } @Test public void shouldReturnAllPeriodsForInitiatingRequisition() throws Exception { ProcessingPeriod processingPeriod = new ProcessingPeriod(6L); List<ProcessingPeriod> periodList = asList(processingPeriod); Rnr rnr = new Rnr(); RequisitionSearchCriteria criteria = make(a(defaultSearchCriteria, with(facilityIdProperty, 1L), with(programIdProperty, 2L), with(periodIdProperty, 6L), with(withoutLineItemFlag, true))); when(requisitionService.getProcessingPeriods(criteria)).thenReturn(periodList); when(requisitionService.getRequisitionsFor(criteria, periodList)).thenReturn(asList(rnr)); ResponseEntity<OpenLmisResponse> response = controller.getAllPeriodsForInitiatingRequisitionWithRequisitionStatus(criteria, request); verify(requisitionService).getProcessingPeriods(criteria); assertThat((List<ProcessingPeriod>) response.getBody().getData().get(PERIODS), is(periodList)); assertThat((List<Rnr>) response.getBody().getData().get(RNR_LIST), is(asList(rnr))); } @Test public void shouldReturnErrorResponseIfNoPeriodsFoundForInitiatingRequisition() throws Exception { RequisitionSearchCriteria criteria = make(a(defaultSearchCriteria, with(facilityIdProperty, 1L), with(programIdProperty, 2L))); String errorMessage = "some error"; doThrow(new DataException(errorMessage)).when(requisitionService).getProcessingPeriods(criteria); ResponseEntity<OpenLmisResponse> response = controller.getAllPeriodsForInitiatingRequisitionWithRequisitionStatus(criteria, request); assertThat(response.getBody().getErrorMsg(), is(errorMessage)); } @Test public void shouldReturnListOfApprovedRequisitionsForConvertingToOrder() { ArrayList<Rnr> expectedRequisitions = new ArrayList<>(); mockStatic(RnrDTO.class); String searchType = "all"; String searchVal = "test"; String sortBy = "program"; String sortDirection = "asc"; Integer pageNumber = 1; when(requisitionService.getNumberOfPagesOfApprovedRequisitionsForCriteria(searchType, searchVal, USER_ID, RightName.CONVERT_TO_ORDER)).thenReturn(1); when(requisitionService.getApprovedRequisitionsForCriteriaAndPageNumber(searchType, searchVal, pageNumber, 1, USER_ID, RightName.CONVERT_TO_ORDER, sortBy, sortDirection)).thenReturn(expectedRequisitions); List<RnrDTO> expectedRnrList = new ArrayList<>(); when(RnrDTO.prepareForListApproval(expectedRequisitions)).thenReturn(expectedRnrList); ResponseEntity<OpenLmisResponse> responseEntity = controller.listForConvertToOrder(searchType, searchVal, pageNumber, sortBy, sortDirection, request); verify(requisitionService).getApprovedRequisitionsForCriteriaAndPageNumber(searchType, searchVal, pageNumber, 1, USER_ID, RightName.CONVERT_TO_ORDER, sortBy, sortDirection); assertThat((List<RnrDTO>) responseEntity.getBody().getData().get(RNR_LIST), is(expectedRnrList)); } @Test public void shouldGetRequisitionsForViewWithGivenFacilityIdProgramIdAndPeriodRangeAndSetUserIdInSearchCriteria() throws Exception { SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy"); String stringRangeStartDate = dateFormat.format(new Date()); String stringDateEndDate = dateFormat.format(new Date()); RequisitionSearchCriteria criteria = make(a(defaultSearchCriteria, with(facilityIdProperty, 1L), with(programIdProperty, 1L), with(startDate, stringRangeStartDate), with(endDate, stringDateEndDate))); List<Rnr> requisitionsReturnedByService = new ArrayList<>(); when(requisitionService.get(criteria)).thenReturn(requisitionsReturnedByService); mockStatic(RnrDTO.class); List<RnrDTO> expectedRnrList = new ArrayList<>(); when(RnrDTO.prepareForView(requisitionsReturnedByService)).thenReturn(expectedRnrList); ResponseEntity<OpenLmisResponse> response = controller.getRequisitionsForView(criteria, request); verify(requisitionService).get(criteria); assertThat(criteria.getUserId(), is(USER_ID)); List<RnrDTO> actual = (List<RnrDTO>) response.getBody().getData().get(RNR_LIST); assertThat(actual, is(expectedRnrList)); } @Test public void shouldReturnModelAndViewForPrintingRequisitionAsPdf() { Long rnrId = 1L; Long programId = 2L; Program program = new Program(); program.setId(programId); rnr.setProgram(program); ArrayList<RnrColumn> rnrTemplate = new ArrayList<>(); when(requisitionService.getFullRequisitionById(rnrId)).thenReturn(rnr); when(requisitionService.getCategoryCount(rnr, true)).thenReturn(10); when(requisitionService.getCategoryCount(rnr, false)).thenReturn(5); List<LossesAndAdjustmentsType> lossesAndAdjustmentTypes = new ArrayList<>(); when(requisitionService.getLossesAndAdjustmentsTypes()).thenReturn(lossesAndAdjustmentTypes); when(rnrTemplateService.fetchColumnsForRequisition(programId)).thenReturn(rnrTemplate); List<RegimenColumn> regimenTemplate = new ArrayList<>(); when(regimenColumnService.getRegimenColumnsByProgramId(programId)).thenReturn(regimenTemplate); ModelAndView modelAndView = controller.printRequisition(rnrId); assertThat((Rnr) modelAndView.getModel().get(RNR), is(rnr)); assertThat((ArrayList<LossesAndAdjustmentsType>) modelAndView.getModel().get(LOSSES_AND_ADJUSTMENT_TYPES), is(lossesAndAdjustmentTypes)); assertThat((ArrayList<RnrColumn>) modelAndView.getModel().get(RNR_TEMPLATE), is(rnrTemplate)); } @Test public void shouldInsertComment() throws Exception { Comment comment = new Comment(); List<Comment> comments = new ArrayList<>(); comments.add(comment); when(requisitionService.getCommentsByRnrId(rnr.getId())).thenReturn(comments); ResponseEntity<OpenLmisResponse> response = controller.insertComment(comment, rnr.getId(), request); verify(requisitionService).insertComment(comment); assertThat((List<Comment>) response.getBody().getData().get(COMMENTS), is(comments)); assertThat(comment.getRnrId(), is(rnr.getId())); assertThat(comment.getAuthor().getId(), is(USER_ID)); } @Test public void shouldGetCommentsForARnR() throws Exception { List<Comment> comments = new ArrayList<>(); when(requisitionService.getCommentsByRnrId(1L)).thenReturn(comments); ResponseEntity<OpenLmisResponse> response = controller.getCommentsForARnr(rnr.getId()); verify(requisitionService).getCommentsByRnrId(rnr.getId()); assertThat(comments, is(response.getBody().getData().get(COMMENTS))); } @Test public void shouldGetReferenceDataForRnr() throws Exception { List<LossesAndAdjustmentsType> lossesAndAdjustmentsTypes = new ArrayList<>(); when(requisitionService.getLossesAndAdjustmentsTypes()).thenReturn(lossesAndAdjustmentsTypes); ResponseEntity<OpenLmisResponse> responseEntity = controller.getReferenceData(); verify(requisitionService).getLossesAndAdjustmentsTypes(); assertThat((List<LossesAndAdjustmentsType>) responseEntity.getBody().getData().get(LOSS_ADJUSTMENT_TYPES), is(lossesAndAdjustmentsTypes)); } @Test public void shouldSetStatusChangesInModelForPrint() throws Exception { Integer numberOfMonths = 2; List<RequisitionStatusChange> statusChanges = new ArrayList<>(); when(requisitionStatusChangeService.getByRnrId(1L)).thenReturn(statusChanges); Rnr rnr = make(a(defaultRequisition)); when(requisitionService.getFullRequisitionById(1L)).thenReturn(rnr); when(requisitionService.findM(rnr.getPeriod())).thenReturn(numberOfMonths); ModelAndView printModel = controller.printRequisition(1L); assertThat((List<RequisitionStatusChange>) printModel.getModel().get(STATUS_CHANGES), is(statusChanges)); assertThat((Integer) printModel.getModel().get(NUMBER_OF_MONTHS), is(numberOfMonths)); } private Rnr createRequisition() { Rnr requisition = new Rnr(); final Facility facility = new Facility(); facility.setCode(FACILITY_CODE); facility.setName(FACILITY_NAME); facility.setFacilityType(new FacilityType()); facility.setGeographicZone(new GeographicZone()); facility.getFacilityType().setId(1L); facility.getGeographicZone().setId(1L); final Program program = new Program(); program.setName(PROGRAM_NAME); final ProcessingPeriod period = new ProcessingPeriod(); period.setStartDate(new Date()); period.setEndDate(new Date(1111232323L)); requisition.setFacility(facility); requisition.setProgram(program); requisition.setPeriod(period); return requisition; } }