<commit_before>﻿using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.Extensions.Caching.Memory;
using Moq;
using Xunit;

namespace Cimpress.Extensions.Http.Caching.InMemory.UnitTests
{
    public class InMemoryCacheFallbackHandler_when_sending_request
    {
        private string url = "http://unittest/";

        [Fact]
        public async Task Always_calls_the_http_handler()
        {
            // setup
            var testMessageHandler = new TestMessageHandler();
            var cache = new MemoryCache(new MemoryCacheOptions());
            var client = new HttpClient(new InMemoryCacheFallbackHandler(testMessageHandler, TimeSpan.FromDays(1), TimeSpan.FromDays(1), null, cache));

            // execute twice
            await client.GetAsync(url);
            cache.Get(HttpMethod.Get + url).Should().NotBeNull(); // ensure it's cached before the 2nd call
            await client.GetAsync(url);

            // validate
            testMessageHandler.NumberOfCalls.Should().Be(2);
        }

        [Fact]
        public async Task Always_updates_the_cache_on_success()
        {
            // setup
            var testMessageHandler = new TestMessageHandler();
            var cache = new Mock<IMemoryCache>(MockBehavior.Strict);
            var cacheTime = TimeSpan.FromSeconds(123);
            cache.Setup(c => c.CreateEntry(url));
            var client = new HttpClient(new InMemoryCacheFallbackHandler(testMessageHandler, TimeSpan.FromDays(1), cacheTime, null, cache.Object));

            // execute twice, validate cache is called each time
            await client.GetAsync(url);
            cache.Verify(c => c.CreateEntry(HttpMethod.Get + url), Times.Once);
            await client.GetAsync(url);
            cache.Verify(c => c.CreateEntry(HttpMethod.Get + url), Times.Exactly(2));
        }

        [Fact]
        public async Task Updates_the_cache_for_head_and_get_independently()
        {
            // setup
            var testMessageHandler = new TestMessageHandler();
            var cache = new Mock<IMemoryCache>(MockBehavior.Strict);
            var cacheTime = TimeSpan.FromSeconds(123);
            cache.Setup(c => c.CreateEntry(url));
            var client = new HttpClient(new InMemoryCacheFallbackHandler(testMessageHandler, TimeSpan.FromDays(1), cacheTime, null, cache.Object));

            // execute twice, validate cache is called each time
            await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, url));
            await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, url));
            cache.Verify(c => c.CreateEntry(HttpMethod.Head + url), Times.Once);
            cache.Verify(c => c.CreateEntry(HttpMethod.Get + url), Times.Once);
        }
        
        [Fact]
        public async Task Never_updates_the_cache_on_failure()
        {
            // setup
            var testMessageHandler = new TestMessageHandler(HttpStatusCode.InternalServerError);
            var cache = new Mock<IMemoryCache>(MockBehavior.Strict);
            var cacheTime = TimeSpan.FromSeconds(123);
            object expectedValue;<commit_msg>Make setup more consistent to not fail with a mock exception (which is silenced by cache errors).<commit_after>﻿using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.Extensions.Caching.Memory;
using Moq;
using Xunit;

namespace Cimpress.Extensions.Http.Caching.InMemory.UnitTests
{
    public class InMemoryCacheFallbackHandler_when_sending_request
    {
        private string url = "http://unittest/";

        [Fact]
        public async Task Always_calls_the_http_handler()
        {
            // setup
            var testMessageHandler = new TestMessageHandler();
            var cache = new MemoryCache(new MemoryCacheOptions());
            var client = new HttpClient(new InMemoryCacheFallbackHandler(testMessageHandler, TimeSpan.FromDays(1), TimeSpan.FromDays(1), null, cache));

            // execute twice
            await client.GetAsync(url);
            cache.Get(HttpMethod.Get + url).Should().NotBeNull(); // ensure it's cached before the 2nd call
            await client.GetAsync(url);

            // validate
            testMessageHandler.NumberOfCalls.Should().Be(2);
        }

        [Fact]
        public async Task Always_updates_the_cache_on_success()
        {
            // setup
            var testMessageHandler = new TestMessageHandler();
            var cache = new Mock<IMemoryCache>(MockBehavior.Strict);
            var cacheTime = TimeSpan.FromSeconds(123);
            cache.Setup(c => c.CreateEntry(HttpMethod.Get + url));
            var client = new HttpClient(new InMemoryCacheFallbackHandler(testMessageHandler, TimeSpan.FromDays(1), cacheTime, null, cache.Object));

            // execute twice, validate cache is called each time
            await client.GetAsync(url);
            cache.Verify(c => c.CreateEntry(HttpMethod.Get + url), Times.Once);
            await client.GetAsync(url);
            cache.Verify(c => c.CreateEntry(HttpMethod.Get + url), Times.Exactly(2));
        }

        [Fact]
        public async Task Updates_the_cache_for_head_and_get_independently()
        {
            // setup
            var testMessageHandler = new TestMessageHandler();
            var cache = new Mock<IMemoryCache>(MockBehavior.Strict);
            var cacheTime = TimeSpan.FromSeconds(123);
            cache.Setup(c => c.CreateEntry(HttpMethod.Get + url));
            cache.Setup(c => c.CreateEntry(HttpMethod.Head + url));
            var client = new HttpClient(new InMemoryCacheFallbackHandler(testMessageHandler, TimeSpan.FromDays(1), cacheTime, null, cache.Object));

            // execute twice, validate cache is called each time
            await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, url));
            await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, url));
            cache.Verify(c => c.CreateEntry(HttpMethod.Head + url), Times.Once);
            cache.Verify(c => c.CreateEntry(HttpMethod.Get + url), Times.Once);
        }
        
        [Fact]
        public async Task Never_updates_the_cache_on_failure()
        {
            // setup
            var testMessageHandler = new TestMessageHandler(HttpStatusCode.InternalServerError);
            var cache = new Mock<IMemoryCache>(MockBehavior.Strict);
            var cacheTime = TimeSpan.FromSeconds(123);
            object expectedValue;
{'fraction_non_alphanumeric': 0.09622411693057248, 'fraction_numerical': 0.0048721071863581, 'mean_word_length': 2.5355220667384284, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6546979', 'n_tokens_mistral': 1744, 'n_tokens_neox': 1729, 'n_words': 390}