Skip to content

Instantly share code, notes, and snippets.

@JayBazuzi
Created October 1, 2017 07:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JayBazuzi/85501561f5321cb1dc6116ff60f07bc3 to your computer and use it in GitHub Desktop.
Save JayBazuzi/85501561f5321cb1dc6116ff60f07bc3 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
class PlaybackHtmlMessageHandler : HttpClientHandler
{
private readonly List<Tuple<HtmlRequestMessageData,
PassthroughAndRecordHttpMessageHandler.HtmlResponseMessageData>> _recordings;
private int _currentRecordingIndex;
public PlaybackHtmlMessageHandler(
List<Tuple<HtmlRequestMessageData, PassthroughAndRecordHttpMessageHandler.HtmlResponseMessageData>>
recordings)
{
_recordings = recordings;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
var recording = _recordings[_currentRecordingIndex++];
recording.Item1.Should().BeEquivalentTo(await HtmlRequestMessageData.FromHttpRequestMessage(request));
return await recording.Item2.ToHttpResponseMessage();
}
protected override void Dispose(bool disposing)
{
VerifyAllRequestsSent();
base.Dispose(disposing);
}
private void VerifyAllRequestsSent()
{
Assert.AreEqual(_recordings.Count, _currentRecordingIndex);
}
}
class PassthroughAndRecordHttpMessageHandler : HttpClientHandler
{
public readonly List<Tuple<HtmlRequestMessageData, HtmlResponseMessageData>> Recordings =
new List<Tuple<HtmlRequestMessageData, HtmlResponseMessageData>>();
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
var response = await base.SendAsync(request, cancellationToken);
await Record(request, response);
return response;
}
private async Task Record(HttpRequestMessage request, HttpResponseMessage response)
{
Recordings.Add(Tuple.Create(
await HtmlRequestMessageData.FromHttpRequestMessage(request),
await HtmlResponseMessageData.FromHttpResponseMessage(response)));
}
public class HtmlResponseMessageData
{
public readonly string Content;
public readonly string ReasonPhrase;
public readonly HttpStatusCode StatusCode;
public HtmlResponseMessageData(string content, HttpStatusCode statusCode, string reasonPhrase)
{
Content = content;
StatusCode = statusCode;
ReasonPhrase = reasonPhrase;
}
public static async Task<HtmlResponseMessageData> FromHttpResponseMessage(HttpResponseMessage response)
{
return new HtmlResponseMessageData(await (response.Content?.ReadAsStringAsync()).OrDefault(),
response.StatusCode,
response.ReasonPhrase);
}
public async Task<HttpResponseMessage> ToHttpResponseMessage()
{
return new HttpResponseMessage
{
Content = new StringContent(Content),
ReasonPhrase = ReasonPhrase,
StatusCode = StatusCode
};
}
}
}
static class _
{
public static Task<T> OrDefault<T>(this Task<T> task)
{
return task ?? Task.FromResult(default(T));
}
public static async Task<string> GetAsStringAsync(this HttpClient httpClient, string requestUri)
{
var response = await httpClient.GetAsync(requestUri);
return await (response.Content?.ReadAsStringAsync()).OrDefault();
}
}
class HtmlRequestMessageData
{
public readonly string Content;
public readonly HttpMethod Method;
public readonly Uri RequestUri;
private HtmlRequestMessageData(HttpMethod method, Uri requestUri, string content)
{
Method = method;
RequestUri = requestUri;
Content = content;
}
public static async Task<HtmlRequestMessageData> FromHttpRequestMessage(HttpRequestMessage request)
{
return new HtmlRequestMessageData(request.Method, request.RequestUri,
await (request.Content?.ReadAsStringAsync()).OrDefault());
}
}
var recordingHandler = new PassthroughAndRecordHttpMessageHandler();
var realServerContent = await new HttpClient(recordingHandler).GetAsStringAsync(RequestUri);
var playbackHandler = new PlaybackHtmlMessageHandler(recordingHandler.Recordings);
var contentFromPlayback = await new HttpClient(playbackHandler).GetAsStringAsync(RequestUri);
Assert.AreEqual(realServerContent, contentFromPlayback);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment