public void MarksTheActionForOnboardingPurposes()
            {
                ViewModel.StopTimeEntry.Execute(Arg.Any <TimeEntryStopOrigin>());

                TestScheduler.Start();
                OnboardingStorage.Received().StopButtonWasTapped();
            }
                public async void DoesNotShowTheRatingViewIfAfter24HourSnooze()
                {
                    var defaultRemoteConfiguration = new RatingViewConfiguration(5, RatingViewCriterion.Start);

                    RemoteConfigService
                    .GetRatingViewConfiguration()
                    .Returns(defaultRemoteConfiguration);

                    var now             = DateTimeOffset.Now;
                    var firstOpened     = now - TimeSpan.FromDays(6);
                    var lastInteraction = now - TimeSpan.FromDays(2);

                    TimeService.CurrentDateTime.Returns(now);
                    OnboardingStorage.GetFirstOpened().Returns(firstOpened);
                    OnboardingStorage.RatingViewOutcome().Returns(RatingViewOutcome.AppWasNotRated);
                    OnboardingStorage.RatingViewOutcomeTime().Returns(lastInteraction);

                    await ViewModel.Initialize();

                    var observer = TestScheduler.CreateObserver <bool>();

                    ViewModel.ShouldShowRatingView.Subscribe(observer);

                    TestScheduler.Start();
                    observer.LastEmittedValue().Should().BeFalse();
                }
            protected override void AdditionalSetup()
            {
                OnboardingStorage
                .CompletedCalendarOnboarding()
                .Returns(true);

                PermissionsService
                .CalendarPermissionGranted
                .Returns(Observable.Return(true));

                NavigationService
                .Navigate <SelectUserCalendarsViewModel, bool, string[]>(Arg.Any <bool>())
                .Returns(new string[0]);

                InteractorFactory
                .GetUserCalendars()
                .Execute()
                .Returns(Observable.Return(new UserCalendar().Yield()));

                DialogService
                .Alert(Arg.Any <string>(), Arg.Any <string>(), Arg.Any <string>())
                .Returns(Observable.Return(Unit.Default));

                TestScheduler.AdvanceBy(1);
            }
Beispiel #4
0
        private async Task timeEntrySelected(EditTimeEntryInfo editTimeEntryInfo)
        {
            OnboardingStorage.TimeEntryWasTapped();

            analyticsService.EditViewOpened.Track(editTimeEntryInfo.Origin);
            await navigate <EditTimeEntryViewModel, long[]>(editTimeEntryInfo.Ids);
        }
Beispiel #5
0
            public void SetsUserSignedUp()
            {
                ExecuteCommand();

                TestScheduler.Start();
                OnboardingStorage.Received().SetUserSignedUp();
            }
Beispiel #6
0
            public void SetsIsNewUserToTrue()
            {
                ExecuteCommand();

                TestScheduler.Start();
                OnboardingStorage.Received().SetIsNewUser(true);
            }
            public void MarksTheUserAsNotNewWhenUsingTheAppForTheFirstTimeAfterSixtyDays()
            {
                var now = DateTimeOffset.Now;

                TimeService.CurrentDateTime.Returns(now);
                OnboardingStorage.GetLastOpened().Returns(now.AddDays(-60));
                var dependencyContainer = new TestDependencyContainer
                {
                    MockTimeService              = TimeService,
                    MockUserAccessManager        = UserAccessManager,
                    MockNavigationService        = NavigationService,
                    MockOnboardingStorage        = OnboardingStorage,
                    MockAccessRestrictionStorage = AccessRestrictionStorage,
                    MockSyncManager              = Substitute.For <ISyncManager>(),
                    MockInteractorFactory        = Substitute.For <IInteractorFactory>(),
                    MockBackgroundSyncService    = Substitute.For <IBackgroundSyncService>()
                };

                var app = new AppStart(dependencyContainer);

                app.UpdateOnboardingProgress();

                OnboardingStorage.Received().SetLastOpened(now);
                OnboardingStorage.Received().SetIsNewUser(false);
            }
Beispiel #8
0
        private async Task save()
        {
            OnboardingStorage.EditedTimeEntry();

            var timeEntries = await interactorFactory.GetMultipleTimeEntriesById(TimeEntryIds).Execute();

            var duration = await durationSubject.FirstAsync();

            var commonTimeEntryData = new EditTimeEntryDto
            {
                Id          = TimeEntryIds.First(),
                Description = Description.Value?.Trim() ?? string.Empty,
                StartTime   = startTimeSubject.Value,
                StopTime    = calculateStopTime(startTimeSubject.Value, duration),
                ProjectId   = projectId,
                TaskId      = taskId,
                Billable    = isBillableSubject.Value,
                WorkspaceId = workspaceId,
                TagIds      = tagIds.ToArray()
            };

            var timeEntriesDtos = timeEntries
                                  .Select(timeEntry => applyDataFromTimeEntry(commonTimeEntryData, timeEntry))
                                  .ToArray();

            interactorFactory
            .UpdateMultipleTimeEntries(timeEntriesDtos)
            .Execute()
            .SubscribeToErrorsAndCompletion((Exception ex) => close(), () => close())
            .DisposedBy(disposeBag);
        }
            public void MarksTheActionButtonTappedForOnboardingPurposes(bool useDefaultMode)
            {
                ViewModel.StartTimeEntry.Execute(useDefaultMode);

                TestScheduler.Start();
                OnboardingStorage.Received().StartButtonWasTapped();
            }
Beispiel #10
0
            public async Task MarksTheActionForOnboardingPurposes()
            {
                var suggestion = createSuggestion();

                await ViewModel.StartTimeEntryCommand.ExecuteAsync(suggestion);

                OnboardingStorage.Received().SetTimeEntryContinued();
            }
Beispiel #11
0
            public async ThreadingTask MarksTheActionForOnboardingPurposes()
            {
                var timeEntryViewModel = createTimeEntryViewModel();

                await ViewModel.ContinueTimeEntryCommand.ExecuteAsync(timeEntryViewModel);

                OnboardingStorage.Received().SetTimeEntryContinued();
            }
Beispiel #12
0
            public void SetsFirstOpenedTime()
            {
                TimeService.CurrentDateTime.Returns(new DateTimeOffset(2020, 1, 2, 3, 4, 5, TimeSpan.Zero));

                AppStart.Start();

                OnboardingStorage.Received().SetFirstOpened(TimeService.CurrentDateTime);
            }
            public async Task NavigatesToTheLoginPageIfUserHasCompletedOnboarding()
            {
                OnboardingStorage.CompletedOnboarding().Returns(true);

                await ViewModel.Initialize();

                await NavigationService.Received().Navigate <LoginViewModel>();
            }
            public void InitializesCurrentPageToTrackPageIfUserHasCompletedOnboarding()
            {
                OnboardingStorage.CompletedOnboarding().Returns(true);

                ViewModel.Prepare();

                ViewModel.CurrentPage.Should().Be(OnboardingViewModel.LoginPage);
            }
Beispiel #15
0
                public async Task StoresTheAppropriateRatingViewOutcomeAndTime()
                {
                    await ViewModel.PerformMainAction();

                    OnboardingStorage
                    .Received()
                    .SetRatingViewOutcome(ExpectedStoragetOutcome, CurrentDateTime);
                }
Beispiel #16
0
        private async Task selectProject()
        {
            analyticsService.EditEntrySelectProject.Track();
            analyticsService.EditViewTapped.Track(EditViewTapSource.Project);

            OnboardingStorage.SelectsProject();

            var selectProjectStopwatch = stopwatchProvider.CreateAndStore(
                MeasuredOperation.OpenSelectProjectFromEditView, true);

            selectProjectStopwatch.Start();

            var chosenProject = await navigationService
                                .Navigate <SelectProjectViewModel, SelectProjectParameter, SelectProjectParameter>(
                SelectProjectParameter.WithIds(projectId, taskId, workspaceId));

            if (chosenProject.WorkspaceId == workspaceId &&
                chosenProject.ProjectId == projectId &&
                chosenProject.TaskId == taskId)
            {
                return;
            }

            projectId = chosenProject.ProjectId;
            taskId    = chosenProject.TaskId;

            if (projectId == null)
            {
                projectClientTaskSubject.OnNext(ProjectClientTaskInfo.Empty);

                clearTagsIfNeeded(workspaceId, chosenProject.WorkspaceId);
                workspaceIdSubject.OnNext(chosenProject.WorkspaceId);

                var workspace = await interactorFactory.GetWorkspaceById(chosenProject.WorkspaceId).Execute();

                isInaccessibleSubject.OnNext(workspace.IsInaccessible);

                return;
            }

            var project = await interactorFactory.GetProjectById(projectId.Value).Execute();

            clearTagsIfNeeded(workspaceId, project.WorkspaceId);

            var taskName = chosenProject.TaskId.HasValue
                ? (await interactorFactory.GetTaskById(taskId.Value).Execute())?.Name
                : string.Empty;

            projectClientTaskSubject.OnNext(new ProjectClientTaskInfo(
                                                project.DisplayName(),
                                                project.DisplayColor(),
                                                project.Client?.Name,
                                                taskName));

            workspaceIdSubject.OnNext(chosenProject.WorkspaceId);

            isInaccessibleSubject.OnNext(project.IsInaccessible);
        }
Beispiel #17
0
            public async ThreadingTask SetsTheIsWelcomePropertyToFalse()
            {
                OnboardingStorage.IsNewUser().Returns(true);
                await ViewModel.Initialize();

                TimeEntryCreatedSubject.OnNext(NewTimeEntry.With((long)TimeSpan.FromHours(1).TotalSeconds));

                ViewModel.IsWelcome.Should().BeFalse();
            }
Beispiel #18
0
                public async Task StoresTheAppropriateRatingViewOutcomeAndTime()
                {
                    ViewModel.PerformMainAction.Execute();
                    TestScheduler.Start();

                    OnboardingStorage
                    .Received()
                    .SetRatingViewOutcome(ExpectedStoragetOutcome, CurrentDateTime);
                }
Beispiel #19
0
            public async ThreadingTask SetsTheUserIsNotNewFlagToFalseInTheStorage()
            {
                OnboardingStorage.IsNewUser().Returns(true);
                await ViewModel.Initialize();

                TimeEntryCreatedSubject.OnNext(NewTimeEntry.With((long)TimeSpan.FromHours(1).TotalSeconds));

                OnboardingStorage.Received().SetIsNewUser(false);
            }
            public async Task SetsCalendarOnboardingAsCompletedIfUserGrantsAccess()
            {
                PermissionsService.RequestCalendarAuthorization().Returns(Observable.Return(true));
                NavigationService.Navigate <SelectUserCalendarsViewModel, string[]>().Returns(new string[0]);

                ViewModel.GetStarted.Execute(Unit.Default);

                OnboardingStorage.Received().SetCompletedCalendarOnboarding();
            }
            public async ThreadingTask MarksTheActionAfterStopButtonForOnboardingPurposes()
            {
                OnboardingStorage.StopButtonWasTappedBefore.Returns(Observable.Return(true));
                ViewModel.Initialize().Wait();

                await ViewModel.OpenSettingsCommand.ExecuteAsync();

                OnboardingStorage.Received().SetNavigatedAwayFromMainViewAfterStopButton();
            }
            public async ThreadingTask MarksTheActionNavigatedAwayBeforeStopButtonForOnboardingPurposes()
            {
                OnboardingStorage.StopButtonWasTappedBefore.Returns(Observable.Return(false));
                ViewModel.Initialize().Wait();

                await CallCommand();

                OnboardingStorage.DidNotReceive().SetNavigatedAwayFromMainViewAfterStopButton();
            }
Beispiel #23
0
            public async Task SetsCalendarOnboardingAsCompletedIfUserGrantsAccess()
            {
                View.RequestCalendarAuthorization().Returns(Observable.Return(true));
                NavigationService.Navigate <SelectUserCalendarsViewModel, bool, string[]>(Arg.Any <bool>(), ViewModel.View).Returns(new string[0]);

                Action.Execute(Unit.Default);

                OnboardingStorage.Received().SetCompletedCalendarOnboarding();
            }
            public async Task SetsCalendarOnboardingAsCompletedIfUserWantsToContinueWithoutGivingPermission()
            {
                PermissionsService.RequestCalendarAuthorization().Returns(Observable.Return(false));
                NavigationService.Navigate <CalendarPermissionDeniedViewModel, Unit>().Returns(Unit.Default);

                await ViewModel.GetStartedAction.Execute(Unit.Default);

                OnboardingStorage.Received().SetCompletedCalendarOnboarding();
            }
Beispiel #25
0
        private async Task selectProject()
        {
            analyticsService.EditEntrySelectProject.Track();
            analyticsService.EditViewTapped.Track(EditViewTapSource.Project);

            OnboardingStorage.SelectsProject();

            var chosenProject = await Navigate <SelectProjectViewModel, SelectProjectParameter, SelectProjectParameter>(
                new SelectProjectParameter(projectId, taskId, workspaceId));

            if (chosenProject.WorkspaceId == workspaceId &&
                chosenProject.ProjectId == projectId &&
                chosenProject.TaskId == taskId)
            {
                return;
            }

            projectId = chosenProject.ProjectId;
            taskId    = chosenProject.TaskId;

            if (projectId == null)
            {
                projectClientTaskSubject.OnNext(ProjectClientTaskInfo.Empty);

                clearTagsIfNeeded(workspaceId, chosenProject.WorkspaceId);
                workspaceIdSubject.OnNext(chosenProject.WorkspaceId);

                var workspace = await interactorFactory.GetWorkspaceById(chosenProject.WorkspaceId).Execute();

                isInaccessibleSubject.OnNext(workspace.IsInaccessible);

                return;
            }

            var project = await interactorFactory.GetProjectById(projectId.Value).Execute();

            clearTagsIfNeeded(workspaceId, project.WorkspaceId);

            var task = chosenProject.TaskId.HasValue
                ? await interactorFactory.GetTaskById(taskId.Value).Execute()
                : null;

            var taskName = task?.Name ?? string.Empty;

            projectClientTaskSubject.OnNext(new ProjectClientTaskInfo(
                                                project.DisplayName(),
                                                project.DisplayColor(),
                                                project.Client?.Name,
                                                taskName,
                                                project.IsPlaceholder(),
                                                task?.IsPlaceholder() ?? false));

            workspaceIdSubject.OnNext(chosenProject.WorkspaceId);

            isInaccessibleSubject.OnNext(project.IsInaccessible);
        }
            public void MarksTheActionAfterStopButtonForOnboardingPurposes()
            {
                OnboardingStorage.StopButtonWasTappedBefore.Returns(Observable.Return(true));
                ViewModel.Initialize().Wait();

                ViewModel.OpenSettings.Execute();

                TestScheduler.Start();
                OnboardingStorage.Received().SetNavigatedAwayFromMainViewAfterStopButton();
            }
Beispiel #27
0
        private Task navigate <TModel, TParameters>(TParameters value)
            where TModel : ViewModelWithInput <TParameters>
        {
            if (hasStopButtonEverBeenUsed)
            {
                OnboardingStorage.SetNavigatedAwayFromMainViewAfterStopButton();
            }

            return(Navigate <TModel, TParameters>(value));
        }
Beispiel #28
0
        private Task navigate <TModel>()
            where TModel : ViewModel
        {
            if (hasStopButtonEverBeenUsed)
            {
                OnboardingStorage.SetNavigatedAwayFromMainViewAfterStopButton();
            }

            return(Navigate <TModel>());
        }
Beispiel #29
0
        private Task startTimeEntry(bool initializeInManualMode)
        {
            OnboardingStorage.StartButtonWasTapped();

            var parameter = initializeInManualMode
                ? StartTimeEntryParameters.ForManualMode(timeService.CurrentDateTime)
                : StartTimeEntryParameters.ForTimerMode(timeService.CurrentDateTime);

            return(navigationService.Navigate <StartTimeEntryViewModel, StartTimeEntryParameters>(parameter));
        }
Beispiel #30
0
        private async Task stopTimeEntry(TimeEntryStopOrigin origin)
        {
            OnboardingStorage.StopButtonWasTapped();

            await interactorFactory
            .StopTimeEntry(TimeService.CurrentDateTime, origin)
            .Execute()
            .Do(_ => intentDonationService.DonateStopCurrentTimeEntry())
            .Do(dataSource.SyncManager.InitiatePushSync);
        }