예제 #1
0
        public async Task GetNewsFromCollection_ShouldFetchCollectionNews()
        {
            // Arrange
            var feeds = Create.Many(Create.RSSFeed).Cast <Feed>().Take(2).ToArray();

            FeedlerContext.Feeds.AddRange(feeds);

            var collection = Create.Collection(feeds);

            FeedlerContext.Collections.Add(collection);

            await FeedlerContext.SaveChangesAsync();

            var itemsByFeed = new Dictionary <Feed, Item[]>();

            foreach (var feed in feeds)
            {
                itemsByFeed[feed] = Create.Many(Create.Item).Take(3).ToArray();
                FeedLoader.LoadItemsAsync(feed).Returns(itemsByFeed[feed]);
            }

            // Act
            var response = await Client.GetAsync($"collections/{collection.Id}/news");

            // Assert: response
            await HttpAssert.IsSuccessResponseAsync(response);

            var responseJson = await response.Content.ReadAsAsync <JArray>();

            Assert.Equal(
                expected: itemsByFeed.Values.Flatten().Select(i => new { Title = i.Title }).ToHashSet(),
                actual: responseJson.Select(j => new { Title = j.String("title") }).ToHashSet()
                );
        }
예제 #2
0
        // Feed sources are assumed to be added to db directly or via config.
        // This method is used for the latter.
        // Todo: move to db context class
        private async Task SeedConfigFeedsAsync(FeedlerContext context)
        {
            _logger.LogInformation("Seeding feed sources from config.");

            var seedingTime = await Timer.TimeAsync(async() =>
            {
                // Todo: consider optimizing seeding to avoid loading all entities to memory
                var addedFeeds = await context.Feeds.ToDictionaryAsync(f => f.Id);
                foreach (var feed in _config.Seeding.Feeds)
                {
                    var addedFeed = addedFeeds.GetValueOrDefault(feed.Id);
                    if (addedFeed == null)
                    {
                        context.Feeds.Add(feed);

                        _logger.LogInformation($"Added feed \"{feed.Id}\".");
                    }
                    else if (!feed.DeepEquals(addedFeed))
                    {
                        context.Feeds.Remove(addedFeed);
                        context.Feeds.Add(feed);
                        context.Entry(feed).State = EntityState.Modified;

                        _logger.LogInformation($"Updated feed \"{feed.Id}\".");
                    }
                }

                await context.SaveChangesAsync();
            });

            _logger.LogInformation($"Seeded feed sources in {seedingTime}.");
        }
예제 #3
0
        public async Task GetNewsFromCollection_ShouldLoadNewsFromCache_IfRequestIsCached()
        {
            // Arrange
            var feed = Create.RSSFeed();

            FeedlerContext.Feeds.Add(feed);

            var collection = Create.Collection(feed);

            FeedlerContext.Collections.Add(collection);

            await FeedlerContext.SaveChangesAsync();

            var items = Create.Many(Create.Item).Take(5).ToArray();

            FeedLoader.LoadItemsAsync(feed).Returns(items);

            // Act
            var response1 = await Client.GetAsync($"collections/{collection.Id}/news");

            await HttpAssert.IsSuccessResponseAsync(response1);

            FeedLoader.ClearReceivedCalls();

            var response2 = await Client.GetAsync($"collections/{collection.Id}/news");

            await HttpAssert.IsSuccessResponseAsync(response2);

            // Assert: calls
            await FeedLoader.DidNotReceive().LoadItemsAsync(feed);
        }
예제 #4
0
 public CollectionsController(ILogger <CollectionsController> logger,
                              FeedlerContext context, IFeedCache feedCache)
 {
     _logger    = logger;
     _context   = context;
     _feedCache = feedCache;
 }
예제 #5
0
        public async Task DeleteCollection_ShouldRemoveCollection()
        {
            // Arrange
            var collection = Create.Collection();

            FeedlerContext.Collections.Add(collection);
            await FeedlerContext.SaveChangesAsync();

            // Act
            var response = await Client.DeleteAsync($"collections/{collection.Id}");

            // Assert: response
            await HttpAssert.IsSuccessResponseAsync(response);

            // Assert: database
            Assert.Null(await FeedlerContext.Collections.Where(c => c.Id == collection.Id).FirstOrDefaultAsync());
        }
예제 #6
0
        public async Task GetCollections_ShouldReturnAllCollections()
        {
            // Arrange
            var testCollections = Create.Many(Create.Collection).Take(3).ToArray();

            FeedlerContext.Collections.AddRange(testCollections);
            await FeedlerContext.SaveChangesAsync();

            // Act
            var response = await Client.GetAsync("collections");

            var responseJson = await response.Content.ReadAsAsync <JArray>();

            // Assert: response
            await HttpAssert.IsSuccessResponseAsync(response);

            Assert.Equal(
                expected: testCollections.Select(c => c.Id).ToHashSet(),
                actual: responseJson.Select(j => j["id"].ToObject <Guid>()).ToHashSet()
                );
        }
예제 #7
0
        public void Configure(IApplicationBuilder app, FeedlerContext context)
        {
            app.UseMiddleware <ExceptionHandlingMiddleware>(new ExceptionHandlingMiddleware.Options
            {
                ForwardExceptions = _config.ForwardExceptions
            });

            app.UseMvc();

            app.UseSwagger();
            app.UseSwaggerUI(o =>
            {
                o.SwaggerEndpoint("/swagger/v1/swagger.json", "Feedler");
            });

            if (context.Database.IsSqlServer())
            {
                _logger.LogInformation("Applying migrations.");
                var migrationTime = Timer.Time(() => context.Database.Migrate());
                _logger.LogInformation($"Applied migrations in {migrationTime}.");
            }

            SeedConfigFeedsAsync(context).Await();
        }
예제 #8
0
 public FeedsCollectionService(FeedlerContext context)
 {
     _context = context;
 }
예제 #9
0
 public FeedsController(FeedlerContext context)
 {
     _context = context;
 }
예제 #10
0
 public CollectionsController(IMemoryCache memoryCache, FeedlerContext context)
 {
     _memoryCache       = memoryCache;
     _collectionService = new FeedsCollectionService(context);
 }