/* * 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.core.service; import org.hamcrest.Matcher; import org.ict4h.atomfeed.server.service.Event; import org.ict4h.atomfeed.server.service.EventService; import org.joda.time.DateTime; import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.BlockJUnit4ClassRunner; import org.mockito.ArgumentMatcher; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.openlmis.core.builder.FacilityBuilder; import org.openlmis.core.domain.*; import org.openlmis.core.dto.FacilityFeedDTO; import org.openlmis.core.exception.DataException; import org.openlmis.core.repository.FacilityRepository; import org.openlmis.core.repository.GeographicZoneRepository; import org.openlmis.core.repository.ProgramRepository; import org.openlmis.db.categories.UnitTests; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.modules.junit4.PowerMockRunnerDelegate; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.UUID; import static com.natpryce.makeiteasy.MakeItEasy.*; import static java.util.Arrays.asList; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.nullValue; import static org.junit.Assert.assertThat; import static org.junit.matchers.JUnitMatchers.hasItem; import static org.mockito.Matchers.any; import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.*; import static org.mockito.Mockito.spy; import static org.openlmis.core.builder.FacilityBuilder.*; import static org.openlmis.core.builder.ProgramSupportedBuilder.*; import static org.openlmis.core.domain.RightName.*; import static org.powermock.api.mockito.PowerMockito.doReturn; import static org.powermock.api.mockito.PowerMockito.*; import static org.powermock.api.mockito.PowerMockito.when; @RunWith(PowerMockRunner.class) @PowerMockRunnerDelegate(BlockJUnit4ClassRunner.class) @Category(UnitTests.class) @PrepareForTest({DateTime.class, FacilityService.class, FacilityServiceTest.class}) public class FacilityServiceTest { @Rule public ExpectedException expectedEx = ExpectedException.none(); @Mock private FacilityRepository facilityRepository; @Mock private ProgramRepository programRepository; @Mock private ProgramSupportedService programSupportedService; @Mock private SupervisoryNodeService supervisoryNodeService; @Mock private RequisitionGroupService requisitionGroupService; @Mock private GeographicZoneRepository geographicZoneRepository; @Mock private ELMISInterfaceService elmisInterfaceService; @Mock private EventService eventService; @Mock private FacilityProgramProductService facilityProgramProductService; @InjectMocks private FacilityService facilityService; private static Matcher<Event> eventMatcher(final UUID uuid, final String title, final DateTime timestamp, final String uri, final String content, final String category) { return new ArgumentMatcher<Event>() { @Override public boolean matches(Object argument) { Event event = (Event) argument; return event.getUuid().equals(uuid.toString()) && event.getTitle().equals(title) && event.getTimeStamp().equals(timestamp) && event.getUri().toString().equals(uri) && event.getContents().equals(content) && event.getCategory().equals(category); } }; } @Test public void shouldReturnNullIfUserIsNotAssignedAFacility() { when(facilityRepository.getHomeFacility(1L)).thenReturn(null); assertThat(facilityService.getHomeFacility(1L), is(nullValue())); } @Test public void shouldGetFacilityById() throws Exception { Long facilityId = 1L; List<ProgramSupported> supportedPrograms = asList(new ProgramSupported()); Facility facility = new Facility(); when(programSupportedService.getAllByFacilityId(facilityId)).thenReturn(supportedPrograms); when(facilityRepository.getById(facilityId)).thenReturn(facility); Facility returnedFacility = facilityService.getById(facilityId); assertThat(returnedFacility, is(facility)); assertThat(returnedFacility.getSupportedPrograms(), is(supportedPrograms)); } @Test public void shouldUpdateFacilityEnabledAndActiveForFacility() throws Exception { Facility facility = make(a(defaultFacility)); Facility parentFacility = new Facility(2l); parentFacility.setCode("PF"); facility.setParentFacilityId(parentFacility.getId()); FacilityFeedDTO facilityFeedDTO = new FacilityFeedDTO(facility, parentFacility); when(facilityRepository.updateEnabledAndActiveFor(facility)).thenReturn(facility); when(facilityRepository.getById(facility.getParentFacilityId())).thenReturn(parentFacility); DateTime dateTime = new DateTime(); mockStatic(DateTime.class); when(DateTime.now()).thenReturn(dateTime); UUID uuid = UUID.randomUUID(); mockStatic(UUID.class); Mockito.when(UUID.randomUUID()).thenReturn(uuid); facilityService.updateEnabledAndActiveFor(facility); verify(facilityRepository).updateEnabledAndActiveFor(facility); verify(facilityRepository).getById(facility.getParentFacilityId()); verify(eventService).notify(argThat(eventMatcher(uuid, "Facility", dateTime, "", facilityFeedDTO.getSerializedContents(), "facilities"))); } @Test public void shouldReturnUserSupervisedFacilitiesForAProgram() { Long userId = 1L; Long programId = 1L; List<Facility> facilities = new ArrayList<>(); List<SupervisoryNode> supervisoryNodes = new ArrayList<>(); List<RequisitionGroup> requisitionGroups = new ArrayList<>(); when(facilityRepository.getFacilitiesBy(programId, requisitionGroups)).thenReturn(facilities); when(supervisoryNodeService.getAllSupervisoryNodesInHierarchyBy(userId, programId, CREATE_REQUISITION)).thenReturn(supervisoryNodes); when(requisitionGroupService.getRequisitionGroupsBy(supervisoryNodes)).thenReturn(requisitionGroups); List<Facility> result = facilityService.getUserSupervisedFacilities(userId, programId, CREATE_REQUISITION); verify(facilityRepository).getFacilitiesBy(programId, requisitionGroups); verify(supervisoryNodeService).getAllSupervisoryNodesInHierarchyBy(userId, programId, CREATE_REQUISITION); verify(requisitionGroupService).getRequisitionGroupsBy(supervisoryNodes); assertThat(result, is(facilities)); } @Test public void shouldThrowExceptionIfProgramsSupportedInvalidWhileUpdating() throws Exception { Facility facility = new Facility(); final Date nullDate = null; List<ProgramSupported> programs = new ArrayList<ProgramSupported>() {{ add(make(a(defaultProgramSupported))); add(make(a(defaultProgramSupported, with(supportedProgram, new Program(1L)), with(isActive, true), with(startDate, nullDate)))); }}; facility.setSupportedPrograms(programs); expectedEx.expect(DataException.class); expectedEx.expectMessage("supported.programs.invalid"); facilityService.update(facility); } @Test public void shouldUpdateFacilityAndNotifyForFeedIfCoreAttributeChanges() throws Exception { Facility facility = make(a(FacilityBuilder.defaultFacility)); List<ProgramSupported> programsForFacility = new ArrayList<ProgramSupported>() {{ add(make(a(defaultProgramSupported))); add(make(a(defaultProgramSupported, with(supportedProgram, new Program(2L))))); }}; when(programSupportedService.getAllByFacilityId(facility.getId())).thenReturn(programsForFacility); facility.setSupportedPrograms(programsForFacility); Facility savedFacility = make(a(FacilityBuilder.defaultFacility)); savedFacility.setName("Updated Name"); when(facilityRepository.getById(facility.getId())).thenReturn(savedFacility); facilityService.update(facility); verify(facilityRepository).save(facility); verify(programSupportedService).updateSupportedPrograms(facility); verify(elmisInterfaceService).updateFacilityInterfaceMapping(facility); verify(eventService).notify(any(Event.class)); } @Test public void shouldUpdateFacilityAndNotNotifyForFeedIfNoCoreAttributeChanges() throws Exception { Facility facility = make(a(FacilityBuilder.defaultFacility)); List<ProgramSupported> programsForFacility = new ArrayList<ProgramSupported>() {{ add(make(a(defaultProgramSupported))); add(make(a(defaultProgramSupported, with(supportedProgram, new Program(2L))))); }}; facility.setSupportedPrograms(programsForFacility); Facility savedFacility = make(a(FacilityBuilder.defaultFacility)); when(facilityRepository.getById(facility.getId())).thenReturn(savedFacility); facilityService.update(facility); verify(facilityRepository).save(facility); verify(programSupportedService).updateSupportedPrograms(facility); verify(eventService, never()).notify(any(Event.class)); } @Test public void shouldUpdateFacilityAndNotifyChildFacilitiesIfFacilityTypeChange() throws Exception { Long parentId = 59L; Facility parentFacility = make(a(defaultFacility, with(facilityId, parentId), with(type, "NGO"))); Facility savedFacility = make(a(defaultFacility, with(facilityId, parentId), with(type, "GOVT"))); Facility childFacility = make(a(defaultFacility, with(parentFacilityId, parentId))); when(facilityRepository.getById(59L)).thenReturn(savedFacility); when(facilityRepository.getChildFacilities(parentFacility)).thenReturn(asList(childFacility)); facilityService.update(parentFacility); verify(facilityRepository).save(parentFacility); verify(programSupportedService).updateSupportedPrograms(parentFacility); verify(facilityRepository).getChildFacilities(parentFacility); verify(facilityRepository).updateVirtualFacilities(parentFacility); verify(eventService, times(2)).notify(any(Event.class)); } @Test public void shouldUpdateFacilityAndNotifyChildFacilitiesIfGeoZoneChange() throws Exception { Long parentId = 59L; Facility parentFacility = make(a(defaultFacility, with(facilityId, parentId), with(geographicZoneCode, "AAA"))); Facility savedFacility = make(a(defaultFacility, with(facilityId, parentId), with(geographicZoneCode, "BBB"))); Facility childFacility = make(a(defaultFacility, with(parentFacilityId, parentId))); when(facilityRepository.getById(59L)).thenReturn(savedFacility); when(facilityRepository.getChildFacilities(parentFacility)).thenReturn(asList(childFacility)); facilityService.update(parentFacility); verify(facilityRepository).save(parentFacility); verify(programSupportedService).updateSupportedPrograms(parentFacility); verify(facilityRepository).getChildFacilities(parentFacility); verify(facilityRepository).updateVirtualFacilities(parentFacility); verify(eventService, times(2)).notify(any(Event.class)); } @Test public void shouldGetAllFacilitiesForUserAndRights() throws Exception { //Arrange String[] rightNames = {VIEW_REQUISITION, APPROVE_REQUISITION}; Facility homeFacility = new Facility(); List<Facility> supervisedFacilities = new ArrayList<>(); supervisedFacilities.add(homeFacility); List<SupervisoryNode> supervisoryNodes = new ArrayList<>(); List<RequisitionGroup> requisitionGroups = new ArrayList<>(); when(facilityRepository.getHomeFacilityForRights(1L, rightNames)).thenReturn(homeFacility); when(supervisoryNodeService.getAllSupervisoryNodesInHierarchyBy(1L, rightNames)).thenReturn(supervisoryNodes); when(requisitionGroupService.getRequisitionGroupsBy(supervisoryNodes)).thenReturn(requisitionGroups); when(facilityRepository.getAllInRequisitionGroups(requisitionGroups)).thenReturn(supervisedFacilities); //Act List<Facility> actualFacilities = facilityService.getForUserAndRights(1L, rightNames); //Assert assertThat(actualFacilities, is(supervisedFacilities)); assertThat(actualFacilities.contains(homeFacility), is(true)); verify(facilityRepository).getHomeFacilityForRights(1L, rightNames); verify(supervisoryNodeService).getAllSupervisoryNodesInHierarchyBy(1L, rightNames); verify(requisitionGroupService).getRequisitionGroupsBy(supervisoryNodes); verify(facilityRepository).getAllInRequisitionGroups(requisitionGroups); } @Test public void shouldNotGetHomeFacilityWhenItIsNull() throws Exception { //Arrange String[] rightNames = {VIEW_REQUISITION, APPROVE_REQUISITION}; Facility supervisedFacility = new Facility(); List<Facility> supervisedFacilities = new ArrayList<>(); supervisedFacilities.add(supervisedFacility); List<SupervisoryNode> supervisoryNodes = new ArrayList<>(); List<RequisitionGroup> requisitionGroups = new ArrayList<>(); when(facilityRepository.getHomeFacilityForRights(1L, rightNames)).thenReturn(null); when(supervisoryNodeService.getAllSupervisoryNodesInHierarchyBy(1L, rightNames)).thenReturn(supervisoryNodes); when(requisitionGroupService.getRequisitionGroupsBy(supervisoryNodes)).thenReturn(requisitionGroups); when(facilityRepository.getAllInRequisitionGroups(requisitionGroups)).thenReturn(supervisedFacilities); //Act List<Facility> actualFacilities = facilityService.getForUserAndRights(1L, rightNames); //Assert assertThat(actualFacilities, is(supervisedFacilities)); assertThat(actualFacilities.size(), is(1)); verify(facilityRepository).getHomeFacilityForRights(1L, rightNames); verify(supervisoryNodeService).getAllSupervisoryNodesInHierarchyBy(1L, rightNames); verify(requisitionGroupService).getRequisitionGroupsBy(supervisoryNodes); verify(facilityRepository).getAllInRequisitionGroups(requisitionGroups); } @Test public void shouldGetAllFacilitiesInDeliveryZoneForSupportedProgram() throws Exception { List<Facility> memberFacilities = new ArrayList<>(); Facility facility = new Facility(1L); Facility facility2 = new Facility(2L); memberFacilities.add(facility); memberFacilities.add(facility2); Long deliveryZoneId = 1l; Long programId = 1l; when(facilityRepository.getAllInDeliveryZoneFor(deliveryZoneId, programId)).thenReturn(memberFacilities); ProgramSupported programSupported = new ProgramSupported(); when(programSupportedService.getFilledByFacilityIdAndProgramId(facility.getId(), programId)).thenReturn(programSupported); when(programSupportedService.getFilledByFacilityIdAndProgramId(facility2.getId(), programId)).thenReturn(programSupported); List<Facility> facilities = facilityService.getAllForDeliveryZoneAndProgram(deliveryZoneId, programId); assertThat(facilities, is(memberFacilities)); assertThat(facilities.get(0).getSupportedPrograms(), is(asList(programSupported))); assertThat(facilities.get(1).getSupportedPrograms(), is(asList(programSupported))); verify(facilityRepository).getAllInDeliveryZoneFor(deliveryZoneId, programId); } @Test public void shouldGetAllFacilitiesByModifiedDate() throws Exception { List<Facility> expectedFacilities = new ArrayList<>(); Date dateModified = new Date(); PowerMockito.when(facilityRepository.getAllByProgramSupportedModifiedDate(dateModified)).thenReturn(expectedFacilities); List<Facility> facilities = facilityService.getAllByProgramSupportedModifiedDate(dateModified); assertThat(facilities, is(expectedFacilities)); verify(facilityRepository).getAllByProgramSupportedModifiedDate(dateModified); } @Test public void shouldGetFacilityWithReferenceDataForCode() throws Exception { String facilityCode = "F10"; Long facilityId = 1l; Facility expectedFacility = new Facility(); when(facilityRepository.getIdForCode(facilityCode)).thenReturn(facilityId); when(facilityRepository.getById(facilityId)).thenReturn(expectedFacility); when(programSupportedService.getAllByFacilityId(facilityId)).thenReturn(asList(new ProgramSupported())); Facility facility = facilityService.getFacilityWithReferenceDataForCode(facilityCode); verify(facilityRepository).getIdForCode(facilityCode); verify(facilityRepository).getById(facilityId); verify(programSupportedService).getAllByFacilityId(facilityId); assertThat(facility, is(expectedFacility)); } @Test public void shouldGetWarehouses() throws Exception { List<Facility> expectedWarehouses = asList(new Facility()); when(facilityRepository.getEnabledWarehouses()).thenReturn(expectedWarehouses); List<Facility> warehouses = facilityService.getEnabledWarehouses(); verify(facilityRepository).getEnabledWarehouses(); assertThat(warehouses, is(expectedWarehouses)); } @Test public void shouldGetFacilityByCode() throws Exception { String facilityCode = "F11"; List<ProgramSupported> programSupported = asList(new ProgramSupported(2l, false, new Date()), new ProgramSupported(3l, true, new Date())); Facility expectedFacility = new Facility(); Long facilityId = 1L; expectedFacility.setId(facilityId); expectedFacility.setSupportedPrograms(programSupported); when(facilityRepository.getByCode(facilityCode)).thenReturn(expectedFacility); Facility facility = facilityService.getFacilityByCode(facilityCode); assertThat(facility, is(expectedFacility)); verify(facilityRepository).getByCode(facilityCode); assertThat(facility.getSupportedPrograms(), hasItem(programSupported.get(1))); } @Test public void shouldThrowErrorIfFacilityCodeInvalid() throws Exception { String invalidCode = "BlahBlahBlah"; when(facilityRepository.getIdForCode(invalidCode)).thenReturn(null); expectedEx.expect(DataException.class); expectedEx.expectMessage("error.facility.code.invalid"); facilityService.getFacilityByCode(invalidCode); } @Test public void shouldGetAllChildFacilitiesForFacility() throws Exception { Facility facility = new Facility(1L); List<Facility> expectedFacilities = asList(new Facility(5L)); when(facilityRepository.getChildFacilities(facility)).thenReturn(expectedFacilities); List<Facility> childFacilities = facilityService.getChildFacilities(facility); verify(facilityRepository).getChildFacilities(facility); assertThat(childFacilities, is(expectedFacilities)); } @Test public void shouldGetVirtualFacility() throws Exception { Facility expectedFacility = make(a(defaultFacility, with(parentFacilityId, 333L))); Facility parentFacility = make(a(defaultFacility, with(facilityId, 333L))); when(facilityRepository.getById(333L)).thenReturn(parentFacility); when(facilityRepository.getByCode("code")).thenReturn(expectedFacility); Facility actualFacility = facilityService.getOperativeFacilityByCode("code"); assertThat(actualFacility, is(expectedFacility)); } @Test public void shouldGetOperativeFacilityByCodeIfNotVirtual() throws Exception { Facility expectedFacility = make(a(defaultFacility)); when(facilityRepository.getByCode("code")).thenReturn(expectedFacility); Facility actualFacility = facilityService.getOperativeFacilityByCode("code"); assertThat(actualFacility, is(expectedFacility)); } @Test public void shouldThrowErrorIfCodeInvalid() throws Exception { when(facilityRepository.getByCode("code")).thenReturn(null); expectedEx.expect(DataException.class); expectedEx.expectMessage("error.facility.code.invalid"); facilityService.getOperativeFacilityByCode("code"); } @Test public void shouldThrowErrorIfFacilityInoperative() throws Exception { Facility facility = spy(new Facility()); facility.setVirtualFacility(true); Facility parent = new Facility(23L); facility.setParentFacilityId(23L); doReturn(false).when(facility).isValid(parent); when(facilityRepository.getById(23L)).thenReturn(parent); when(facilityRepository.getByCode("code")).thenReturn(facility); expectedEx.expect(DataException.class); expectedEx.expectMessage("error.facility.inoperative"); facilityService.getOperativeFacilityByCode("code"); } @Test public void shouldNotCheckForParentIfFacilityNotVirtual() throws Exception { Facility facility = spy(new Facility()); facility.setVirtualFacility(false); doReturn(true).when(facility).isValid(null); when(facilityRepository.getByCode("code")).thenReturn(facility); facilityService.getOperativeFacilityByCode("code"); verify(facilityRepository, never()).getById(anyLong()); } @Test public void shouldGetTotalSearchResultCountByFacility(){ String columnName = "facility"; String searchParam = "searchParam"; int count = 10; when(facilityRepository.getTotalSearchResultCount(searchParam)).thenReturn(count); assertThat(facilityService.getTotalSearchResultCountByColumnName(searchParam, columnName),is(count)); verify(facilityRepository).getTotalSearchResultCount(searchParam); } @Test public void shouldGetTotalSearchResultCountByGeographicZone(){ String columnName = "geographicZone"; String searchParam = "searchParam"; int count = 10; when(facilityRepository.getTotalSearchResultCountByGeographicZone(searchParam)).thenReturn(count); assertThat(facilityService.getTotalSearchResultCountByColumnName(searchParam, columnName), is(count)); verify(facilityRepository).getTotalSearchResultCountByGeographicZone(searchParam); } }