Java tutorial
/******************************************************************************* * Copyright (c) 2018 Stichting Yona Foundation This Source Code Form is subject to the terms of the Mozilla Public License, v. * 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. *******************************************************************************/ package nu.yona.server.analysis.service; import static org.hamcrest.collection.IsEmptyCollection.empty; import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; import static org.junit.Assert.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.time.Duration; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import org.mockito.Mock; import org.springframework.data.repository.Repository; import nu.yona.server.Translator; import nu.yona.server.crypto.pubkey.PublicKeyUtil; import nu.yona.server.device.entities.DeviceAnonymized; import nu.yona.server.device.entities.DeviceAnonymized.OperatingSystem; import nu.yona.server.device.service.DeviceAnonymizedDto; import nu.yona.server.goals.entities.ActivityCategory; import nu.yona.server.goals.entities.BudgetGoal; import nu.yona.server.goals.entities.Goal; import nu.yona.server.goals.entities.GoalRepository; import nu.yona.server.goals.entities.TimeZoneGoal; import nu.yona.server.goals.service.ActivityCategoryDto; import nu.yona.server.goals.service.GoalDto; import nu.yona.server.messaging.entities.MessageDestination; import nu.yona.server.subscriptions.entities.UserAnonymized; import nu.yona.server.subscriptions.service.UserAnonymizedDto; import nu.yona.server.test.util.JUnitUtil; import nu.yona.server.util.TimeUtil; @RunWith(Parameterized.class) public class AnalysisEngineService_determineRelevantGoalsTest { @Mock private GoalRepository mockGoalRepository; private OperatingSystem operatingSystem; private boolean isIOs; private Goal gamblingGoal; private Goal newsGoal; private Goal gamingGoal; private Goal socialGoal; private Goal shoppingGoal; private Goal shoppingGoalHistoryItem; private DeviceAnonymized deviceAnonEntity; private UserAnonymized userAnonEntity; private UserAnonymizedDto userAnonDto; private ZoneId userAnonZoneId; private DeviceAnonymizedDto deviceAnonDto; public AnalysisEngineService_determineRelevantGoalsTest(String operatingSystem, boolean isIOs) { this.operatingSystem = OperatingSystem.valueOf(operatingSystem); this.isIOs = isIOs; } @Parameters public static Collection<Object[]> data() { return Arrays.asList(new Object[][] { { "IOS", true }, { "ANDROID", false } }); } @Before public void setUp() { initMocks(this); setUpRepositoryMocks(); LocalDateTime yesterday = TimeUtil.utcNow().minusDays(1); LocalDateTime dayBeforeYesterday = yesterday.minusDays(1); gamblingGoal = BudgetGoal.createNoGoInstance(dayBeforeYesterday, ActivityCategory.createInstance(UUID.randomUUID(), usString("gambling"), false, new HashSet<>(Arrays.asList("poker", "lotto")), new HashSet<>(Arrays.asList("Poker App", "Lotto App")), usString("Descr"))); newsGoal = BudgetGoal.createNoGoInstance(dayBeforeYesterday, ActivityCategory.createInstance(UUID.randomUUID(), usString("news"), false, new HashSet<>(Arrays.asList("refdag", "bbc")), Collections.emptySet(), usString("Descr"))); gamingGoal = BudgetGoal.createNoGoInstance(dayBeforeYesterday, ActivityCategory.createInstance(UUID.randomUUID(), usString("gaming"), false, new HashSet<>(Arrays.asList("games")), Collections.emptySet(), usString("Descr"))); socialGoal = TimeZoneGoal.createInstance(dayBeforeYesterday, ActivityCategory.createInstance(UUID.randomUUID(), usString("social"), false, new HashSet<>(Arrays.asList("social")), Collections.emptySet(), usString("Descr")), Collections.emptyList()); shoppingGoal = BudgetGoal .createInstance(dayBeforeYesterday, ActivityCategory.createInstance(UUID.randomUUID(), usString("shopping"), false, new HashSet<>(Arrays.asList("webshop")), Collections.emptySet(), usString("Descr")), 1); shoppingGoalHistoryItem = shoppingGoal.cloneAsHistoryItem(yesterday); // Set up UserAnonymized instance. MessageDestination anonMessageDestinationEntity = MessageDestination .createInstance(PublicKeyUtil.generateKeyPair().getPublic()); Set<Goal> goals = new HashSet<>( Arrays.asList(gamblingGoal, gamingGoal, socialGoal, shoppingGoal, shoppingGoalHistoryItem)); deviceAnonEntity = DeviceAnonymized.createInstance(0, operatingSystem, "Unknown", 0, Optional.empty()); userAnonEntity = UserAnonymized.createInstance(anonMessageDestinationEntity, goals); userAnonEntity.addDeviceAnonymized(deviceAnonEntity); userAnonDto = UserAnonymizedDto.createInstance(userAnonEntity); deviceAnonDto = DeviceAnonymizedDto.createInstance(deviceAnonEntity); userAnonZoneId = userAnonDto.getTimeZone(); } private void setUpRepositoryMocks() { JUnitUtil.setUpRepositoryMock(mockGoalRepository); Map<Class<?>, Repository<?, ?>> repositoriesMap = new HashMap<>(); repositoriesMap.put(Goal.class, mockGoalRepository); JUnitUtil.setUpRepositoryProviderMock(repositoriesMap); } private Map<Locale, String> usString(String string) { return Collections.singletonMap(Translator.EN_US_LOCALE, string); } @Test public void determineRelevantGoals_appActivityNotAUserGoal_emptySet() { Set<GoalDto> relevantGoals = AnalysisEngineService .determineRelevantGoals(makeAppPayload(makeCategorySet(newsGoal))); assertThat(relevantGoals, empty()); } @Test public void determineRelevantGoals_appActivityOneUserGoal_userGoal() { Set<GoalDto> relevantGoals = AnalysisEngineService .determineRelevantGoals(makeAppPayload(makeCategorySet(socialGoal))); assertThat(relevantGoals, containsInAnyOrder(GoalDto.createInstance(socialGoal))); } @Test public void determineRelevantGoals_appActivityTwoUserGoals_bothUserGoals() { Set<GoalDto> relevantGoals = AnalysisEngineService .determineRelevantGoals(makeAppPayload(makeCategorySet(socialGoal, gamblingGoal))); assertThat(relevantGoals, containsInAnyOrder(GoalDto.createInstance(socialGoal), GoalDto.createInstance(gamblingGoal))); } @Test public void determineRelevantGoals_appActivityTwoGoalsOneUserGoal_userGoal() { Set<GoalDto> relevantGoals = AnalysisEngineService .determineRelevantGoals(makeAppPayload(makeCategorySet(newsGoal, gamblingGoal))); assertThat(relevantGoals, containsInAnyOrder(GoalDto.createInstance(gamblingGoal))); } @Test public void determineRelevantGoals_appActivityBeforeGoalStart_emptySet() { Set<GoalDto> relevantGoals = AnalysisEngineService .determineRelevantGoals(makeAppPayload(makeCategorySet(socialGoal), Duration.ofDays(3))); assertThat(relevantGoals, empty()); } @Test public void determineRelevantGoals_appActivityOnGoalWithHistory_oneGoalReturned() { Set<GoalDto> relevantGoals = AnalysisEngineService .determineRelevantGoals(makeAppPayload(makeCategorySet(shoppingGoal), Duration.ofDays(1))); assertThat(relevantGoals, containsInAnyOrder(GoalDto.createInstance(shoppingGoal))); } @Test public void determineRelevantGoals_networkActivityOneNoGoUserGoal_userGoal() { Set<GoalDto> relevantGoals = AnalysisEngineService .determineRelevantGoals(makeNetworkPayload(makeCategorySet(gamingGoal))); assertThat(relevantGoals, containsInAnyOrder(GoalDto.createInstance(gamingGoal))); } @Test public void determineRelevantGoals_networkActivityOneOptionalUserGoal_userGoalOnIOs() { Set<GoalDto> relevantGoals = AnalysisEngineService .determineRelevantGoals(makeNetworkPayload(makeCategorySet(socialGoal))); if (isIOs) { assertThat(relevantGoals, containsInAnyOrder(GoalDto.createInstance(socialGoal))); } else { assertThat(relevantGoals, empty()); } } private Set<ActivityCategoryDto> makeCategorySet(Goal... goals) { return Arrays.asList(goals).stream().map(Goal::getActivityCategory).map(ActivityCategoryDto::createInstance) .collect(Collectors.toSet()); } private ActivityPayload makeAppPayload(Set<ActivityCategoryDto> activityCategories) { return makeAppPayload(activityCategories, Duration.ofDays(0)); } private ActivityPayload makeAppPayload(Set<ActivityCategoryDto> activityCategories, Duration timeAgo) { ZonedDateTime endTime = now().minus(timeAgo); ZonedDateTime startTime = endTime.minusMinutes(2); return ActivityPayload.createInstance(userAnonDto, deviceAnonDto, startTime, endTime, "n/a", activityCategories); } private ActivityPayload makeNetworkPayload(Set<ActivityCategoryDto> activityCategories) { return makeNetworkPayload(activityCategories, Duration.ofDays(0)); } private ActivityPayload makeNetworkPayload(Set<ActivityCategoryDto> activityCategories, Duration timeAgo) { ZonedDateTime eventTime = now().minus(timeAgo); NetworkActivityDto networkActivity = new NetworkActivityDto(-1, Collections.singleton("n/a"), "n/a", Optional.of(eventTime)); return ActivityPayload.createInstance(userAnonDto, deviceAnonDto, networkActivity, activityCategories); } private ZonedDateTime now() { return ZonedDateTime.now().withZoneSameInstant(userAnonZoneId); } }