Ejemplo n.º 1
0
        /// <summary>
        /// Creates a tester.
        /// </summary>
        /// <param name="tests">The conformance tests.</param>
        /// <param name="api">The API interface to test.</param>
        /// <param name="httpClient">The optional HTTP client for HTTP tests.</param>
        public ConformanceApiTester(IReadOnlyList <ConformanceTestInfo> tests, IConformanceApi api, HttpClient?httpClient)
        {
            m_tests      = tests ?? throw new ArgumentNullException(nameof(tests));
            m_api        = api ?? throw new ArgumentNullException(nameof(api));
            m_httpClient = httpClient;

            var sameNameTests = m_tests.GroupBy(x => x.Test).FirstOrDefault(x => x.Count() != 1);

            if (sameNameTests != null)
            {
                throw new ArgumentException($"Multiple tests have the name {sameNameTests.First().Test}");
            }

            foreach (var testsPerMethod in m_tests.GroupBy(x => x.Method).Select(x => x.ToList()))
            {
                for (var i = 0; i < testsPerMethod.Count; i++)
                {
                    for (var j = i + 1; j < testsPerMethod.Count; j++)
                    {
                        if (JToken.DeepEquals(testsPerMethod[i].Request, testsPerMethod[j].Request))
                        {
                            throw new ArgumentException($"Tests must not have the same method name and request data, e.g. {testsPerMethod[i].Test} and {testsPerMethod[j].Test}.");
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Creates the handler.
        /// </summary>
        public ConformanceApiHttpHandler(IConformanceApi service, ServiceHttpHandlerSettings settings)
            : base(settings)
        {
            if (service == null)
            {
                throw new ArgumentNullException("service");
            }

            m_service = service;
        }
 public ConformanceApiController(IConformanceApi api)
 {
     m_api = api;
 }
Ejemplo n.º 4
0
    private async Task HostAsync(HttpContext httpContext, IConformanceApi service, HttpContentSerializer contentSerializer)
    {
        var httpRequest = httpContext.Request;
        var requestUrl  = httpRequest.GetEncodedUrl();

        var apiHandler = new ConformanceApiHttpHandler(service, new ServiceHttpHandlerSettings {
            ContentSerializer = contentSerializer
        });

        var requestMessage = new HttpRequestMessage(new HttpMethod(httpRequest.Method), requestUrl)
        {
            Content = new StreamContent(httpRequest.Body),
        };

        foreach (var header in httpRequest.Headers)
        {
            // Every header should be able to fit into one of the two header collections.
            // Try message.Headers first since that accepts more of them.
            if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.AsEnumerable()))
            {
                requestMessage.Content.Headers.TryAddWithoutValidation(header.Key, header.Value.AsEnumerable());
            }
        }

        HttpResponseMessage?responseMessage = null;
        ServiceErrorDto?    error           = null;

        try
        {
            responseMessage = await apiHandler.TryHandleHttpRequestAsync(requestMessage, httpContext.RequestAborted).ConfigureAwait(false);

            if (responseMessage == null)
            {
                error = ServiceErrors.CreateInvalidRequest($"Test not found for {httpRequest.Method} {requestUrl}");
            }
        }
        catch (Exception exception)
        {
            error = ServiceErrorUtility.CreateInternalErrorForException(exception);
        }

        if (error != null)
        {
            var statusCode = HttpServiceErrors.TryGetHttpStatusCode(error.Code) ?? HttpStatusCode.InternalServerError;
            responseMessage = new HttpResponseMessage(statusCode)
            {
                Content = contentSerializer.CreateHttpContent(error)
            };
        }

        if (responseMessage != null)
        {
            using (responseMessage)
            {
                var response = httpContext.Response;
                response.StatusCode = (int)responseMessage.StatusCode;

                var responseHeaders = responseMessage.Headers;

                // Ignore the Transfer-Encoding header if it is just "chunked".
                // We let the host decide about whether the response should be chunked or not.
                if (responseHeaders.TransferEncodingChunked == true && responseHeaders.TransferEncoding.Count == 1)
                {
                    responseHeaders.TransferEncoding.Clear();
                }

                foreach (var header in responseHeaders)
                {
                    response.Headers.Append(header.Key, header.Value.ToArray());
                }

                // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                if (responseMessage.Content != null)
                {
                    var contentHeaders = responseMessage.Content.Headers;

                    // Copy the response content headers only after ensuring they are complete.
                    // We ask for Content-Length first because HttpContent lazily computes this
                    // and only afterwards writes the value into the content headers.
                    _ = contentHeaders.ContentLength;

                    foreach (var header in contentHeaders)
                    {
                        response.Headers.Append(header.Key, header.Value.ToArray());
                    }

                    await responseMessage.Content.CopyToAsync(response.Body).ConfigureAwait(false);
                }
            }
        }
    }
Ejemplo n.º 5
0
 public ConformanceApiHttpHandler(IConformanceApi service, ServiceHttpHandlerSettings?settings = null)
     : base(settings, s_defaults)
 {
     m_service = service ?? throw new ArgumentNullException(nameof(service));
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Creates a tester.
 /// </summary>
 /// <param name="tests">The conformance tests.</param>
 /// <param name="api">The API interface to test.</param>
 public ConformanceApiTester(IReadOnlyList <ConformanceTestInfo> tests, IConformanceApi api)
     : this(tests, api, httpClient : null)
 {
 }
Ejemplo n.º 7
0
 public ConformanceApiTester(IReadOnlyList <ConformanceTestInfo> tests, IConformanceApi api, HttpClient?httpClient)
     : this(new ConformanceApiTesterSettings {
     Tests = tests, Api = api, JsonSerializer = NewtonsoftJsonServiceSerializer.Instance, HttpClient = httpClient
 })
 {
 }