public RepositoryViewModel(RepositoryDatabase repositoryDatabase, GitHubAuthenticationService gitHubAuthenticationService, GitHubGraphQLApiService gitHubGraphQLApiService, IAnalyticsService analyticsService, MobileSortingService sortingService, GitHubApiV3Service gitHubApiV3Service, NotificationService notificationService, IMainThread mainThread, GitHubUserService gitHubUserService) : base(analyticsService, mainThread) { LanguageService.PreferredLanguageChanged += HandlePreferredLanguageChanged; SetTitleText(); _repositoryDatabase = repositoryDatabase; _gitHubAuthenticationService = gitHubAuthenticationService; _gitHubGraphQLApiService = gitHubGraphQLApiService; _sortingService = sortingService; _gitHubApiV3Service = gitHubApiV3Service; _gitHubUserService = gitHubUserService; RefreshState = RefreshState.Uninitialized; PullToRefreshCommand = new AsyncCommand(() => ExecutePullToRefreshCommand(gitHubUserService.Alias)); FilterRepositoriesCommand = new Command <string>(SetSearchBarText); SortRepositoriesCommand = new Command <SortingOption>(ExecuteSortRepositoriesCommand); notificationService.SortingOptionRequested += HandleSortingOptionRequested; gitHubAuthenticationService.LoggedOut += HandleGitHubAuthenticationServiceLoggedOut; gitHubAuthenticationService.AuthorizeSessionCompleted += HandleAuthorizeSessionCompleted; gitHubAuthenticationService.DemoUserActivated += HandleDemoUserActivated; }
public void GetSortingCategoryTest_InvalidOption(SortingOption sortingOption) { //Arrange //Act //Assert Assert.Throws <NotSupportedException>(() => MobileSortingService.GetSortingCategory(sortingOption)); }
public void SortReferringSitesTests() { const int largestTotalCount = 1000; const int largestTotalUniqueCount = 11; const string lastReferer = "t.co"; //Arrange var referringSitesList = new List <MobileReferringSiteModel> { new MobileReferringSiteModel(new ReferringSiteModel(10, 10, "Google")), new MobileReferringSiteModel(new ReferringSiteModel(10, 10, "codetraver.io")), new MobileReferringSiteModel(new ReferringSiteModel(10, 10, lastReferer)), new MobileReferringSiteModel(new ReferringSiteModel(100, largestTotalUniqueCount, "facebook.com")), new MobileReferringSiteModel(new ReferringSiteModel(100, 9, "linkedin.com")), new MobileReferringSiteModel(new ReferringSiteModel(largestTotalCount, 9, "reddit.com")) }; //Act var sortedReferringSitesList = MobileSortingService.SortReferringSites(referringSitesList); //Assert Assert.IsTrue(sortedReferringSitesList.First().TotalCount is largestTotalCount); Assert.IsTrue(sortedReferringSitesList.Skip(1).First().TotalUniqueCount is largestTotalUniqueCount); Assert.IsTrue(sortedReferringSitesList.Last().Referrer is lastReferer); }
public InformationButton(MobileSortingService mobileSortingService, IMainThread mainThread) { _mainThread = mainThread; RowDefinitions = Rows.Define(AbsoluteGridLength(_diameter)); ColumnDefinitions = Columns.Define(AbsoluteGridLength(_diameter)); Children.Add(new FloatingActionTextButton(mobileSortingService, FloatingActionButtonSize.Mini, FloatingActionButtonType.Statistic1).Assign(out _statistic1FloatingActionButton) .Bind <FloatingActionTextButton, IReadOnlyList <Repository>, string>(FloatingActionTextButton.TextProperty, nameof(RepositoryViewModel.VisibleRepositoryList), convert: repositories => GetLabelTextConverter(mobileSortingService, repositories, FloatingActionButtonType.Statistic1)) .Invoke(fab => fab.SetBinding(IsVisibleProperty, getIsVisibleBinding()))); Children.Add(new FloatingActionTextButton(mobileSortingService, FloatingActionButtonSize.Mini, FloatingActionButtonType.Statistic2).Assign(out _statistic2FloatingActionButton) .Bind <FloatingActionTextButton, IReadOnlyList <Repository>, string>(FloatingActionTextButton.TextProperty, nameof(RepositoryViewModel.VisibleRepositoryList), convert: repositories => GetLabelTextConverter(mobileSortingService, repositories, FloatingActionButtonType.Statistic2)) .Invoke(fab => fab.SetBinding(IsVisibleProperty, getIsVisibleBinding()))); Children.Add(new FloatingActionTextButton(mobileSortingService, FloatingActionButtonSize.Mini, FloatingActionButtonType.Statistic3).Assign(out _statistic3FloatingActionButton) .Bind <FloatingActionTextButton, IReadOnlyList <Repository>, string>(FloatingActionTextButton.TextProperty, nameof(RepositoryViewModel.VisibleRepositoryList), convert: repositories => GetLabelTextConverter(mobileSortingService, repositories, FloatingActionButtonType.Statistic3)) .Invoke(fab => fab.SetBinding(IsVisibleProperty, getIsVisibleBinding()))); Children.Add(new FloatingActionTextButton(mobileSortingService, FloatingActionButtonSize.Normal, FloatingActionButtonType.Information, new AsyncCommand(ExecuteFloatingActionButtonCommand)) { FontFamily = FontFamilyConstants.RobotoMedium, Text = "TOTAL" }.Center() .DynamicResource(FloatingActionButtonView.RippleColorProperty, nameof(BaseTheme.PageBackgroundColor)) .Invoke(fab => fab.SetBinding(IsVisibleProperty, getIsVisibleBinding())));
public ExtendedNotificationService(IPreferences preferences, ISecureStorage secureStorage, IAnalyticsService analyticsService, MobileSortingService sortingService, DeepLinkingService deepLinkingService, INotificationManager notificationManager, INotificationService notificationService, AzureFunctionsApiService azureFunctionsApiService) : base(preferences, secureStorage, analyticsService, sortingService, deepLinkingService, notificationManager, notificationService, azureFunctionsApiService) { }
public void GetSortingCategoryTest_ValidOption(SortingOption sortingOption, SortingCategory expectedSortingCategory) { //Arrange SortingCategory actualSortingCategory; //Act actualSortingCategory = MobileSortingService.GetSortingCategory(sortingOption); //Assert Assert.AreEqual(expectedSortingCategory, actualSortingCategory); }
public async Task VerifySortingOptions(SortingOption sortingOption) { //Fail all tests if the DefaultSortingOption has changed Assert.AreEqual(MobileSortingService.DefaultSortingOption, SortingOption.Views); //Arrange string floatingActionTextButtonStatistic1Text, floatingActionTextButtonStatistic2Text, floatingActionTextButtonStatistic3Text; Repository finalFirstRepository, finalSecondTopRepository, finalLastRepository; Repository initialFirstRepository = RepositoryPage.VisibleCollection.First(); Repository initialSecondTopRepository = RepositoryPage.VisibleCollection.Skip(1).First(); Repository initialLastRepository = RepositoryPage.VisibleCollection.Last(); //Act await RepositoryPage.SetSortingOption(sortingOption).ConfigureAwait(false); floatingActionTextButtonStatistic1Text = RepositoryPage.InformationButtonStatistic1Text; floatingActionTextButtonStatistic2Text = RepositoryPage.InformationButtonStatistic2Text; floatingActionTextButtonStatistic3Text = RepositoryPage.InformationButtonStatistic3Text; RepositoryPage.TapInformationButton(); //Assert finalFirstRepository = RepositoryPage.VisibleCollection.First(); finalSecondTopRepository = RepositoryPage.VisibleCollection.Skip(1).First(); finalLastRepository = RepositoryPage.VisibleCollection.Last(); if (initialFirstRepository.IsTrending == initialSecondTopRepository.IsTrending) { Assert.GreaterOrEqual(initialFirstRepository.TotalViews, initialSecondTopRepository.TotalViews); } Assert.GreaterOrEqual(initialFirstRepository.TotalViews, initialLastRepository.TotalViews); var floatingActionTextButtonStatistic1Text_Expected = StatisticsService.GetFloatingActionTextButtonText(MobileSortingService.GetSortingCategory(sortingOption), RepositoryPage.VisibleCollection, FloatingActionButtonType.Statistic1); var floatingActionTextButtonStatistic2Text_Expected = StatisticsService.GetFloatingActionTextButtonText(MobileSortingService.GetSortingCategory(sortingOption), RepositoryPage.VisibleCollection, FloatingActionButtonType.Statistic2); var floatingActionTextButtonStatistic3Text_Expected = StatisticsService.GetFloatingActionTextButtonText(MobileSortingService.GetSortingCategory(sortingOption), RepositoryPage.VisibleCollection, FloatingActionButtonType.Statistic3); Assert.AreEqual(floatingActionTextButtonStatistic1Text_Expected, floatingActionTextButtonStatistic1Text); Assert.AreEqual(floatingActionTextButtonStatistic2Text_Expected, floatingActionTextButtonStatistic2Text); Assert.AreEqual(floatingActionTextButtonStatistic3Text_Expected, floatingActionTextButtonStatistic3Text); switch (sortingOption) { case SortingOption.Views when finalFirstRepository.IsTrending == finalSecondTopRepository.IsTrending: Assert.LessOrEqual(finalFirstRepository.TotalViews, finalSecondTopRepository.TotalViews); break; case SortingOption.Views: Assert.LessOrEqual(finalSecondTopRepository.TotalViews, finalLastRepository.TotalViews); break; case SortingOption.Stars when finalFirstRepository.IsTrending == finalSecondTopRepository.IsTrending: Assert.GreaterOrEqual(finalFirstRepository.StarCount, finalSecondTopRepository.StarCount); break; case SortingOption.Stars: Assert.GreaterOrEqual(finalSecondTopRepository.StarCount, finalLastRepository.StarCount); break; case SortingOption.Forks when finalFirstRepository.IsTrending == finalSecondTopRepository.IsTrending: Assert.GreaterOrEqual(finalFirstRepository.ForkCount, finalSecondTopRepository.ForkCount); break; case SortingOption.Forks: Assert.GreaterOrEqual(finalSecondTopRepository.ForkCount, finalLastRepository.ForkCount); break; case SortingOption.Issues when finalFirstRepository.IsTrending == finalSecondTopRepository.IsTrending: Assert.GreaterOrEqual(finalFirstRepository.IssuesCount, finalSecondTopRepository.IssuesCount); break; case SortingOption.Issues: Assert.GreaterOrEqual(finalSecondTopRepository.IssuesCount, finalLastRepository.IssuesCount); break; case SortingOption.Clones when finalFirstRepository.IsTrending == finalSecondTopRepository.IsTrending: Assert.GreaterOrEqual(finalFirstRepository.TotalClones, finalSecondTopRepository.TotalClones); break; case SortingOption.Clones: Assert.GreaterOrEqual(finalSecondTopRepository.TotalClones, finalLastRepository.TotalClones); break; case SortingOption.UniqueClones when finalFirstRepository.IsTrending == finalSecondTopRepository.IsTrending: Assert.GreaterOrEqual(finalFirstRepository.TotalUniqueClones, finalSecondTopRepository.TotalUniqueClones); break; case SortingOption.UniqueClones: Assert.GreaterOrEqual(finalSecondTopRepository.TotalUniqueClones, finalLastRepository.TotalUniqueClones); break; case SortingOption.UniqueViews when finalFirstRepository.IsTrending == finalSecondTopRepository.IsTrending: Assert.GreaterOrEqual(finalFirstRepository.TotalUniqueViews, finalSecondTopRepository.TotalUniqueViews); break; case SortingOption.UniqueViews: Assert.GreaterOrEqual(finalSecondTopRepository.TotalUniqueViews, finalLastRepository.TotalUniqueViews); break; default: throw new NotSupportedException(); } ; }
public RepositoryPage(RepositoryViewModel repositoryViewModel, IAnalyticsService analyticsService, MobileSortingService sortingService, DeepLinkingService deepLinkingService, IMainThread mainThread, FirstRunService firstRunService, GitHubUserService gitHubUserService) : base(repositoryViewModel, analyticsService, mainThread) { _firstRunService = firstRunService; _gitHubUserService = gitHubUserService; _deepLinkingService = deepLinkingService; ViewModel.PullToRefreshFailed += HandlePullToRefreshFailed; SearchBarTextChanged += HandleSearchBarTextChanged; var collectionView = new CollectionView { ItemTemplate = new RepositoryDataTemplateSelector(sortingService), BackgroundColor = Color.Transparent, SelectionMode = SelectionMode.Single, AutomationId = RepositoryPageAutomationIds.CollectionView, //Work around for https://github.com/xamarin/Xamarin.Forms/issues/9879 Header = Device.RuntimePlatform is Device.Android ? new BoxView { HeightRequest = BaseRepositoryDataTemplate.BottomPadding } : null, Footer = Device.RuntimePlatform is Device.Android ? new BoxView { HeightRequest = BaseRepositoryDataTemplate.TopPadding } : null, EmptyView = new EmptyDataView("EmptyRepositoriesList", RepositoryPageAutomationIds.EmptyDataView) .Bind <EmptyDataView, bool, bool>(IsVisibleProperty, nameof(RepositoryViewModel.IsRefreshing), convert: isRefreshing => !isRefreshing) .Bind(EmptyDataView.TitleProperty, nameof(RepositoryViewModel.EmptyDataViewTitle)) .Bind(EmptyDataView.DescriptionProperty, nameof(RepositoryViewModel.EmptyDataViewDescription)) }; collectionView.SelectionChanged += HandleCollectionViewSelectionChanged; collectionView.SetBinding(CollectionView.ItemsSourceProperty, nameof(RepositoryViewModel.VisibleRepositoryList)); _refreshView = new RefreshView { AutomationId = RepositoryPageAutomationIds.RefreshView, Content = collectionView }.DynamicResource(RefreshView.RefreshColorProperty, nameof(BaseTheme.PullToRefreshColor)) .Bind(RefreshView.IsRefreshingProperty, nameof(RepositoryViewModel.IsRefreshing)) .Bind(RefreshView.CommandProperty, nameof(RepositoryViewModel.PullToRefreshCommand)); var settingsToolbarItem = new ToolbarItem { Text = PageTitles.SettingsPage, IconImageSource = Device.RuntimePlatform is Device.iOS ? "Settings" : null, Order = Device.RuntimePlatform is Device.Android ? ToolbarItemOrder.Secondary : ToolbarItemOrder.Default, AutomationId = RepositoryPageAutomationIds.SettingsButton, Command = new AsyncCommand(ExecuteSetttingsToolbarItemCommand) }; ToolbarItems.Add(settingsToolbarItem); var sortToolbarItem = new ToolbarItem { Text = RepositoryPageConstants.SortToolbarItemText, Priority = 1, IconImageSource = Device.RuntimePlatform is Device.iOS ? "Sort" : null, Order = Device.RuntimePlatform is Device.Android ? ToolbarItemOrder.Secondary : ToolbarItemOrder.Default, AutomationId = RepositoryPageAutomationIds.SortButton, Command = new AsyncCommand(ExecuteSortToolbarItemCommand) }; ToolbarItems.Add(sortToolbarItem); //Work-around to prevent LargeNavigationBar from collapsing when CollectionView is scrolled; prevents janky animation when LargeNavigationBar collapses if (Device.RuntimePlatform is Device.iOS) { Content = new Grid { Children = { new BoxView { HeightRequest = 0 }, _refreshView } }; } else { Content = _refreshView; } this.SetBinding(TitleProperty, nameof(RepositoryViewModel.TitleText)); }
public InformationButton(MobileSortingService mobileSortingService, in IMainThread mainThread, in IAnalyticsService analyticsService)
public RepositoryDataTemplateSelector(MobileSortingService sortingService) => _sortingService = sortingService;
public void SortRepositoriesTests(SortingOption sortingOption, bool isReversed) { //Arrange Repository topRepository, bottomRepository; List <Repository> repositoryList = new List <Repository>(); for (int i = 0; i < DemoDataConstants.RepoCount; i++) { repositoryList.Add(CreateRepository()); } //Act var sortedRepositoryList = MobileSortingService.SortRepositories(repositoryList, sortingOption, isReversed); topRepository = sortedRepositoryList.First(); bottomRepository = sortedRepositoryList.Last(); //Assert switch (sortingOption) { case SortingOption.Clones when isReversed: Assert.Less(topRepository.TotalClones, bottomRepository.TotalClones); break; case SortingOption.Clones: Assert.Greater(topRepository.TotalClones, bottomRepository.TotalClones); break; case SortingOption.Forks when isReversed: Assert.Less(topRepository.ForkCount, bottomRepository.ForkCount); break; case SortingOption.Forks: Assert.Greater(topRepository.ForkCount, bottomRepository.ForkCount); break; case SortingOption.Issues when isReversed: Assert.Less(topRepository.IssuesCount, bottomRepository.IssuesCount); break; case SortingOption.Issues: Assert.Greater(topRepository.IssuesCount, bottomRepository.IssuesCount); break; case SortingOption.Stars when isReversed: Assert.Less(topRepository.StarCount, bottomRepository.StarCount); break; case SortingOption.Stars: Assert.Greater(topRepository.StarCount, bottomRepository.StarCount); break; case SortingOption.UniqueClones when isReversed: Assert.Less(topRepository.TotalUniqueClones, bottomRepository.TotalUniqueClones); break; case SortingOption.UniqueClones: Assert.Greater(topRepository.TotalUniqueClones, bottomRepository.TotalUniqueClones); break; case SortingOption.UniqueViews when isReversed: Assert.Less(topRepository.TotalUniqueViews, bottomRepository.TotalUniqueViews); break; case SortingOption.UniqueViews: Assert.Greater(topRepository.TotalUniqueViews, bottomRepository.TotalUniqueViews); break; case SortingOption.Views when isReversed: Assert.Less(topRepository.TotalViews, bottomRepository.TotalViews); break; case SortingOption.Views: Assert.Greater(topRepository.TotalViews, bottomRepository.TotalViews); break; default: throw new NotSupportedException(); } }
public RepositoryPage(IMainThread mainThread, FirstRunService firstRunService, IAnalyticsService analyticsService, GitHubUserService gitHubUserService, DeepLinkingService deepLinkingService, RepositoryViewModel repositoryViewModel, MobileSortingService mobileSortingService) : base(repositoryViewModel, analyticsService, mainThread) { _firstRunService = firstRunService; _gitHubUserService = gitHubUserService; _deepLinkingService = deepLinkingService; SearchBarTextChanged += HandleSearchBarTextChanged; RepositoryViewModel.PullToRefreshFailed += HandlePullToRefreshFailed; LanguageService.PreferredLanguageChanged += HandlePreferredLanguageChanged; this.SetBinding(TitleProperty, nameof(RepositoryViewModel.TitleText)); ToolbarItems.Add(new ToolbarItem { Text = PageTitles.SettingsPage, IconImageSource = Device.RuntimePlatform is Device.iOS ? "Settings" : null, Order = Device.RuntimePlatform is Device.Android ? ToolbarItemOrder.Secondary : ToolbarItemOrder.Default, AutomationId = RepositoryPageAutomationIds.SettingsButton, Command = new AsyncCommand(ExecuteSetttingsToolbarItemCommand) }); ToolbarItems.Add(new ToolbarItem { Text = RepositoryPageConstants.SortToolbarItemText, Priority = 1, IconImageSource = Device.RuntimePlatform is Device.iOS ? "Sort" : null, Order = Device.RuntimePlatform is Device.Android ? ToolbarItemOrder.Secondary : ToolbarItemOrder.Default, AutomationId = RepositoryPageAutomationIds.SortButton, Command = new AsyncCommand(ExecuteSortToolbarItemCommand) }); Content = new Grid { RowDefinitions = Rows.Define( (Row.Totals, AbsoluteGridLength(125)), (Row.CollectionView, Star), (Row.Information, AbsoluteGridLength(100))), ColumnDefinitions = Columns.Define( (Column.CollectionView, Star), (Column.Information, AbsoluteGridLength(100))), Children = { new TotalsLabel().Row(Row.Totals).ColumnSpan(All <Column>()) .Bind <Label, bool, bool>(IsVisibleProperty, nameof(RepositoryViewModel.IsRefreshing), convert: isRefreshing => !isRefreshing) .Bind <Label, IReadOnlyList <Repository>, string>(Label.TextProperty, nameof(RepositoryViewModel.VisibleRepositoryList), convert: repositories => totalsLabelConverter(repositories, mobileSortingService)), new RefreshView { AutomationId = RepositoryPageAutomationIds.RefreshView, Content = new CollectionView { ItemTemplate = new RepositoryDataTemplateSelector(mobileSortingService), BackgroundColor = Color.Transparent, SelectionMode = SelectionMode.Single, AutomationId = RepositoryPageAutomationIds.CollectionView, //Work around for https://github.com/xamarin/Xamarin.Forms/issues/9879 Header = Device.RuntimePlatform is Device.Android ? new BoxView { HeightRequest = BaseRepositoryDataTemplate.BottomPadding } : null, Footer = Device.RuntimePlatform is Device.Android ? new BoxView { HeightRequest = BaseRepositoryDataTemplate.TopPadding } : null, EmptyView = new EmptyDataView("EmptyRepositoriesList",RepositoryPageAutomationIds.EmptyDataView) .Bind <EmptyDataView, bool, bool>(IsVisibleProperty, nameof(RepositoryViewModel.IsRefreshing), convert: isRefreshing => !isRefreshing) .Bind(EmptyDataView.TitleProperty, nameof(RepositoryViewModel.EmptyDataViewTitle)) .Bind(EmptyDataView.DescriptionProperty, nameof(RepositoryViewModel.EmptyDataViewDescription)) }.Bind(CollectionView.ItemsSourceProperty, nameof(RepositoryViewModel.VisibleRepositoryList)) .Invoke(collectionView => collectionView.SelectionChanged += HandleCollectionViewSelectionChanged) }.RowSpan(All <Row>()).ColumnSpan(All <Column>()).Assign(out _refreshView) .Bind(RefreshView.IsRefreshingProperty, nameof(RepositoryViewModel.IsRefreshing)) .Bind(RefreshView.CommandProperty, nameof(RepositoryViewModel.PullToRefreshCommand)) .DynamicResource(RefreshView.RefreshColorProperty, nameof(BaseTheme.PullToRefreshColor)), } }.Assign(out Grid grid);