diff --git a/avni-server-api/src/main/java/org/avni/server/domain/UserSettings.java b/avni-server-api/src/main/java/org/avni/server/domain/UserSettings.java index 7d8090392..b67051214 100644 --- a/avni-server-api/src/main/java/org/avni/server/domain/UserSettings.java +++ b/avni-server-api/src/main/java/org/avni/server/domain/UserSettings.java @@ -1,6 +1,7 @@ package org.avni.server.domain; import org.avni.server.util.CollectionUtil; +import org.springframework.util.StringUtils; import java.util.Arrays; import java.util.List; @@ -12,16 +13,29 @@ public class UserSettings { public static final String LOCALE = "locale"; public static final String ENABLE_BENEFICIARY_MODE = "showBeneficiaryMode"; public static final String TRACK_LOCATION = "trackLocation"; - public static final List DATE_PICKER_MODE_OPTIONS = Arrays.asList("calendar", "spinner"); + public static final String DEFAULT_DATE_PICKER_MODE = "calendar"; + public static final String SPINNER_DATE_PICKER_MODE = "spinner"; + public static final List DATE_PICKER_MODE_OPTIONS = Arrays.asList(DEFAULT_DATE_PICKER_MODE, SPINNER_DATE_PICKER_MODE); public UserSettings(JsonObject jsonObject) { this.jsonObject = jsonObject; } public static String createDatePickerMode(String datePickerMode) { + if (StringUtils.isEmpty(datePickerMode)) { + return DEFAULT_DATE_PICKER_MODE; + } return CollectionUtil.findMatchingIgnoreCase(DATE_PICKER_MODE_OPTIONS, datePickerMode); } + public static Boolean createTrackLocation(Boolean trackLocation) { + return trackLocation != null && trackLocation; + } + + public static Boolean createEnableBeneficiaryMode(Boolean enableBeneficiaryMode) { + return enableBeneficiaryMode != null && enableBeneficiaryMode; + } + public String getIdPrefix() { return UserSettings.getIdPrefix(this.jsonObject); } diff --git a/avni-server-api/src/main/java/org/avni/server/importer/batch/csv/writer/UserAndCatchmentWriter.java b/avni-server-api/src/main/java/org/avni/server/importer/batch/csv/writer/UserAndCatchmentWriter.java index e8006d0c1..4ccc3843e 100644 --- a/avni-server-api/src/main/java/org/avni/server/importer/batch/csv/writer/UserAndCatchmentWriter.java +++ b/avni-server-api/src/main/java/org/avni/server/importer/batch/csv/writer/UserAndCatchmentWriter.java @@ -159,9 +159,9 @@ private void write(Row row) throws IDPException { user.setSettings(new JsonObject() .with(UserSettings.LOCALE, locale) - .with(UserSettings.TRACK_LOCATION, trackLocation) + .with(UserSettings.TRACK_LOCATION, UserSettings.createTrackLocation(trackLocation)) .withEmptyCheckAndTrim(UserSettings.DATE_PICKER_MODE, UserSettings.createDatePickerMode(datePickerMode)) - .with(UserSettings.ENABLE_BENEFICIARY_MODE, beneficiaryMode) + .with(UserSettings.ENABLE_BENEFICIARY_MODE, UserSettings.createEnableBeneficiaryMode(beneficiaryMode)) .withEmptyCheckAndTrim(UserSettings.ID_PREFIX, idPrefix)); user.setOrganisationId(organisation.getId()); diff --git a/avni-server-api/src/main/java/org/avni/server/service/AddressLevelCache.java b/avni-server-api/src/main/java/org/avni/server/service/AddressLevelCache.java index 88282fadf..c65401db2 100644 --- a/avni-server-api/src/main/java/org/avni/server/service/AddressLevelCache.java +++ b/avni-server-api/src/main/java/org/avni/server/service/AddressLevelCache.java @@ -36,7 +36,7 @@ public List getAddressLevelsForCatchment(Catchment c } } - @Cacheable(value = ADDRESSES_PER_CATCHMENT_AND_MATCHING_ADDR_LEVELS) + @Cacheable(cacheNames = ADDRESSES_PER_CATCHMENT_AND_MATCHING_ADDR_LEVELS, key="T(java.lang.String).valueOf(#catchment?.id + '_' + T(org.springframework.util.StringUtils).collectionToCommaDelimitedString(#matchingAddressLevelTypeIds)).intern()") @Transactional public List getAddressLevelsForCatchmentAndMatchingAddressLevelTypeIds(Catchment catchment, List matchingAddressLevelTypeIds) { try { diff --git a/avni-server-api/src/main/java/org/avni/server/service/AddressLevelService.java b/avni-server-api/src/main/java/org/avni/server/service/AddressLevelService.java index 3771d4f1f..07dd78438 100644 --- a/avni-server-api/src/main/java/org/avni/server/service/AddressLevelService.java +++ b/avni-server-api/src/main/java/org/avni/server/service/AddressLevelService.java @@ -53,6 +53,7 @@ private Stream filterByCatchmentAndSubjectType(Catch customRegistrationLocationSetting.get().getLocationTypeUUIDs()) .stream() .map(CHSBaseEntity::getId) + .sorted() .collect(Collectors.toList()); return addressLevelCache.getAddressLevelsForCatchmentAndMatchingAddressLevelTypeIds(catchment, matchingAddressLevelTypeIds).stream(); diff --git a/avni-server-api/src/test/java/org/avni/server/importer/batch/csv/writer/UserAndCatchmentWriterIntegrationTest.java b/avni-server-api/src/test/java/org/avni/server/importer/batch/csv/writer/UserAndCatchmentWriterIntegrationTest.java index 7f20a6f6f..54cc148e6 100644 --- a/avni-server-api/src/test/java/org/avni/server/importer/batch/csv/writer/UserAndCatchmentWriterIntegrationTest.java +++ b/avni-server-api/src/test/java/org/avni/server/importer/batch/csv/writer/UserAndCatchmentWriterIntegrationTest.java @@ -231,6 +231,7 @@ public void shouldCreateUpdate() throws IDPException { dataRow(" Bihar, District1, Block11", " Catchment 6", " username8@example", " User 8", " username8@example.com ", " 9455509147 ", "Answer 1"), catchmentCreated(false), userCreatedDetails(true)); + userCreatedDetails(user("username8@example"), datePickerMode("calendar"), language("en"), trackLocation(false), enableBeneficiaryMode(false), userGroup("Everyone")); // wrong - username, email, phone number, language, track location, date picker mode, enable beneficiary mode failure( diff --git a/avni-server-api/src/test/java/org/avni/server/service/AddressLevelCacheIntegrationTest.java b/avni-server-api/src/test/java/org/avni/server/service/AddressLevelCacheIntegrationTest.java index 85577aa38..3dc931c4f 100644 --- a/avni-server-api/src/test/java/org/avni/server/service/AddressLevelCacheIntegrationTest.java +++ b/avni-server-api/src/test/java/org/avni/server/service/AddressLevelCacheIntegrationTest.java @@ -24,6 +24,7 @@ import java.util.Objects; import static org.avni.server.service.AddressLevelCache.ADDRESSES_PER_CATCHMENT; +import static org.avni.server.service.AddressLevelCache.ADDRESSES_PER_CATCHMENT_AND_MATCHING_ADDR_LEVELS; import static org.mockito.Mockito.*; @Sql(value = {"/tear-down.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) @@ -68,6 +69,11 @@ public class AddressLevelCacheIntegrationTest extends AbstractControllerIntegrat private ReferenceQueue keysReferenceQueue; private ReferenceQueue valuesReferenceQueue; + List matchingAddressLevelTypeIds1= Arrays.asList(1l, 2l,3l); + List matchingAddressLevelTypeIds2Ordered= Arrays.asList(1l, 2l,3l); + List matchingAddressLevelTypeIds2UnOrdered= Arrays.asList(2l, 1l,3l); + List matchingAddressLevelTypeIds3= Arrays.asList(4l); + @Before public void setUpAddressLevelCache() { addressIdStartIdx = 1L; @@ -109,6 +115,10 @@ private Catchment initCatchmentAndMock(long catchment1Id, long startIndex, int n //stubbing when(mockLocationRepository.getCatchmentAddressesForCatchmentId(catchment.getId())).thenReturn(catchmentResponseList); + when(mockLocationRepository.getCatchmentAddressesForCatchmentIdAndLocationTypeId(catchment.getId(), matchingAddressLevelTypeIds1)).thenReturn(catchmentResponseList); + when(mockLocationRepository.getCatchmentAddressesForCatchmentIdAndLocationTypeId(catchment.getId(), matchingAddressLevelTypeIds2Ordered)).thenReturn(catchmentResponseList); + when(mockLocationRepository.getCatchmentAddressesForCatchmentIdAndLocationTypeId(catchment.getId(), matchingAddressLevelTypeIds2UnOrdered)).thenReturn(catchmentResponseList); + when(mockLocationRepository.getCatchmentAddressesForCatchmentIdAndLocationTypeId(catchment.getId(), matchingAddressLevelTypeIds3)).thenReturn(new ArrayList<>()); return catchment; } @@ -121,6 +131,41 @@ private ArrayList getCatchmentAddressProjectionArray return CatchmentAddressProjectionList; } + @Test + public void givenAddressLevelCacheIsConfigured_whenCallGetCatchmentAddressesForCatchmentIdAndLevelTypeList_thenDataShouldBeInAddressPerCatchmentAndMatchingAddressLevelCache() { + //Clear cache + Cache addrPerCatchmentCacheAndMatchingAddrLevels = cacheManager.getCache(ADDRESSES_PER_CATCHMENT_AND_MATCHING_ADDR_LEVELS); + addrPerCatchmentCacheAndMatchingAddrLevels.clear(); + + //Fetch and cache + List cachedCatchmentAddressesList = addressLevelCache.getAddressLevelsForCatchmentAndMatchingAddressLevelTypeIds(catchment1, matchingAddressLevelTypeIds1); + + //Validate cache content + Assert.notNull(cachedCatchmentAddressesList, "addrPerCatchmentCache should have had the data"); + Assert.isTrue(CATCHMENT_1_SIZE == cachedCatchmentAddressesList.size(), "addrPerCatchmentCache size should have been 2"); + + //Validate cache miss the first time + verify(mockLocationRepository).getCatchmentAddressesForCatchmentIdAndLocationTypeId(catchment1.getId(), matchingAddressLevelTypeIds1); + + //Invoke cache again for same catchment and level type ids + addressLevelCache.getAddressLevelsForCatchmentAndMatchingAddressLevelTypeIds(catchment1, matchingAddressLevelTypeIds2Ordered); + + //Validate cache hits + verifyNoMoreInteractions(mockLocationRepository); + + //Invoke cache again for same catchment and level type ids list + addressLevelCache.getAddressLevelsForCatchmentAndMatchingAddressLevelTypeIds(catchment1, matchingAddressLevelTypeIds2UnOrdered); + + //Validate cache miss this time due to change in order of level type ids list + verify(mockLocationRepository).getCatchmentAddressesForCatchmentIdAndLocationTypeId(catchment1.getId(), matchingAddressLevelTypeIds2UnOrdered); + + //Invoke cache again for same catchment and different level type ids list + addressLevelCache.getAddressLevelsForCatchmentAndMatchingAddressLevelTypeIds(catchment1, matchingAddressLevelTypeIds3); + + //Validate cache miss this time due to change in level type ids list + verify(mockLocationRepository).getCatchmentAddressesForCatchmentIdAndLocationTypeId(catchment1.getId(), matchingAddressLevelTypeIds3); + } + @Test public void givenAddressLevelCacheIsConfigured_whenCallGetCatchmentAddressesForCatchmentId_thenDataShouldBeInAddressPerCatchmentCache() { //Fetch and cache