Skip to content

Instantly share code, notes, and snippets.

@palmerandy
Last active June 20, 2020 11:25
Show Gist options
  • Save palmerandy/2da6b7fc0e9bfa0b4a8e39888677468b to your computer and use it in GitHub Desktop.
Save palmerandy/2da6b7fc0e9bfa0b4a8e39888677468b to your computer and use it in GitHub Desktop.
C# End-to-end automated integration testing for MVC. More infromation available at https://andypalmer.dev/end-to-end-testing-mvc-signalr-api
using System;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
public static class AntiForgeryHelper
{
public static string ExtractAntiForgeryToken(string htmlResponseText)
{
if (htmlResponseText == null)
{
throw new ArgumentNullException("htmlResponseText");
}
var match = Regex.Match(htmlResponseText, @"\<input name=""__RequestVerificationToken"" type=""hidden"" value=""([^""]+)"" \/\>");
return match.Success ? match.Groups[1].Captures[0].Value : null;
}
public static async Task<string> ExtractAntiForgeryToken(this HttpResponseMessage response)
{
string responseAsString = await response.Content.ReadAsStringAsync();
return ExtractAntiForgeryToken(responseAsString);
}
}
using Microsoft.Net.Http.Headers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
public class CookiesHelper
{
public static IDictionary<string, string> ExtractCookiesFromResponse(HttpResponseMessage response)
{
IDictionary<string, string> result = new Dictionary<string, string>();
if (response.Headers.TryGetValues("Set-Cookie", out var values))
{
SetCookieHeaderValue.ParseList(values.ToList()).ToList().ForEach(cookie =>
{
result.Add(cookie.Name.ToString(), cookie.Value.ToString());
});
}
return result;
}
public static HttpRequestMessage PutCookiesOnRequest(HttpRequestMessage request, IDictionary<string, string> cookies)
{
cookies.Keys.ToList().ForEach(key =>
{
request.Headers.Add("Cookie", new CookieHeaderValue(key, cookies[key]).ToString());
});
return request;
}
public static HttpRequestMessage CopyCookiesFromResponse(HttpRequestMessage request, HttpResponseMessage response)
{
return PutCookiesOnRequest(request, ExtractCookiesFromResponse(response));
}
}
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
public class MvcHttpClientHelper
{
public HttpClient Client { get; }
public MvcHttpClientHelper(HttpClient httpClient)
{
Client = httpClient;
}
public async Task<HttpResponseMessage> LoginHttpRequest()
{
var request = new HttpRequestMessage(new HttpMethod("GET"), $"{Environment.MvcUrl}/Login");
var httpResponseMessage = await Client.SendAsync(request);
var formPostBodyData = await ExtractAntiForgeryToken(httpResponseMessage, new Dictionary<string, string> { { "username", Environment.Username }, { "password", Environment.Password } });
var requestMessage = PostRequestHelper.CreateWithCookiesFromResponse($"{ Environment.MvcUrl}/Login", formPostBodyData, httpResponseMessage);
var response = await Client.SendAsync(requestMessage);
string result = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
return response;
}
else
{
throw new Exception(result);
}
}
public async Task<HttpResponseMessage> PostHttpRequest(HttpResponseMessage httpResponseMessage, string url, Dictionary<string, string> formData)
{
var formPostBodyData = await ExtractAntiForgeryToken(httpResponseMessage, formData);
var requestMessage = PostRequestHelper.CreateWithCookiesFromResponse(url, formPostBodyData, httpResponseMessage);
var response = await Client.SendAsync(requestMessage);
var result = await response.Content.ReadAsStringAsync();
return response;
}
private static async Task<Dictionary<string, string>> ExtractAntiForgeryToken(HttpResponseMessage httpResponseMessage, Dictionary<string, string> formData)
{
var antiForgeryToken = await httpResponseMessage.ExtractAntiForgeryToken();
formData.Add("__RequestVerificationToken", antiForgeryToken);
return formData;
}
}
using Microsoft.Net.Http.Headers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
public class PostRequestHelper
{
public static HttpRequestMessage Create(String path, Dictionary<string, string> formPostBodyData)
{
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, path)
{
Content = new FormUrlEncodedContent(ToFormPostData(formPostBodyData))
};
return httpRequestMessage;
}
public static List<KeyValuePair<string, string>> ToFormPostData(Dictionary<string, string> formPostBodyData)
{
List<KeyValuePair<string, string>> result = new List<KeyValuePair<string, string>>();
formPostBodyData.Keys.ToList().ForEach(key =>
{
result.Add(new KeyValuePair<string, string>(key, formPostBodyData[key]));
});
return result;
}
public static HttpRequestMessage CreateWithCookiesFromResponse(string path, Dictionary<string, string> formPostBodyData,
HttpResponseMessage response)
{
var httpRequestMessage = Create(path, formPostBodyData);
return CookiesHelper.CopyCookiesFromResponse(httpRequestMessage, response);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment