public async Task Can_Get_Line_Information_If_Response_Can_Be_Cached()
        {
            // Arrange
            var builder = CreateBuilder()
                          .ForPath("Line/Mode/dlr,overground,tflrail,tube")
                          .WithResponseHeader("Cache-Control", "max-age=3600")
                          .WithJsonContent(new[] { new { id = "waterloo-city", name = "Waterloo & City" } });

            _interceptor.Register(builder);

            ICollection <LineInfo> actual1;
            ICollection <LineInfo> actual2;

            using (var httpClient = _interceptor.CreateHttpClient())
            {
                using (var target = new TflService(httpClient, _cache, _options))
                {
                    // Act
                    actual1 = await target.GetLinesAsync();

                    actual2 = await target.GetLinesAsync();
                }
            }

            // Assert
            Assert.NotNull(actual1);
            Assert.Equal(1, actual1.Count);

            var item = actual1.First();

            Assert.Equal("waterloo-city", item.Id);
            Assert.Equal("Waterloo & City", item.Name);

            Assert.Same(actual1, actual2);
        }
    public InterceptionBenchmarks()
    {
        _options = new HttpClientInterceptorOptions().ThrowsOnMissingRegistration();

        var builder = new HttpRequestInterceptionBuilder();

        builder
        .Requests()
        .ForHttp()
        .ForHost("www.google.co.uk")
        .ForPath("search")
        .ForQuery("q=Just+Eat")
        .Responds()
        .WithMediaType("text/html")
        .WithContent(@"<!DOCTYPE html><html dir=""ltr"" lang=""en""><head><title>Just Eat</title></head></html>")
        .RegisterWith(_options);

        builder
        .Requests()
        .ForHttps()
        .ForHost("files.domain.com")
        .ForPath("setup.exe")
        .ForQuery(string.Empty)
        .Responds()
        .WithMediaType("application/octet-stream")
        .WithContent(() => new byte[] { 0, 1, 2, 3, 4 })
        .RegisterWith(_options);

        builder
        .Requests()
        .ForHttps()
        .ForHost("api.github.com")
        .ForPath("orgs/justeat")
        .ForQuery(string.Empty)
        .Responds()
        .WithMediaType("application/json")
        .WithJsonContent(new { id = 1516790, login = "******", url = "https://api.github.com/orgs/justeat" })
        .RegisterWith(_options);

        builder
        .Requests()
        .ForQuery("page=1")
        .Responds()
        .WithContentStream(() => File.OpenRead("organization.json"))
        .RegisterWith(_options);

        var refitSettings = new RefitSettings()
        {
            ContentSerializer = new SystemTextJsonContentSerializer(),
        };

#pragma warning disable CA2000
        _client = _options.CreateHttpClient();
        _serviceNewtonsoftJson = RestService.For <IGitHub>(_options.CreateHttpClient("https://api.github.com"));
        _serviceSystemTextJson = RestService.For <IGitHub>(_options.CreateHttpClient("https://api.github.com"), refitSettings);
#pragma warning restore CA2000
    }
    public static async Task Register_For_Array_Registers_Interceptions()
    {
        // Arrange
        var builder1 = new HttpRequestInterceptionBuilder()
                       .ForGet()
                       .ForUrl("https://google.com/")
                       .WithContent("foo");

        var builder2 = new HttpRequestInterceptionBuilder()
                       .ForGet()
                       .ForUrl("https://bing.com/")
                       .WithContent("bar");

        var options = new HttpClientInterceptorOptions()
                      .Register(builder1, builder2);

        string actual1;
        string actual2;

        // Act
        using (var httpClient = options.CreateHttpClient())
        {
            actual1 = await httpClient.GetStringAsync("https://google.com/");

            actual2 = await httpClient.GetStringAsync("https://bing.com/");
        }

        // Assert
        actual1.ShouldBe("foo");
        actual2.ShouldBe("bar");
    }
        public async Task GetById_ErrorResponse_ThrowsException()
        {
            // Arrange
            var httpRequestInterceptor = new HttpClientInterceptorOptions();

            new HttpRequestInterceptionBuilder()
            .Requests()
            .ForHttps()
            .ForHost("api.getaddress.io")
            .ForPath("find/XX2 00X")
            .ForQuery("api-key=key&expand=true&sort=true")
            .IgnoringQuery()
            .Responds()
            .WithStatus(HttpStatusCode.InternalServerError)
            .RegisterWith(httpRequestInterceptor);

            var httpClient = httpRequestInterceptor.CreateHttpClient();

            var options = new Mock <IOptions <GetAddressAddressSearchServiceOptions> >();

            options.Setup(s => s.Value).Returns(new GetAddressAddressSearchServiceOptions {
                Key = "key"
            });

            var service = new GetAddressAddressSearchService(httpClient, options.Object);

            // Act & Assert
            await Assert.ThrowsAsync <HttpRequestException>(() => service.GetById("XX2 00X::660 Mitcham Road"));
        }
        public async Task GetById_ItemDoesNotExist_ReturnsNull()
        {
            // Arrange
            var httpRequestInterceptor = new HttpClientInterceptorOptions();

            new HttpRequestInterceptionBuilder()
            .Requests()
            .ForHttps()
            .ForHost("api.getaddress.io")
            .ForPath("find/XX2 00X")
            .ForQuery("api-key=key&expand=true&sort=true")
            .Responds()
            .WithStatus(HttpStatusCode.NotFound)
            .RegisterWith(httpRequestInterceptor);

            var httpClient = httpRequestInterceptor.CreateHttpClient();

            var options = new Mock <IOptions <GetAddressAddressSearchServiceOptions> >();

            options.Setup(s => s.Value).Returns(new GetAddressAddressSearchServiceOptions {
                Key = "key"
            });

            var service = new GetAddressAddressSearchService(httpClient, options.Object);

            // Act
            var result = await service.GetById("XX2 00X::660 Mitcham Road");

            // Assert
            Assert.Null(result);
        }
        public async Task SearchByPostcode_WithBadRequest_ReturnsEmptyResult()
        {
            // Arrange
            var httpRequestInterceptor = new HttpClientInterceptorOptions();

            new HttpRequestInterceptionBuilder()
            .Requests()
            .ForHttps()
            .ForHost("api.getaddress.io")
            .ForPath("find/XX2 00X")
            .ForQuery("api-key=key&expand=true&sort=true")
            .Responds()
            .WithStatus(HttpStatusCode.BadRequest)
            .RegisterWith(httpRequestInterceptor);

            var httpClient = httpRequestInterceptor.CreateHttpClient();

            var options = new Mock <IOptions <GetAddressAddressSearchServiceOptions> >();

            options.Setup(s => s.Value).Returns(new GetAddressAddressSearchServiceOptions {
                Key = "key"
            });

            var service = new GetAddressAddressSearchService(httpClient, options.Object);

            // Act
            var result = await service.SearchByPostcode("XX2 00X");

            Assert.NotNull(result);
            Assert.Empty(result);
        }
Esempio n. 7
0
    public static async Task SendAsync_Calls_Inner_Handler_If_Registration_Missing()
    {
        // Arrange
        var options = new HttpClientInterceptorOptions()
                      .RegisterByteArray(HttpMethod.Get, new Uri("https://google.com/foo"), () => Array.Empty <byte>())
                      .RegisterByteArray(HttpMethod.Options, new Uri("http://google.com/foo"), () => Array.Empty <byte>())
                      .RegisterByteArray(HttpMethod.Options, new Uri("https://google.com/FOO"), () => Array.Empty <byte>());

        options.OnMissingRegistration = (request) => Task.FromResult <HttpResponseMessage>(null);

        var mock = new Mock <HttpMessageHandler>();

        using var expected = new HttpResponseMessage(HttpStatusCode.OK);
        using var request  = new HttpRequestMessage(HttpMethod.Options, "https://google.com/foo");

        mock.Protected()
        .Setup <Task <HttpResponseMessage> >("SendAsync", request, ItExpr.IsAny <CancellationToken>())
        .ReturnsAsync(expected);

        using var httpClient = options.CreateHttpClient(mock.Object);

        // Act
        var actual = await httpClient.SendAsync(request, CancellationToken.None);

        // Assert
        actual.ShouldBe(expected);
    }
        // etc
        public void QueryEmailAsync_AnotherError_ThrowsResponseException(HttpStatusCode httpStatusCode)
        {
            // Arrange
            var builder = new HttpRequestInterceptionBuilder()
                          .ForHost("emailrep.io")
                          .ForPath("*****@*****.**")
                          .ForHttps()
                          .WithStatus(httpStatusCode);

            var options = new HttpClientInterceptorOptions {
                ThrowOnMissingRegistration = true
            }
            .Register(builder);

            var client = options.CreateHttpClient();

            var sut = new EmailRepClient(client, _settings);

            // Act
            Func <Task> result = () => sut.QueryEmailAsync("*****@*****.**");

            // Assert
            result.Should().ThrowExactly <EmailRepResponseException>()
            .Where(x => x.ErrorCode == ErrorCode.Unknown &&
                   x.OriginalCode == httpStatusCode)
            .WithMessage("Unknown error occured.");
        }
        public async Task SearchByPostcode_WithInternalServerError_ThrowsException()
        {
            // Arrange
            var httpRequestInterceptor = new HttpClientInterceptorOptions();

            new HttpRequestInterceptionBuilder()
            .Requests()
            .ForHttps()
            .ForHost("example.com")
            .ForPath("getaddress/XX2 00X")
            .ForQuery("api-key=key&expand=true&sort=true")
            .Responds()
            .WithStatus(HttpStatusCode.InternalServerError)
            .RegisterWith(httpRequestInterceptor);

            var httpClient = httpRequestInterceptor.CreateHttpClient();

            var options = new Mock <IOptions <GetAddressAddressSearchServiceOptions> >();

            options.Setup(s => s.Value).Returns(new GetAddressAddressSearchServiceOptions {
                ApiUrl = "https://example.com/getaddress/{0}", ApiKey = "key"
            });

            var service = new GetAddressAddressSearchService(httpClient, options.Object);

            // Act & Assert
            await Assert.ThrowsAsync <HttpRequestException>(() => service.SearchByPostcode("XX2 00X"));
        }
    public static void CreateHttpClient_Throws_If_Options_Is_Null()
    {
        // Arrange
        var baseAddress = new Uri("https://google.com");

        HttpClientInterceptorOptions options = null;

        // Act and Assert
        Should.Throw <ArgumentNullException>(() => options.CreateHttpClient(baseAddress), "options");
    }
Esempio n. 11
0
    /// <summary>
    /// Creates an <see cref="HttpClient"/> that uses the interceptors registered for the specified options and base address.
    /// </summary>
    /// <param name="options">The <see cref="HttpClientInterceptorOptions"/> to set up.</param>
    /// <param name="baseAddress">The base address to use for the created HTTP client.</param>
    /// <param name="innerHandler">The optional inner <see cref="HttpMessageHandler"/>.</param>
    /// <returns>
    /// The <see cref="HttpClient"/> that uses the specified <see cref="HttpClientInterceptorOptions"/>.
    /// </returns>
    /// <exception cref="ArgumentNullException">
    /// <paramref name="options"/> is <see langword="null"/>.
    /// </exception>
    public static HttpClient CreateHttpClient(this HttpClientInterceptorOptions options, Uri baseAddress, HttpMessageHandler?innerHandler = null)
    {
        if (options == null)
        {
            throw new ArgumentNullException(nameof(options));
        }

        var client = options.CreateHttpClient(innerHandler);

        client.BaseAddress = baseAddress;

        return(client);
    }
        public void QueryEmailAsync_InvalidEmail_ThrowsException(string emailAddress)
        {
            // Arrange
            var options = new HttpClientInterceptorOptions().RegisterBundle(BundleFileName);

            var client = options.CreateHttpClient();
            var sut    = new EmailRepClient(client, _settings);

            // Act
            Func <Task> result = () => sut.QueryEmailAsync(emailAddress);

            // Assert
            result.Should().ThrowExactly <EmailRepException>().WithMessage("Invalid email address. Email must be valid.");
        }
Esempio n. 13
0
    public static async Task SendAsync_Throws_If_Registration_Missing_Get()
    {
        // Arrange
        var options = new HttpClientInterceptorOptions()
                      .ThrowsOnMissingRegistration();

        using var target = options.CreateHttpClient();

        // Act
        var exception = await Should.ThrowAsync <HttpRequestNotInterceptedException>(
            () => target.GetAsync("https://google.com/"));

        // Assert
        exception.Message.ShouldBe("No HTTP response is configured for GET https://google.com/.");
    }
        public async Task SearchByPostcode_ValidRequest_ReturnsParsedResults()
        {
            // Arrange
            var options = new HttpClientInterceptorOptions();

            new HttpRequestInterceptionBuilder()
            .Requests()
            .ForHttps()
            .ForHost("services.postcodeanywhere.co.uk")
            .ForPath("PostcodeAnywhere/Interactive/FindByPostcode/v1.00/json3.ws")
            .IgnoringQuery()
            .Responds()
            .WithJsonContent(new
            {
                Items = new[]
                {
                    new { Id = "5702836.00", StreetAddress = "2 Seagrave Road", Place = "Coventry" },
                    new { Id = "5702847.00", StreetAddress = "4 Seagrave Road", Place = "Coventry" },
                    new { Id = "5702859.00", StreetAddress = "6 Seagrave Road", Place = "Coventry" },
                }
            })
            .RegisterWith(options);

            var httpClient = options.CreateHttpClient();

            var service = new LoqateAddressSearchService(httpClient, new Options()
            {
                Key = "key"
            });

            // Act
            var result = await service.SearchByPostcode("CV1 2AA");

            // Assert
            Assert.Equal(3, result.Count);

            Assert.Equal("5702836.00", result.First().Id);
            Assert.Equal("2 Seagrave Road", result.First().StreetAddress);
            Assert.Equal("Coventry", result.First().Place);

            Assert.Equal("5702847.00", result.Skip(1).First().Id);
            Assert.Equal("4 Seagrave Road", result.Skip(1).First().StreetAddress);
            Assert.Equal("Coventry", result.Skip(1).First().Place);

            Assert.Equal("5702859.00", result.Skip(2).First().Id);
            Assert.Equal("6 Seagrave Road", result.Skip(2).First().StreetAddress);
            Assert.Equal("Coventry", result.Skip(2).First().Place);
        }
        public async Task QueryEmailAsync_Success()
        {
            // Arrange
            var options = new HttpClientInterceptorOptions().RegisterBundle(BundleFileName);

            var client = options.CreateHttpClient();
            var sut    = new EmailRepClient(client, _settings);

            // Act
            var result = await sut.QueryEmailAsync("*****@*****.**");

            // Assert
            result.Should().NotBeNull();
            result.Email.Should().Be("*****@*****.**");
            // not checking the mapping code here, so not further processing to be checked.
        }
        public void QueryEmailAsync_InvalidApiKey_ThrowsResponseException()
        {
            // Arrange
            var options = new HttpClientInterceptorOptions().RegisterBundle(BundleFileName);

            var client = options.CreateHttpClient();
            var sut    = new EmailRepClient(client, _settings);

            // Act
            Func <Task> result = () => sut.QueryEmailAsync("*****@*****.**");

            // Assert
            result.Should().ThrowExactly <EmailRepResponseException>()
            .Where(
                x => x.ErrorCode == ErrorCode.InvalidApiKey &&
                x.OriginalCode == HttpStatusCode.Unauthorized)
            .WithMessage("invalid api key");
        }
        public void QueryEmailAsync_InvalidEmail_ThrowsResponseException()
        {
            // Arrange
            var options = new HttpClientInterceptorOptions().RegisterBundle(BundleFileName);

            var client = options.CreateHttpClient();
            var sut    = new EmailRepClient(client, _settings);

            // Act
            Func <Task> result = () => sut.QueryEmailAsync("invalid@bob");

            // Assert
            result.Should().ThrowExactly <EmailRepResponseException>()
            .Where(
                x => x.ErrorCode == ErrorCode.InvalidEmailAddress &&
                x.OriginalCode == HttpStatusCode.BadRequest)
            .WithMessage("invalid email");
        }
        public void QueryEmailAsync_DailyLimitHit_ThrowsResponseException()
        {
            // Arrange
            var options = new HttpClientInterceptorOptions().RegisterBundle(BundleFileName);

            var client = options.CreateHttpClient();
            var sut    = new EmailRepClient(client, _settings);

            // Act
            Func <Task> result = () => sut.QueryEmailAsync("*****@*****.**");

            // Assert
            result.Should().ThrowExactly <EmailRepResponseException>()
            .Where(
                x => x.ErrorCode == ErrorCode.TooManyRequests &&
                x.OriginalCode == HttpStatusCode.TooManyRequests)
            .WithMessage("exceeded daily limit. please wait 24 hrs or visit emailrep.io/key for an api key.");
        }