// ------------------------------------------------------------ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. // ------------------------------------------------------------ namespace Dapr { using System; using System.Collections.Concurrent; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Text.Json; using System.Threading; using System.Threading.Tasks; // This client will capture all requests, and put them in .Requests for you to inspect. public class TestHttpClient : HttpClient { private readonly TestHttpClientHandler handler; public TestHttpClient() : this(new TestHttpClientHandler()) { } private TestHttpClient(TestHttpClientHandler handler) : base(handler) { this.handler = handler; } public ConcurrentQueue Requests => this.handler.Requests; public Action Handler { get => this.handler.Handler; set => this.handler.Handler = value; } public class Entry { public Entry(HttpRequestMessage request) { this.Request = request; this.Completion = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); } public TaskCompletionSource Completion { get; } public HttpRequestMessage Request { get; } public bool IsGetStateRequest => this.Request.Method == HttpMethod.Get; public bool IsSetStateRequest => this.Request.Method == HttpMethod.Post; public void Respond(HttpResponseMessage response) { this.Completion.SetResult(response); } public void RespondWithResponse(HttpResponseMessage response) { this.Completion.SetResult(response); } public void RespondWithJson(TValue value, JsonSerializerOptions options = null) { var bytes = JsonSerializer.SerializeToUtf8Bytes(value, options); var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(bytes) }; response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json") { CharSet = "UTF-8", }; this.Completion.SetResult(response); } } private class TestHttpClientHandler : HttpMessageHandler { public TestHttpClientHandler() { this.Requests = new ConcurrentQueue(); } public ConcurrentQueue Requests { get; } public Action Handler { get; set; } protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var entry = new Entry(request); this.Handler?.Invoke(entry); this.Requests.Enqueue(entry); using (cancellationToken.Register(() => entry.Completion.TrySetCanceled())) { return await entry.Completion.Task.ConfigureAwait(false); } } } } }