Beispiel #1
0
        public async Task InitializeAsyncLoadsValuesIntoCache()
        {
            var testCache = new InMemoryBlobCache();
            await testCache.InsertObject("Storage:DummyNumber", 16);
            await testCache.InsertObject("Storage:DummyText", "Random");

            var cache = Substitute.For<IBlobCache>();
            cache.Get(Arg.Any<string>()).Returns(x => testCache.Get(x.Arg<string>()));
            var settings = new DummySettingsStorage("Storage", cache);

            await settings.InitializeAsync();

            int number = settings.DummyNumber;
            string text = settings.DummyText;

            Assert.Equal(16, number);
            Assert.Equal("Random", text);
            cache.ReceivedWithAnyArgs(2).Get(Arg.Any<string>());
        }
Beispiel #2
0
        public async Task RetrievesCurrentUserAsync()
        {
            var cache = new InMemoryBlobCache();
            await cache.InsertObject <AccountCacheItem>("user", new AccountCacheItem(CreateOctokitUser("octocat")));

            var modelService = CreateTarget(hostCache: cache);

            var user = await modelService.GetCurrentUser();

            Assert.That("octocat", Is.EqualTo(user.Login));
        }
            public async Task NullSearchTermDefaultsToEmptyString()
            {
                var songs = new[] { new SoundCloudSong { IsStreamable = true, StreamUrl = new Uri("http://blabla.com"), PermaLinkUrl = new Uri("http://blabla") } };
                var cache = new InMemoryBlobCache();
                cache.InsertObject(BlobCacheKeys.GetKeyForSoundCloudCache(string.Empty), songs);
                var finder = new SoundCloudSongFinder(cache);

                var result = await finder.GetSongsAsync();

                Assert.Equal(1, result.Count);
            }
            public async Task NullSearchTermDefaultsToEmptyString()
            {
                var songs = new[] { new YoutubeSong("http://blabla", TimeSpan.Zero) };
                var cache = new InMemoryBlobCache();
                cache.InsertObject(BlobCacheKeys.GetKeyForYoutubeCache(string.Empty), songs);
                var finder = new YoutubeSongFinder(cache);

                var result = await finder.GetSongsAsync();

                Assert.Equal(1, result.Count);
            }
        public async Task RetrievesUserFromCache()
        {
            var apiClient = Substitute.For<IApiClient>();
            var cache = new InMemoryBlobCache();
            await cache.InsertObject<AccountCacheItem>("user", new AccountCacheItem(CreateOctokitUser("octocat")));
            var modelService = new ModelService(apiClient, cache, Substitute.For<IAvatarProvider>());

            var user = await modelService.GetUserFromCache();

            Assert.Equal("octocat", user.Login);
        }
Beispiel #6
0
        public async Task RetrievesUserFromCache()
        {
            var apiClient = Substitute.For <IApiClient>();
            var cache     = new InMemoryBlobCache();
            await cache.InsertObject <AccountCacheItem>("user", new AccountCacheItem(CreateOctokitUser("octocat")));

            var modelService = new ModelService(apiClient, cache, Substitute.For <IAvatarProvider>());

            var user = await modelService.GetUserFromCache();

            Assert.Equal("octocat", user.Login);
        }
Beispiel #7
0
            public async Task NullSearchTermDefaultsToEmptyString()
            {
                var songs = new[] { new YoutubeSong("http://blabla", TimeSpan.Zero) };
                var cache = new InMemoryBlobCache();

                cache.InsertObject(BlobCacheKeys.GetKeyForYoutubeCache(string.Empty), songs);
                var finder = new YoutubeSongFinder(cache);

                var result = await finder.GetSongsAsync();

                Assert.Equal(1, result.Count);
            }
            public async Task UsesCachedSongsIfAvailable()
            {
                const string searchTerm = "Foo";
                var songs = new[] { new YoutubeSong("http://blabla", TimeSpan.Zero) };
                var cache = new InMemoryBlobCache();
                cache.InsertObject(BlobCacheKeys.GetKeyForYoutubeCache(searchTerm), songs);
                var finder = new YoutubeSongFinder(cache);

                var result = await finder.GetSongsAsync(searchTerm);

                Assert.Equal(1, result.Count);
            }
            public async Task UsesCachedSongsIfAvailable()
            {
                const string searchTerm = "Foo";
                var songs = new[] { new SoundCloudSong { IsStreamable = true, StreamUrl = new Uri("http://blabla.com"), PermaLinkUrl = new Uri("http://blabla") } };
                var cache = new InMemoryBlobCache();
                cache.InsertObject(BlobCacheKeys.GetKeyForSoundCloudCache(searchTerm), songs);
                var finder = new SoundCloudSongFinder(cache);

                var result = await finder.GetSongsAsync(searchTerm);

                Assert.Equal(1, result.Count);
            }
Beispiel #10
0
            public async Task UsesCachedSongsIfAvailable()
            {
                const string searchTerm = "Foo";
                var          songs      = new[] { new YoutubeSong("http://blabla", TimeSpan.Zero) };
                var          cache      = new InMemoryBlobCache();

                cache.InsertObject(BlobCacheKeys.GetKeyForYoutubeCache(searchTerm), songs);
                var finder = new YoutubeSongFinder(cache);

                var result = await finder.GetSongsAsync(searchTerm);

                Assert.Equal(1, result.Count);
            }
Beispiel #11
0
            public async Task NullSearchTermDefaultsToEmptyString()
            {
                var songs = new[] { new SoundCloudSong {
                                        IsStreamable = true, StreamUrl = new Uri("http://blabla.com"), PermaLinkUrl = new Uri("http://blabla")
                                    } };
                var cache = new InMemoryBlobCache();

                cache.InsertObject(BlobCacheKeys.GetKeyForSoundCloudCache(string.Empty), songs);
                var finder = new SoundCloudSongFinder(cache);

                var result = await finder.GetSongsAsync();

                Assert.Equal(1, result.Count);
            }
Beispiel #12
0
        public async Task InitializeAsyncLoadsValuesIntoCache()
        {
            var testCache = new InMemoryBlobCache();
            await testCache.InsertObject("Storage:DummyNumber", 16);

            await testCache.InsertObject("Storage:DummyText", "Random");

            var cache = Substitute.For <IBlobCache>();

            cache.Get(Arg.Any <string>()).Returns(x => testCache.Get(x.Arg <string>()));
            var settings = new DummySettingsStorage("Storage", cache);

            await settings.InitializeAsync();

            int    number = settings.DummyNumber;
            string text   = settings.DummyText;

            Assert.Equal(16, number);
            Assert.Equal("Random", text);
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            cache.ReceivedWithAnyArgs(2).Get(Arg.Any <string>());
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
        }
Beispiel #13
0
            public async Task UsesCachedSongsIfAvailable()
            {
                const string searchTerm = "Foo";
                var          songs      = new[] { new SoundCloudSong {
                                                      IsStreamable = true, StreamUrl = new Uri("http://blabla.com"), PermaLinkUrl = new Uri("http://blabla")
                                                  } };
                var cache = new InMemoryBlobCache();

                cache.InsertObject(BlobCacheKeys.GetKeyForSoundCloudCache(searchTerm), songs);
                var finder = new SoundCloudSongFinder(cache);

                var result = await finder.GetSongsAsync(searchTerm);

                Assert.Equal(1, result.Count);
            }
            public async Task PullsSearchesFromCache()
            {
                string artist = "A";
                string album = "B";
                string key = BlobCacheKeys.GetKeyForOnlineArtwork(artist, album);
                var fetcher = Substitute.For<IArtworkFetcher>();
                var blobCache = new InMemoryBlobCache();
                await blobCache.InsertObject(key, "TestArtworkKey");
                var fixture = new ArtworkCache(blobCache, fetcher);

                string returned = await fixture.FetchOnline(artist, album);

                Assert.Equal("TestArtworkKey", returned);
                fetcher.DidNotReceiveWithAnyArgs().RetrieveAsync(null, null);
            }
Beispiel #15
0
            public async Task PullsSearchesFromCache()
            {
                string artist    = "A";
                string album     = "B";
                string key       = BlobCacheKeys.GetKeyForOnlineArtwork(artist, album);
                var    fetcher   = Substitute.For <IArtworkFetcher>();
                var    blobCache = new InMemoryBlobCache();
                await blobCache.InsertObject(key, "TestArtworkKey");

                var fixture = new ArtworkCache(blobCache, fetcher);

                string returned = await fixture.FetchOnline(artist, album);

                Assert.Equal("TestArtworkKey", returned);
                fetcher.DidNotReceiveWithAnyArgs().RetrieveAsync(null, null);
            }
Beispiel #16
0
        public async Task ExpiredIndexClearsItems()
        {
            var expected = 5;

            var username = "******";
            var reponame = "repo";

            var cache        = new InMemoryBlobCache();
            var apiClient    = Substitute.For <IApiClient>();
            var modelService = new ModelService(apiClient, cache, Substitute.For <IAvatarProvider>());
            var user         = CreateOctokitUser(username);

            apiClient.GetUser().Returns(Observable.Return(new UserAndScopes(user, null)));
            apiClient.GetOrganizations().Returns(Observable.Empty <Organization>());
            var act = modelService.GetAccounts().ToEnumerable().First().First();

            var repo = Substitute.For <ISimpleRepositoryModel>();

            repo.Name.Returns(reponame);
            repo.CloneUrl.Returns(new UriString("https://github.com/" + username + "/" + reponame));

            var indexKey = string.Format(CultureInfo.InvariantCulture, "{0}|{1}|pr", user.Login, repo.Name);

            var prcache = Enumerable.Range(1, expected)
                          .Select(id => CreatePullRequest(user, id, ItemState.Open, "Cache " + id, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow, 0));

            // seed the cache
            prcache
            .Select(item => new ModelService.PullRequestCacheItem(item))
            .Select(item => item.Save <ModelService.PullRequestCacheItem>(cache, indexKey).ToEnumerable().First())
            .SelectMany(item => CacheIndex.AddAndSaveToIndex(cache, indexKey, item).ToEnumerable())
            .ToList();

            // expire the index
            var indexobj = await cache.GetObject <CacheIndex>(indexKey);

            indexobj.UpdatedAt = DateTimeOffset.UtcNow - TimeSpan.FromMinutes(6);
            await cache.InsertObject(indexKey, indexobj);

            var prlive = Observable.Range(5, expected)
                         .Select(id => CreatePullRequest(user, id, ItemState.Open, "Live " + id, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow, 0))
                         .DelaySubscription(TimeSpan.FromMilliseconds(10));

            apiClient.GetPullRequestsForRepository(user.Login, repo.Name).Returns(prlive);

            await modelService.InsertUser(new AccountCacheItem(user));

            var col = modelService.GetPullRequests(repo);

            col.ProcessingDelay = TimeSpan.Zero;

            var count = 0;
            var evt   = new ManualResetEvent(false);

            col.Subscribe(t =>
            {
                // we get all the items from the cache (items 1-5), all the items from the live (items 5-9),
                // and 4 deletions (items 1-4) because the cache expired the items that were not
                // a part of the live data
                if (++count == 14)
                {
                    evt.Set();
                }
            }, () => { });


            evt.WaitOne();
            evt.Reset();

            Assert.Equal(5, col.Count);
            Assert.Collection(col,
                              t => { Assert.True(t.Title.StartsWith("Live")); Assert.Equal(5, t.Number); },
                              t => { Assert.True(t.Title.StartsWith("Live")); Assert.Equal(6, t.Number); },
                              t => { Assert.True(t.Title.StartsWith("Live")); Assert.Equal(7, t.Number); },
                              t => { Assert.True(t.Title.StartsWith("Live")); Assert.Equal(8, t.Number); },
                              t => { Assert.True(t.Title.StartsWith("Live")); Assert.Equal(9, t.Number); }
                              );
        }
        public async Task ExpiredIndexReturnsLive()
        {
            var expected = 5;

            var username = "******";
            var reponame = "repo";

            var cache        = new InMemoryBlobCache();
            var apiClient    = Substitute.For <IApiClient>();
            var modelService = new ModelService(apiClient, cache, Substitute.For <IAvatarProvider>());
            var user         = CreateOctokitUser(username);

            apiClient.GetUser().Returns(Observable.Return(new UserAndScopes(user, null)));
            apiClient.GetOrganizations().Returns(Observable.Empty <Organization>());
            var act = modelService.GetAccounts().ToEnumerable().First().First();

            var repo = Substitute.For <ILocalRepositoryModel>();

            repo.Name.Returns(reponame);
            repo.CloneUrl.Returns(new UriString("https://github.com/" + username + "/" + reponame));

            var indexKey = string.Format(CultureInfo.InvariantCulture, "{0}|{1}:{2}", CacheIndex.PRPrefix, user.Login, repo.Name);

            var prcache = Enumerable.Range(1, expected)
                          .Select(id => CreatePullRequest(user, id, ItemState.Open, "Cache " + id, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow));

            // seed the cache
            prcache
            .Select(item => new ModelService.PullRequestCacheItem(item))
            .Select(item => item.Save <ModelService.PullRequestCacheItem>(cache, indexKey).ToEnumerable().First())
            .SelectMany(item => CacheIndex.AddAndSaveToIndex(cache, indexKey, item).ToEnumerable())
            .ToList();

            // expire the index
            var indexobj = await cache.GetObject <CacheIndex>(indexKey);

            indexobj.UpdatedAt = DateTimeOffset.UtcNow - TimeSpan.FromMinutes(6);
            await cache.InsertObject(indexKey, indexobj);

            var prlive = Observable.Range(1, expected)
                         .Select(id => CreatePullRequest(user, id, ItemState.Open, "Live " + id, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow))
                         .DelaySubscription(TimeSpan.FromMilliseconds(10));

            apiClient.GetPullRequestsForRepository(user.Login, repo.Name).Returns(prlive);

            await modelService.InsertUser(new AccountCacheItem(user));

            ITrackingCollection <IPullRequestModel> col = new TrackingCollection <IPullRequestModel>();

            modelService.GetPullRequests(repo, col);
            col.ProcessingDelay = TimeSpan.Zero;

            var count = 0;
            var done  = new ReplaySubject <Unit>();

            done.OnNext(Unit.Default);
            done.Subscribe();

            col.Subscribe(t =>
            {
                if (++count == expected * 2)
                {
                    done.OnCompleted();
                }
            }, () => { });

            await done;

            Assert.Collection(col, col.Select(x => new Action <IPullRequestModel>(t => Assert.True(x.Title.StartsWith("Live")))).ToArray());
        }
Beispiel #18
0
        public async Task ExpiredIndexClearsItemsAsync()
        {
            var expected = 5;

            var username = "******";
            var reponame = "repo";

            var cache        = new InMemoryBlobCache();
            var apiClient    = Substitute.For <IApiClient>();
            var modelService = CreateTarget(apiClient: apiClient, hostCache: cache);
            var user         = CreateOctokitUser(username);

            apiClient.GetUser().Returns(Observable.Return(user));
            apiClient.GetOrganizations().Returns(Observable.Empty <Organization>());
            var act = modelService.GetAccounts().ToEnumerable().First().First();

            var repo = Substitute.For <LocalRepositoryModel>();

            repo.Name.Returns(reponame);
            repo.Owner.Returns(user.Login);
            repo.CloneUrl.Returns(new UriString("https://github.com/" + username + "/" + reponame));

            var indexKey = string.Format(CultureInfo.InvariantCulture, "{0}|{1}:{2}", CacheIndex.PRPrefix, user.Login, repo.Name);

            var prcache = Enumerable.Range(1, expected)
                          .Select(id => CreatePullRequest(user, id, ItemState.Open, "Cache " + id, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow));

            // seed the cache
            prcache
            .Select(item => new ModelService.PullRequestCacheItem(item))
            .Select(item => item.Save <ModelService.PullRequestCacheItem>(cache, indexKey).ToEnumerable().First())
            .SelectMany(item => CacheIndex.AddAndSaveToIndex(cache, indexKey, item).ToEnumerable())
            .ToList();

            // expire the index
            var indexobj = await cache.GetObject <CacheIndex>(indexKey);

            indexobj.UpdatedAt = DateTimeOffset.UtcNow - TimeSpan.FromMinutes(6);
            await cache.InsertObject(indexKey, indexobj);

            var prlive = Observable.Range(5, expected)
                         .Select(id => CreatePullRequest(user, id, ItemState.Open, "Live " + id, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow, 0))
                         .DelaySubscription(TimeSpan.FromMilliseconds(10));

            apiClient.GetPullRequestsForRepository(user.Login, repo.Name).Returns(prlive);

            await modelService.InsertUser(new AccountCacheItem(user));

            ITrackingCollection <IPullRequestModel> col = new TrackingCollection <IPullRequestModel>();

            modelService.GetPullRequests(repo, col);
            col.ProcessingDelay = TimeSpan.Zero;

            var count = 0;
            var done  = new ReplaySubject <Unit>();

            done.OnNext(Unit.Default);
            done.Subscribe();

            col.Subscribe(t =>
            {
                // we get all the items from the cache (items 1-5), all the items from the live (items 5-9),
                // and 4 deletions (items 1-4) because the cache expired the items that were not
                // a part of the live data
                if (++count == 14)
                {
                    done.OnCompleted();
                }
            }, () => { });

            await done;

            Assert.That(5, Is.EqualTo(col.Count));

            /**Assert.Collection(col,
             *  t => { Assert.StartsWith("Live", t.Title); Assert.Equal(5, t.Number); },
             *  t => { Assert.StartsWith("Live", t.Title); Assert.Equal(6, t.Number); },
             *  t => { Assert.StartsWith("Live", t.Title); Assert.Equal(7, t.Number); },
             *  t => { Assert.StartsWith("Live", t.Title); Assert.Equal(8, t.Number); },
             *  t => { Assert.StartsWith("Live", t.Title); Assert.Equal(9, t.Number); }
             * );*/
        }
        public async Task ExpiredIndexClearsItems()
        {
            var expected = 5;

            var username = "******";
            var reponame = "repo";

            var cache = new InMemoryBlobCache();
            var apiClient = Substitute.For<IApiClient>();
            var modelService = new ModelService(apiClient, cache, Substitute.For<IAvatarProvider>());
            var user = CreateOctokitUser(username);
            apiClient.GetUser().Returns(Observable.Return(user));
            apiClient.GetOrganizations().Returns(Observable.Empty<Organization>());
            var act = modelService.GetAccounts().ToEnumerable().First().First();

            var repo = Substitute.For<ISimpleRepositoryModel>();
            repo.Name.Returns(reponame);
            repo.CloneUrl.Returns(new UriString("https://github.com/" + username + "/" + reponame));

            var indexKey = string.Format(CultureInfo.InvariantCulture, "{0}|{1}|pr", user.Login, repo.Name);

            var prcache = Enumerable.Range(1, expected)
                .Select(id => CreatePullRequest(user, id, ItemState.Open, "Cache " + id, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow, 0));

            // seed the cache
            prcache
                .Select(item => new ModelService.PullRequestCacheItem(item))
                .Select(item => item.Save<ModelService.PullRequestCacheItem>(cache, indexKey).ToEnumerable().First())
                .SelectMany(item => CacheIndex.AddAndSaveToIndex(cache, indexKey, item).ToEnumerable())
                .ToList();

            // expire the index
            var indexobj = await cache.GetObject<CacheIndex>(indexKey);
            indexobj.UpdatedAt = DateTimeOffset.UtcNow - TimeSpan.FromMinutes(6);
            await cache.InsertObject(indexKey, indexobj);

            var prlive = Observable.Range(5, expected)
                .Select(id => CreatePullRequest(user, id, ItemState.Open, "Live " + id, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow, 0))
                .DelaySubscription(TimeSpan.FromMilliseconds(10));

            apiClient.GetPullRequestsForRepository(user.Login, repo.Name).Returns(prlive);

            await modelService.InsertUser(new AccountCacheItem(user));
            var col = modelService.GetPullRequests(repo);
            col.ProcessingDelay = TimeSpan.Zero;

            var count = 0;
            var evt = new ManualResetEvent(false);
            col.Subscribe(t =>
            {
                // we get all the items from the cache (items 1-5), all the items from the live (items 5-9),
                // and 4 deletions (items 1-4) because the cache expired the items that were not
                // a part of the live data
                if (++count == 14)
                    evt.Set();
            }, () => { });


            evt.WaitOne();
            evt.Reset();

            Assert.Equal(5, col.Count);
            Assert.Collection(col, 
                t => { Assert.True(t.Title.StartsWith("Live")); Assert.Equal(5, t.Number); },
                t => { Assert.True(t.Title.StartsWith("Live")); Assert.Equal(6, t.Number); },
                t => { Assert.True(t.Title.StartsWith("Live")); Assert.Equal(7, t.Number); },
                t => { Assert.True(t.Title.StartsWith("Live")); Assert.Equal(8, t.Number); },
                t => { Assert.True(t.Title.StartsWith("Live")); Assert.Equal(9, t.Number); }
            );
        }
        public async Task ExpiredIndexReturnsLive()
        {
            var expected = 5;

            var username = "******";
            var reponame = "repo";

            var cache = new InMemoryBlobCache();
            var apiClient = Substitute.For<IApiClient>();
            var modelService = new ModelService(apiClient, cache, Substitute.For<IAvatarProvider>());
            var user = CreateOctokitUser(username);
            apiClient.GetUser().Returns(Observable.Return(new UserAndScopes(user, null)));
            apiClient.GetOrganizations().Returns(Observable.Empty<Organization>());
            var act = modelService.GetAccounts().ToEnumerable().First().First();

            var repo = Substitute.For<ILocalRepositoryModel>();
            repo.Name.Returns(reponame);
            repo.CloneUrl.Returns(new UriString("https://github.com/" + username + "/" + reponame));

            var indexKey = string.Format(CultureInfo.InvariantCulture, "{0}|{1}:{2}", CacheIndex.PRPrefix, user.Login, repo.Name);

            var prcache = Enumerable.Range(1, expected)
                .Select(id => CreatePullRequest(user, id, ItemState.Open, "Cache " + id, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow));

            // seed the cache
            prcache
                .Select(item => new ModelService.PullRequestCacheItem(item))
                .Select(item => item.Save<ModelService.PullRequestCacheItem>(cache, indexKey).ToEnumerable().First())
                .SelectMany(item => CacheIndex.AddAndSaveToIndex(cache, indexKey, item).ToEnumerable())
                .ToList();

            // expire the index
            var indexobj = await cache.GetObject<CacheIndex>(indexKey);
            indexobj.UpdatedAt = DateTimeOffset.UtcNow - TimeSpan.FromMinutes(6);
            await cache.InsertObject(indexKey, indexobj);

            var prlive = Observable.Range(1, expected)
                .Select(id => CreatePullRequest(user, id, ItemState.Open, "Live " + id, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow))
                .DelaySubscription(TimeSpan.FromMilliseconds(10));

            apiClient.GetPullRequestsForRepository(user.Login, repo.Name).Returns(prlive);

            await modelService.InsertUser(new AccountCacheItem(user));

            ITrackingCollection<IPullRequestModel> col = new TrackingCollection<IPullRequestModel>();
            modelService.GetPullRequests(repo, col);
            col.ProcessingDelay = TimeSpan.Zero;

            var count = 0;
            var done = new ReplaySubject<Unit>();
            done.OnNext(Unit.Default);
            done.Subscribe();

            col.Subscribe(t =>
            {
                if (++count == expected * 2)
                {
                    done.OnCompleted();
                }
            }, () => { });

            await done;

            Assert.Collection(col, col.Select(x => new Action<IPullRequestModel>(t => Assert.True(x.Title.StartsWith("Live")))).ToArray());
        }