/// <summary> /// Creates an <see cref="IAvatarProvider"/> based on the given /// <see cref="AvatarProvider"/> and <see cref="AvatarFallbackType"/> enum options. /// </summary> /// <returns>Returns an avatar provider that can be used to resolve user avatars.</returns> public static IAvatarProvider CreateAvatarProvider( AvatarProvider provider, AvatarFallbackType?fallbackType, IAvatarDownloader downloader = null) { // initialize download only if needed (some options, like local providers, don't need a downloader) // and use the downloader provided as parameter if possible. var lazyDownloader = new Lazy <IAvatarDownloader>(() => downloader ?? new AvatarDownloader()); // build collection of (non-null) providers var providers = new[] { BuildMainProvider(), BuildFallbackProvider() } .Where(p => p != null) .ToArray(); // only create chained avatar overhead if really needed return(providers.Length switch { 0 => null, 1 => providers[0], _ => new ChainedAvatarProvider(providers), });
public ActorViewModel(ActorModel model) { Login = model?.Login ?? "[unknown]"; if (model?.AvatarUrl != null) { try { var uri = new Uri(model.AvatarUrl); // Image requests to enterprise hosts over https always fail currently, // so just display the default avatar. See #1547. if (uri.Scheme != "https" || uri.Host.EndsWith("githubusercontent.com", StringComparison.OrdinalIgnoreCase)) { AvatarUrl = model.AvatarUrl; Avatar = new BitmapImage(uri); } } catch (Exception ex) { log.Error(ex, "Invalid avatar URL"); } } if (AvatarUrl == null) { Avatar = AvatarProvider.CreateBitmapImage(DefaultAvatar); AvatarUrl = DefaultAvatar; } }
public ActorViewModel(ActorModel model) { Login = model?.Login ?? "[unknown]"; Avatar = model?.AvatarUrl != null ? new BitmapImage(new Uri(model.AvatarUrl)) : AvatarProvider.CreateBitmapImage(DefaultAvatar); AvatarUrl = model?.AvatarUrl ?? DefaultAvatar; }
public void DoesNotThrowOnNullUserOrAvatarUrl() { var blobStore = Substitute.For <IBlobCache>(); blobStore.Invalidate(null).Returns(_ => { throw new ArgumentNullException(); }); var sharedCache = Substitute.For <ISharedCache>(); sharedCache.LocalMachine.Returns(blobStore); var avatarProvider = new AvatarProvider(sharedCache, new TestImageCache()); avatarProvider.InvalidateAvatar(null); avatarProvider.InvalidateAvatar(Substitute.For <IAvatarContainer>()); }
public void GetsBytesFromImage() { var image = AvatarProvider.CreateBitmapImage("pack://application:,,,/GitHub.App;component/Images/default_user_avatar.png"); byte[] bytes; var encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(image)); using (var ms = new MemoryStream()) { encoder.Save(ms); bytes = ms.ToArray(); } Assert.NotNull(bytes); Assert.True(bytes.Length > 256); }
public async Task RetrievesGitHubAvatar() { var expectedImage = AvatarProvider.CreateBitmapImage("pack://*****:*****@test.com&s=140"); var blobCache = new InMemoryBlobCache(); var sharedCache = Substitute.For <ISharedCache>(); sharedCache.LocalMachine.Returns(blobCache); var imageCache = new TestImageCache(); await imageCache.SeedImage(avatarUrl, expectedImage, DateTimeOffset.MaxValue); var avatarProvider = new AvatarProvider(sharedCache, imageCache); var avatarContainer = Substitute.For <IAvatarContainer>(); avatarContainer.AvatarUrl.Returns("https://avatars.githubusercontent.com/u/[email protected]&s=140"); var retrieved = await avatarProvider.GetAvatar(avatarContainer); AssertSameImage(expectedImage, retrieved); }
public async Task CanBeAccessedFromMultipleThreads() { var blobCache = new InMemoryBlobCache(); var sharedCache = Substitute.For <ISharedCache>(); sharedCache.LocalMachine.Returns(blobCache); var imageCache = new TestImageCache(); var avatarProvider = new AvatarProvider(sharedCache, imageCache); var expected = avatarProvider.DefaultUserBitmapImage.ToString(); int mainThreadId = Thread.CurrentThread.ManagedThreadId; int otherThreadId = mainThreadId; var actual = await Task.Run(() => { otherThreadId = Thread.CurrentThread.ManagedThreadId; return(avatarProvider.DefaultUserBitmapImage.ToString()); }); Assert.Equal(expected, actual); Assert.NotEqual(mainThreadId, otherThreadId); }
public static IEnumerable <IPullRequestCheckViewModel> Build(IViewViewModelFactory viewViewModelFactory, PullRequestDetailModel pullRequest) { return(pullRequest.Statuses?.Select(model => { PullRequestCheckStatus checkStatus; switch (model.State) { case StatusState.Expected: case StatusState.Error: case StatusState.Failure: checkStatus = PullRequestCheckStatus.Failure; break; case StatusState.Pending: checkStatus = PullRequestCheckStatus.Pending; break; case StatusState.Success: checkStatus = PullRequestCheckStatus.Success; break; default: throw new InvalidOperationException("Unkown PullRequestCheckStatusEnum"); } var pullRequestCheckViewModel = (PullRequestCheckViewModel)viewViewModelFactory.CreateViewModel <IPullRequestCheckViewModel>(); pullRequestCheckViewModel.Title = model.Context; pullRequestCheckViewModel.Description = model.Description; pullRequestCheckViewModel.Status = checkStatus; pullRequestCheckViewModel.DetailsUrl = new Uri(model.TargetUrl); pullRequestCheckViewModel.AvatarUrl = model.AvatarUrl ?? DefaultAvatar; pullRequestCheckViewModel.Avatar = model.AvatarUrl != null ? new BitmapImage(new Uri(model.AvatarUrl)) : AvatarProvider.CreateBitmapImage(DefaultAvatar); return pullRequestCheckViewModel; }) ?? new PullRequestCheckViewModel[0]); }
public void CopyFromDoesNotLoseAvatar() { var userImage = AvatarProvider.CreateBitmapImage("pack://application:,,,/GitHub.App;component/Images/default_user_avatar.png"); var orgImage = AvatarProvider.CreateBitmapImage("pack://application:,,,/GitHub.App;component/Images/default_org_avatar.png"); var initialBitmapImageSubject = new Subject <BitmapImage>(); var collectionEvent = new ManualResetEvent(false); var avatarPropertyEvent = new ManualResetEvent(false); //Creating an initial account with an observable that returns immediately const string login = "******"; const int initialOwnedPrivateRepositoryCount = 1; var initialAccount = new Account(login, true, false, initialOwnedPrivateRepositoryCount, 0, initialBitmapImageSubject); //Creating the test collection var col = new TrackingCollection <IAccount>(Observable.Empty <IAccount>(), OrderedComparer <IAccount> .OrderByDescending(x => x.Login).Compare); col.Subscribe(account => { collectionEvent.Set(); }, () => { }); //Adding that account to the TrackingCollection col.AddItem(initialAccount); //Waiting for the collection add the item collectionEvent.WaitOne(); collectionEvent.Reset(); //Checking some initial properties Assert.That(login, Is.EqualTo(col[0].Login)); Assert.That(initialOwnedPrivateRepositoryCount, Is.EqualTo(col[0].OwnedPrivateRepos)); //Demonstrating that the avatar is not yet present Assert.That(col[0].Avatar, Is.Null); //Adding a listener to check for the changing of the Avatar property initialAccount.Changed.Subscribe(args => { if (args.PropertyName == "Avatar") { avatarPropertyEvent.Set(); } }); //Providing the first avatar initialBitmapImageSubject.OnNext(userImage); initialBitmapImageSubject.OnCompleted(); //Waiting for the avatar to be added avatarPropertyEvent.WaitOne(); avatarPropertyEvent.Reset(); //Demonstrating that the avatar is present Assert.That(col[0].Avatar, Is.Not.Null); Assert.True(BitmapSourcesAreEqual(col[0].Avatar, userImage)); Assert.False(BitmapSourcesAreEqual(col[0].Avatar, orgImage)); //Creating an account update const int updatedOwnedPrivateRepositoryCount = 2; var updatedBitmapImageSubject = new Subject <BitmapImage>(); var updatedAccount = new Account(login, true, false, updatedOwnedPrivateRepositoryCount, 0, updatedBitmapImageSubject); //Updating the account in the collection col.AddItem(updatedAccount); //Waiting for the collection to process the update collectionEvent.WaitOne(); collectionEvent.Reset(); //Providing the second avatar updatedBitmapImageSubject.OnNext(orgImage); updatedBitmapImageSubject.OnCompleted(); //Waiting for the delayed bitmap image observable avatarPropertyEvent.WaitOne(); avatarPropertyEvent.Reset(); //Login is the id, so that should be the same Assert.That(login, Is.EqualTo(col[0].Login)); //CopyFrom() should have updated this field Assert.That(updatedOwnedPrivateRepositoryCount, Is.EqualTo(col[0].OwnedPrivateRepos)); //CopyFrom() should not cause a race condition here Assert.That(col[0].Avatar, Is.Not.Null); Assert.True(BitmapSourcesAreEqual(col[0].Avatar, orgImage)); Assert.False(BitmapSourcesAreEqual(col[0].Avatar, userImage)); }
public async Task TestMethod1() { var uri = await AvatarProvider.GetAvatarUri(); uri.Should().NotBeNullOrEmpty(); }
public ActorViewModelDesigner() { AvatarUrl = "pack://application:,,,/GitHub.App;component/Images/default_user_avatar.png"; Avatar = AvatarProvider.CreateBitmapImage(AvatarUrl); }