public HackerNewsClientTests()
 {
     _api        = new HackerNewsMockAPI();
     _localCache = new MemoryCache(Options.Create(new MemoryCacheOptions()));
     _distCache  = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
     _client     = new HackerNewsClient(_api, _localCache, _distCache);
 }
示例#2
0
        public void TestPaginateArticlesAtEnd()
        {
            var storyIDs = Enumerable.Range(100, 500);

            var nextPage = HackerNewsClient.PaginateArticles(storyIDs, 590);

            Assert.Equal(9, nextPage.Count());
            Assert.Equal(591, nextPage.First());
            Assert.Equal(599, nextPage.Last());
        }
示例#3
0
        public void TestPaginateArticlesFromStart()
        {
            var storyIDs = Enumerable.Range(100, 500);

            var nextPage = HackerNewsClient.PaginateArticles(storyIDs, null);

            Assert.Equal(20, nextPage.Count());
            Assert.Equal(100, nextPage.First());
            Assert.Equal(119, nextPage.Last());
        }
示例#4
0
        public async Task ClientTest([ValueSource("_files")] string file)
        {
            var response = ReadFile(file);
            var client   = new HackerNewsClient(GetFakeHttpClientFactory(response));

            using (ApprovalResults.ForScenario(file))
            {
                var output = await client.GetFrontpage();

                Approvals.Verify(output.Json);
            }
        }
示例#5
0
        public void GetMostRecentArticlesTest()
        {
            var conn    = new WebApiConnection("https://hacker-news.firebaseio.com/v0/");
            var client  = new HackerNewsClient(conn);
            var request = new GetMostRecentArticlesRequest
            {
                ArticleCount = 20
            };

            var response = client.GetMostRecentArticles(request);

            response.Articles.Count.ShouldBe(20);
        }
示例#6
0
        public void GetSearchedArticlesTest()
        {
            var conn    = new WebApiConnection("https://hacker-news.firebaseio.com/v0/");
            var client  = new HackerNewsClient(conn);
            var request = new GetSearchedArticlesRequest
            {
                ArticleCount = 500,
                SearchTerm   = "the" // we are assuming at least one article will include the word "the", which may not always be the case
            };

            var response = client.GetSearchedArticles(request);

            response.Articles.Where(x => x.Headline.Contains(request.SearchTerm)).Count().ShouldBe(response.Articles.Count());
        }
示例#7
0
        public void GetTopHackerNewsTest()
        {
            string url = "https://hacker-news.firebaseio.com/";

            string pathTop = "v0/beststories.json";

            string pathDetails = "v0/item/{0}.json";

            int order = 20;

            var result = new HackerNewsClient(url, pathTop, pathDetails, order).GetTopHackerNews();

            Assert.IsInstanceOfType(result, typeof(IList <HackerNewsModel>));
            Assert.IsTrue(result.Count == order);
        }
示例#8
0
        public async Task <IEnumerable <HackerNewsStory> > Get()
        {
            const string cacheKey = "HackerNewsResult";

            _logger.LogInformation("HackerNews-Get: Called");

            // Get Cache slide and absolute expire values from settings file, if not exists use hardcoded default values
            int slideExpireSecs = _config.GetValue <int?>("Cache:SlidingExpiration") ?? 30;
            int absExpireSecs   = _config.GetValue <int?>("Cache:AbsoluteExpiration") ?? 300;

            IEnumerable <HackerNewsStory> result;

            try
            {
                // Check if item is already in MemCache,
                // if it is then return the cached version, if not call the hackernews webservice and place it on cache
                if (!_cache.TryGetValue(cacheKey, out result))
                {
                    _logger.LogDebug("HackerNews-Get: Getting from external webservice");

                    // Call base API
                    result = await HackerNewsClient.GetHackerNewsStories(20);

                    // Add returned item to cache using the already defined expiration values
                    _cache.Set(cacheKey,
                               result,
                               new MemoryCacheEntryOptions()
                    {
                        SlidingExpiration  = TimeSpan.FromSeconds(slideExpireSecs),
                        AbsoluteExpiration = DateTimeOffset.UtcNow.AddSeconds(absExpireSecs)
                    });
                }
                else
                {
                    _logger.LogDebug("HackerNews-Get: Getting from cache");
                }

                _logger.LogInformation("HackerNews-Get: Returning json item");
                return(result.OrderByDescending(x => x.score));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "An error occurd while calling the HackerNews API.");
                throw;
            }
        }
示例#9
0
        /// <summary>
        /// Returns the hacker news on the website.
        /// </summary>
        /// <param name="filterField">.</param>
        /// <param name="filterOperation">.</param>
        /// <param name="orderByField">.</param>
        /// <param name="orderByFieldDesc">.</param>
        /// <param name="maxResultCount">.</param>
        /// <returns>.</returns>
        public async Task <IList <HackerNewsItem> > GetHackerNewsHtmlSanitizer(HackerNewsFieldEnum filterField, HackerNewsFilterOperationEnum filterOperation, HackerNewsFieldEnum orderByField, bool orderByFieldDesc, int maxResultCount)
        {
            IList <HackerNewsItem> hackerNewsItemList;

            // Initialize http client
            using (HackerNewsClient hackerNewsClient = new HackerNewsClient())
            {
                // Get response from web site
                string hackerNewsHtmlContent = await hackerNewsClient.GetNewsAsString();

                HtmlDocumentSanitizer dataManualScraping = new HtmlDocumentSanitizer();
                hackerNewsItemList = dataManualScraping.ScrapeHackerNewsHtmlContent(hackerNewsHtmlContent, maxResultCount);
            }

            hackerNewsItemList = FilterHackerNews(hackerNewsItemList, filterField, filterOperation, orderByField, orderByFieldDesc);

            return(hackerNewsItemList);
        }
示例#10
0
        public void GetTopHackerNewsWithErrorPathDetailsTest()
        {
            try
            {
                string url = "https://hacker-news.firebaseio.com/";

                string pathTop = "v0/beststories.json";

                string pathDetails = string.Empty;

                int order = 20;

                var result = new HackerNewsClient(url, pathTop, pathDetails, order).GetTopHackerNews();

                Assert.IsTrue(false);
            }
            catch (System.Exception ec)
            {
                Assert.IsInstanceOfType(ec, typeof(System.Exception));
            }
        }
示例#11
0
        public void GetTopHackerNewsWithErrorUrlTest()
        {
            try
            {
                string url = string.Empty;

                string pathTop = "v0/beststories.json";

                string pathDetails = "v0/item/{0}.json";

                int order = 20;

                var result = new HackerNewsClient(url, pathTop, pathDetails, order).GetTopHackerNews();

                Assert.IsTrue(false);
            }
            catch (System.Exception ec)
            {
                Assert.IsInstanceOfType(ec, typeof(System.Exception));
            }
        }
示例#12
0
        /// <summary>
        /// Returns the hacker news on the website.
        /// </summary>
        /// <param name="filterField">.</param>
        /// <param name="filterOperation">.</param>
        /// <param name="orderByField">.</param>
        /// <param name="orderByFieldDesc">.</param>
        /// <param name="maxResultCount">.</param>
        /// <returns>.</returns>
        public async Task <IList <HackerNewsItem> > GetHackerNewsManualCleaner(HackerNewsFieldEnum filterField, HackerNewsFilterOperationEnum filterOperation, HackerNewsFieldEnum orderByField, bool orderByFieldDesc, int maxResultCount)
        {
            IList <HackerNewsItem> hackerNewsItemList;

            // Initialize http client
            using (HackerNewsClient hackerNewsClient = new HackerNewsClient())
            {
                // Get response from web site
                using (Stream hackerNewsHtmlContent = await hackerNewsClient.GetNewsAsStream())
                {
                    ManualHtmlTableParser dataManualScraping = new ManualHtmlTableParser();
                    hackerNewsItemList = await dataManualScraping.ScrapeHackerNewsHtmlContent(hackerNewsHtmlContent, maxResultCount);
                }
            }

            LambdaExpressionBuilder <HackerNewsItem> expressionBuilder = new LambdaExpressionBuilder <HackerNewsItem>();

            Expression <Func <HackerNewsItem, bool> >   filteringQuery = GetHackerNewsItemExpressionFilter(expressionBuilder, filterField, filterOperation);
            Expression <Func <HackerNewsItem, object> > sortingQuery   = GetHackerNewsItemExpressionSort(expressionBuilder, orderByField, orderByFieldDesc);

            // DEBUG: To check the final value
            if (filteringQuery != null)
            {
                hackerNewsItemList = hackerNewsItemList.Where(filteringQuery.Compile()).ToList();
            }

            if (sortingQuery != null)
            {
                if (orderByFieldDesc)
                {
                    hackerNewsItemList = hackerNewsItemList.OrderByDescending(sortingQuery.Compile()).ToList();
                }
                else
                {
                    hackerNewsItemList = hackerNewsItemList.OrderBy(sortingQuery.Compile()).ToList();
                }
            }

            return(hackerNewsItemList);
        }
示例#13
0
        public HackerNewsCommand(string name, HackerNewsClient client) : base(name)
        {
            Description = "Description of TwitterCommand";

            AddOption(new Option(
                          new[] { "--json" },
                          "Return as Json")
            {
                Argument = new Argument <bool>() // defaultValue: () => 99
                {
                    //Arity = ArgumentArity.ExactlyOne
                },
                Description = "Argument description"
            });

            Handler = CommandHandler.Create <bool, bool>(async(json, debug) =>
            {
                var output = await client.GetFrontpage(debug);
                var text   = json ? output.Json : output.String;
                ConsoleHelper.WriteLine(text);
                Environment.ExitCode = (int)ExitCode.Success;
            });
        }