/* * 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.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.InjectMocks; import org.mockito.Mock; import org.openlmis.core.domain.GeographicLevel; import org.openlmis.core.domain.GeographicZone; import org.openlmis.core.domain.Pagination; import org.openlmis.core.repository.GeographicZoneRepository; import org.openlmis.db.categories.UnitTests; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.modules.junit4.PowerMockRunnerDelegate; import java.util.List; import static java.util.Collections.EMPTY_LIST; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.*; import static org.openlmis.core.matchers.Matchers.dataExceptionMatcher; import static org.powermock.api.mockito.PowerMockito.whenNew; @RunWith(PowerMockRunner.class) @PowerMockRunnerDelegate(BlockJUnit4ClassRunner.class) @Category(UnitTests.class) @PrepareForTest(GeographicZoneService.class) public class GeographicZoneServiceTest { @Rule public ExpectedException expectedEx = ExpectedException.none(); @Mock GeographicZoneRepository repository; @InjectMocks GeographicZoneService service; public static final String ROOT_GEOGRAPHIC_ZONE_CODE = "Root"; public static final String ROOT_GEOGRAPHIC_ZONE_NAME = "Root"; private Integer pageSize = 11; @Test public void shouldSaveGeographicZone() throws Exception { GeographicLevel rootLevel = new GeographicLevel(1234L, ROOT_GEOGRAPHIC_ZONE_CODE, ROOT_GEOGRAPHIC_ZONE_NAME, 1); GeographicZone rootZone = new GeographicZone(1234L, "root zone", "root zone", rootLevel, null); GeographicLevel childLevel = new GeographicLevel(2345L, "child level", "child level", 2); GeographicZone childZone = new GeographicZone(null, "child zone", "child zone", childLevel, rootZone); when(repository.getGeographicLevelByCode(childZone.getLevel().getCode())).thenReturn(childLevel); when(repository.getByCode(childZone.getParent().getCode())).thenReturn(rootZone); service.save(childZone); verify(repository).getGeographicLevelByCode("child level"); verify(repository).getByCode("root zone"); assertThat(childZone.getLevel().getId(), is(2345L)); assertThat(childZone.getParent().getId(), is(1234L)); verify(repository).save(childZone); } @Test public void shouldThrowAnExceptionIfParentCodeIsInvalid() throws Exception { GeographicZone invalidZone = new GeographicZone(null, "invalid zone", "invalid zone", null, null); GeographicLevel childLevel = new GeographicLevel(2345L, "child level", "child level", 2); GeographicZone childZone = new GeographicZone(null, "child zone", "child zone", childLevel, invalidZone); when(repository.getGeographicLevelByCode(childZone.getLevel().getCode())).thenReturn(childLevel); when(repository.getByCode(childZone.getParent().getCode())).thenReturn(null); expectedEx.expect(dataExceptionMatcher("error.geo.zone.parent.invalid")); service.save(childZone); } @Test public void shouldThrowAnExceptionIfGeographicLevelCodeIsInvalid() throws Exception { GeographicLevel invalidLevel = new GeographicLevel(null, "invalid level", "invalid level", null); GeographicZone childZone = new GeographicZone(1235L, "child zone", "child zone", invalidLevel, null); when(repository.getByCode(childZone.getLevel().getCode())).thenReturn(null); expectedEx.expect(dataExceptionMatcher("error.geo.level.invalid")); service.save(childZone); } @Test public void shouldThrowAnExceptionIfGeographicZoneCodeIsMissing() throws Exception { GeographicZone geoZone = new GeographicZone(); expectedEx.expect(dataExceptionMatcher("error.mandatory.fields.missing")); service.save(geoZone); } @Test public void shouldThrowAnExceptionIfGeographicZoneNameIsMissing() throws Exception { GeographicZone geoZone = new GeographicZone(); geoZone.setCode("code"); expectedEx.expect(dataExceptionMatcher("error.mandatory.fields.missing")); service.save(geoZone); } @Test public void shouldThrowExceptionIfLevelIsNotRootAndStillParentIsNull() throws Exception { GeographicLevel level = new GeographicLevel(1L, "abc", "abc", 2); GeographicZone zone = new GeographicZone(1L, "xyz", "xyz", level, null); when(repository.getGeographicLevelByCode(zone.getLevel().getCode())).thenReturn(level); expectedEx.expect(dataExceptionMatcher("error.invalid.hierarchy")); service.save(zone); } @Test public void shouldUpdateZoneIfZonePreviouslyPresent() throws Exception { GeographicLevel rootLevel = new GeographicLevel(1234L, ROOT_GEOGRAPHIC_ZONE_CODE, ROOT_GEOGRAPHIC_ZONE_NAME, 1); GeographicZone rootZone = new GeographicZone(1234L, "root zone", "root zone", rootLevel, null); GeographicLevel childLevel = new GeographicLevel(2345L, "child level", "child level", 2); GeographicZone childZone = new GeographicZone(2345L, "child zone", "child zone", childLevel, rootZone); when(repository.getGeographicLevelByCode(childZone.getLevel().getCode())).thenReturn(childLevel); when(repository.getByCode(childZone.getParent().getCode())).thenReturn(rootZone); childZone.setName("new name"); service.save(childZone); verify(repository).save(childZone); assertThat(childZone.getLevel(), is(childLevel)); assertThat(childZone.getParent(), is(rootZone)); } @Test public void shouldGetGeoZoneById() throws Exception { GeographicZone expected = new GeographicZone(1L, "Root", "Root", null, null); when(repository.getById(1L)).thenReturn(expected); GeographicZone actual = service.getById(1L); assertThat(actual, is(expected)); verify(repository).getById(1L); } @Test public void shouldThrowExceptionIfParentSpecifiedForTopMostLevelGeographicZone() throws Exception { GeographicLevel level = new GeographicLevel(1L, "abc", "abc", 1); GeographicZone parent = new GeographicZone(1L, "xyz", "xyz", null, null); GeographicZone country = new GeographicZone(1L, "xyz", "xyz", level, parent); when(repository.getGeographicLevelByCode(country.getLevel().getCode())).thenReturn(level); when(repository.getByCode(country.getParent().getCode())).thenReturn(parent); expectedEx.expect(dataExceptionMatcher("error.invalid.hierarchy")); service.save(country); } @Test public void shouldThrowExceptionIfParentSetToItsSiblingInHierarchy() throws Exception { GeographicLevel level = new GeographicLevel(1L, "abc", "abc", 2); GeographicZone country1 = new GeographicZone(1L, "xyz", "xyz", level, null); GeographicZone country2 = new GeographicZone(1L, "xyz", "xyz", level, country1); when(repository.getGeographicLevelByCode(country2.getLevel().getCode())).thenReturn(level); when(repository.getByCode(country2.getParent().getCode())).thenReturn(country1); expectedEx.expect(dataExceptionMatcher("error.invalid.hierarchy")); service.save(country2); } @Test public void shouldThrowExceptionIfParentIsSetToALowerInHierarchyGeographicLevel() throws Exception { GeographicLevel higherLevel = new GeographicLevel(1L, "abc", "abc", 2); GeographicLevel lowerLevel = new GeographicLevel(1L, "abc", "abc", 3); GeographicZone country1 = new GeographicZone(1L, "xyz", "xyz", lowerLevel, null); GeographicZone country2 = new GeographicZone(1L, "xyz", "xyz", higherLevel, country1); when(repository.getGeographicLevelByCode(country2.getLevel().getCode())).thenReturn(higherLevel); when(repository.getByCode(country2.getParent().getCode())).thenReturn(country1); expectedEx.expect(dataExceptionMatcher("error.invalid.hierarchy")); service.save(country2); } @Test public void shouldSearchByParentNameIfSearchCriteriaIsParentName() throws Exception { service.setPageSize(String.valueOf(pageSize)); Pagination pagination = new Pagination(0, 0); whenNew(Pagination.class).withArguments(7, pageSize).thenReturn(pagination); service.searchBy("name", "parentName", 7); verify(repository).searchByParentName("name", pagination); } @Test public void shouldSearchByGeoZoneNameIfSearchCriteriaIsName() throws Exception { service.setPageSize(String.valueOf(pageSize)); Pagination pagination = new Pagination(0, 0); whenNew(Pagination.class).withArguments(7, pageSize).thenReturn(pagination); service.searchBy("name", "name", 7); verify(repository).searchByName("name", pagination); } @Test public void shouldReturnEmptyListIfSearchCriteriaIsInvalid() throws Exception { service.setPageSize(String.valueOf(pageSize)); Pagination pagination = new Pagination(0, 0); whenNew(Pagination.class).withArguments(7, pageSize).thenReturn(pagination); List<GeographicZone> geographicZones = service.searchBy("name", "invalidName", 7); assertThat(geographicZones, is(EMPTY_LIST)); verify(repository, never()).searchByName("name", pagination); verify(repository, never()).searchByParentName("name", pagination); } @Test public void shouldReturnTotalParentSearchResultCountIfSearchCriteriaIsParentName() throws Exception { service.getTotalSearchResultCount("name", "parentName"); verify(repository).getTotalParentSearchResultCount("name"); } @Test public void shouldReturnTotalGeoZoneNameSearchResultCountIfSearchCriteriaIsName() throws Exception { service.getTotalSearchResultCount("name", "name"); verify(repository).getTotalSearchResultCount("name"); } @Test public void shouldReturnTotalCountAsZeroIfSearchCriteriaIsInvalid() throws Exception { Integer count = service.getTotalSearchResultCount("name", "invalidName"); assertThat(count, is(0)); verify(repository, never()).getTotalSearchResultCount("name"); verify(repository, never()).getTotalParentSearchResultCount("name"); } }