#508 more test asserts for headers, cookies
This commit is contained in:
parent
ddc709286a
commit
4724c709dc
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -24,9 +24,8 @@ namespace Flurl.Test.Http
|
||||
await "https://cookies.com/2".WithCookies(cookies).GetAsync();
|
||||
await "https://cookies.com/3".WithCookies(cookies).GetAsync();
|
||||
|
||||
HttpTest.ShouldHaveMadeACall().WithCookie("x", "foo").Times(3);
|
||||
HttpTest.ShouldHaveMadeACall().WithCookie("y", "bar").Times(2);
|
||||
HttpTest.ShouldHaveMadeACall().WithCookie("y", "bazz").Times(1);
|
||||
HttpTest.ShouldHaveMadeACall().WithCookies(new { x = "foo", y = "bar" }).Times(2);
|
||||
HttpTest.ShouldHaveMadeACall().WithCookies(new { x = "foo", y = "bazz" }).Times(1);
|
||||
|
||||
Assert.AreEqual(2, cookies.Count);
|
||||
Assert.AreEqual("foo", cookies["x"].Value);
|
||||
@ -47,9 +46,8 @@ namespace Flurl.Test.Http
|
||||
await "https://cookies.com/2".WithCookies(cookies).GetAsync();
|
||||
await "https://cookies.com/3".WithCookies(cookies).GetAsync();
|
||||
|
||||
HttpTest.ShouldHaveMadeACall().WithCookie("x", "foo").Times(4);
|
||||
HttpTest.ShouldHaveMadeACall().WithCookie("y", "bar").Times(3);
|
||||
HttpTest.ShouldHaveMadeACall().WithCookie("y", "bazz").Times(1);
|
||||
HttpTest.ShouldHaveMadeACall().WithCookies(new { x = "foo", y = "bar" }).Times(3);
|
||||
HttpTest.ShouldHaveMadeACall().WithCookies(new { x = "foo", y = "bazz" }).Times(1);
|
||||
|
||||
Assert.AreEqual(2, cookies.Count);
|
||||
Assert.AreEqual("foo", cookies["x"].Value);
|
||||
@ -71,9 +69,8 @@ namespace Flurl.Test.Http
|
||||
await cs.Request("2").GetAsync();
|
||||
await cs.Request("3").GetAsync();
|
||||
|
||||
HttpTest.ShouldHaveMadeACall().WithCookie("x", "foo").Times(3);
|
||||
HttpTest.ShouldHaveMadeACall().WithCookie("y", "bar").Times(2);
|
||||
HttpTest.ShouldHaveMadeACall().WithCookie("y", "bazz").Times(1);
|
||||
HttpTest.ShouldHaveMadeACall().WithCookies(new { x = "foo", y = "bar" }).Times(2);
|
||||
HttpTest.ShouldHaveMadeACall().WithCookies(new { x = "foo", y = "bazz" }).Times(1);
|
||||
|
||||
Assert.AreEqual(2, cs.Cookies.Count);
|
||||
Assert.AreEqual("foo", cs.Cookies["x"].Value);
|
||||
|
@ -114,14 +114,14 @@ namespace Flurl.Http.Testing
|
||||
|
||||
#region query params
|
||||
/// <summary>
|
||||
/// Asserts whether calls were made containing the given query parameter name and (optionally) value.
|
||||
/// Asserts whether calls were made containing the given query parameter name and (optionally) value. value may contain * wildcard.
|
||||
/// </summary>
|
||||
public HttpCallAssertion WithQueryParam(string name, object value = null) {
|
||||
return With(c => c.HasQueryParam(name, value), BuildDescrip("query param", name, value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asserts whether calls were made NOT containing the given query parameter and (optionally) value.
|
||||
/// Asserts whether calls were made NOT containing the given query parameter and (optionally) value. value may contain * wildcard.
|
||||
/// </summary>
|
||||
public HttpCallAssertion WithoutQueryParam(string name, object value = null) {
|
||||
return Without(c => c.HasQueryParam(name, value), BuildDescrip("no query param", name, value));
|
||||
@ -172,39 +172,123 @@ namespace Flurl.Http.Testing
|
||||
|
||||
#region headers
|
||||
/// <summary>
|
||||
/// Asserts whether calls were made containing the given request header and (optionally) value.
|
||||
/// value may contain * wildcard.
|
||||
/// Asserts whether calls were made containing the given header name and (optionally) value. value may contain * wildcard.
|
||||
/// </summary>
|
||||
public HttpCallAssertion WithHeader(string name, string valuePattern = "*", string descrip = null) {
|
||||
descrip = descrip ?? BuildDescrip("header", name, valuePattern);
|
||||
return With(c => c.HasHeader(name, valuePattern), descrip);
|
||||
public HttpCallAssertion WithHeader(string name, object value = null) {
|
||||
return With(c => c.HasHeader(name, value), BuildDescrip("header", name, value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asserts whether calls were made that do NOT contain the given request header and (optionally) value.
|
||||
/// value may contain * wildcard.
|
||||
/// Asserts whether calls were made NOT containing the given header and (optionally) value. value may contain * wildcard.
|
||||
/// </summary>
|
||||
public HttpCallAssertion WithoutHeader(string name, string valuePattern = "*") {
|
||||
return Without(c => c.HasHeader(name, valuePattern), BuildDescrip("no header", name, valuePattern));
|
||||
public HttpCallAssertion WithoutHeader(string name, object value = null) {
|
||||
return Without(c => c.HasHeader(name, value), BuildDescrip("no header", name, value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asserts whether calls were made containing ALL the given headers (regardless of their values).
|
||||
/// </summary>
|
||||
public HttpCallAssertion WithHeaders(params string[] names) {
|
||||
return names.Select(n => WithHeader(n)).LastOrDefault() ?? this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asserts whether calls were made NOT containing any of the given headers.
|
||||
/// If no names are provided, asserts no calls were made with any headers.
|
||||
/// </summary>
|
||||
public HttpCallAssertion WithoutHeaders(params string[] names) {
|
||||
if (!names.Any())
|
||||
return With(c => !c.Request.Headers.Any(), "no headers");
|
||||
return names.Select(n => WithoutHeader(n)).LastOrDefault() ?? this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asserts whether calls were made containing ANY the given headers (regardless of their values).
|
||||
/// If no names are provided, asserts that calls were made containing at least one header with any name.
|
||||
/// </summary>
|
||||
public HttpCallAssertion WithAnyHeader(params string[] names) {
|
||||
var descrip = $"any header {string.Join(", ", names)}".Trim();
|
||||
return With(call => {
|
||||
if (!names.Any()) return call.Request.Headers.Any();
|
||||
return call.Request.Headers.Select(h => h.Key).Intersect(names).Any();
|
||||
}, descrip);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asserts whether calls were made containing all of the given header values.
|
||||
/// </summary>
|
||||
/// <param name="values">Object (usually anonymous) or dictionary that is parsed to name/value headers to check for. Values may contain * wildcard.</param>
|
||||
public HttpCallAssertion WithHeaders(object values) {
|
||||
return values.ToKeyValuePairs().Select(kv => WithHeader(kv.Key, kv.Value)).LastOrDefault() ?? this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asserts whether calls were made NOT containing any of the given header values.
|
||||
/// </summary>
|
||||
/// <param name="values">Object (usually anonymous) or dictionary that is parsed to name/value headers to check for. Values may contain * wildcard.</param>
|
||||
public HttpCallAssertion WithoutHeaders(object values) {
|
||||
return values.ToKeyValuePairs().Select(kv => WithoutHeader(kv.Key, kv.Value)).LastOrDefault() ?? this;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region cookies
|
||||
/// <summary>
|
||||
/// Asserts whether calls were made containing the given cookie and (optionally) value.
|
||||
/// value may contain * wildcard.
|
||||
/// Asserts whether calls were made containing the given cookie name and (optionally) value. value may contain * wildcard.
|
||||
/// </summary>
|
||||
public HttpCallAssertion WithCookie(string name, string valuePattern = "*", string descrip = null) {
|
||||
descrip = descrip ?? BuildDescrip("cookie", name, valuePattern);
|
||||
return With(c => c.HasCookie(name, valuePattern), descrip);
|
||||
public HttpCallAssertion WithCookie(string name, object value = null) {
|
||||
return With(c => c.HasCookie(name, value), BuildDescrip("cookie", name, value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asserts whether calls were made that do NOT contain the given cookie and (optionally) value.
|
||||
/// value may contain * wildcard.
|
||||
/// Asserts whether calls were made NOT containing the given cookie and (optionally) value. value may contain * wildcard.
|
||||
/// </summary>
|
||||
public HttpCallAssertion WithoutCookie(string name, string valuePattern = "*") {
|
||||
return Without(c => c.HasCookie(name, valuePattern), BuildDescrip("no cookie", name, valuePattern));
|
||||
public HttpCallAssertion WithoutCookie(string name, object value = null) {
|
||||
return Without(c => c.HasCookie(name, value), BuildDescrip("no cookie", name, value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asserts whether calls were made containing ALL the given cookies (regardless of their values).
|
||||
/// </summary>
|
||||
public HttpCallAssertion WithCookies(params string[] names) {
|
||||
return names.Select(n => WithCookie(n)).LastOrDefault() ?? this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asserts whether calls were made NOT containing any of the given cookies.
|
||||
/// If no names are provided, asserts no calls were made with any cookies.
|
||||
/// </summary>
|
||||
public HttpCallAssertion WithoutCookies(params string[] names) {
|
||||
if (!names.Any())
|
||||
return With(c => !c.Request.Cookies.Any(), "no cookies");
|
||||
return names.Select(n => WithoutCookie(n)).LastOrDefault() ?? this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asserts whether calls were made containing ANY the given cookies (regardless of their values).
|
||||
/// If no names are provided, asserts that calls were made containing at least one cookie with any name.
|
||||
/// </summary>
|
||||
public HttpCallAssertion WithAnyCookie(params string[] names) {
|
||||
var descrip = $"any cookie {string.Join(", ", names)}".Trim();
|
||||
return With(call => {
|
||||
if (!names.Any()) return call.Request.Cookies.Any();
|
||||
return call.Request.Cookies.Select(c => c.Key).Intersect(names).Any();
|
||||
}, descrip);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asserts whether calls were made containing all of the given cookie values.
|
||||
/// </summary>
|
||||
/// <param name="values">Object (usually anonymous) or dictionary that is parsed to name/value cookies to check for. Values may contain * wildcard.</param>
|
||||
public HttpCallAssertion WithCookies(object values) {
|
||||
return values.ToKeyValuePairs().Select(kv => WithCookie(kv.Key, kv.Value)).LastOrDefault() ?? this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asserts whether calls were made NOT containing any of the given cookie values.
|
||||
/// </summary>
|
||||
/// <param name="values">Object (usually anonymous) or dictionary that is parsed to name/value cookies to check for. Values may contain * wildcard.</param>
|
||||
public HttpCallAssertion WithoutCookies(object values) {
|
||||
return values.ToKeyValuePairs().Select(kv => WithoutCookie(kv.Key, kv.Value)).LastOrDefault() ?? this;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -224,7 +308,7 @@ namespace Flurl.Http.Testing
|
||||
/// Token can contain * wildcard.
|
||||
/// </summary>
|
||||
public HttpCallAssertion WithOAuthBearerToken(string token = "*") {
|
||||
return WithHeader("Authorization", $"Bearer {token}", "bearer token " + token);
|
||||
return WithHeader("Authorization", $"Bearer {token}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -4,7 +4,6 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Flurl.Util;
|
||||
|
||||
namespace Flurl.Http.Testing
|
||||
@ -14,16 +13,6 @@ namespace Flurl.Http.Testing
|
||||
/// </summary>
|
||||
internal static class Util
|
||||
{
|
||||
internal static bool MatchesPattern(string textToCheck, string pattern) {
|
||||
// avoid regex'ing in simple cases
|
||||
if (string.IsNullOrEmpty(pattern) || pattern == "*") return true;
|
||||
if (string.IsNullOrEmpty(textToCheck)) return false;
|
||||
if (!pattern.Contains("*")) return textToCheck == pattern;
|
||||
|
||||
var regex = "^" + Regex.Escape(pattern).Replace("\\*", "(.*)") + "$";
|
||||
return Regex.IsMatch(textToCheck ?? "", regex);
|
||||
}
|
||||
|
||||
internal static bool HasAnyVerb(this FlurlCall call, HttpMethod[] verbs) {
|
||||
// for good measure, check both FlurlRequest.Verb and HttpRequestMessage.Method
|
||||
return verbs.Any(verb => call.Request.Verb == verb && call.HttpRequestMessage.Method == verb);
|
||||
@ -44,15 +33,11 @@ namespace Flurl.Http.Testing
|
||||
|
||||
if (!paramVals.Any())
|
||||
return false;
|
||||
if (value == null)
|
||||
return true;
|
||||
if (value is string s)
|
||||
return paramVals.Any(v => MatchesPattern(v, s));
|
||||
if (value is IEnumerable en) {
|
||||
if (!(value is string) && value is IEnumerable en) {
|
||||
var values = en.Cast<object>().Select(o => o.ToInvariantString()).ToList();
|
||||
return values.Intersect(paramVals).Count() == values.Count;
|
||||
}
|
||||
return paramVals.Any(v => v == value.ToInvariantString());
|
||||
return paramVals.Any(v => MatchesValue(v, value));
|
||||
}
|
||||
|
||||
internal static bool HasAllQueryParams(this FlurlCall call, string[] names) {
|
||||
@ -74,23 +59,32 @@ namespace Flurl.Http.Testing
|
||||
return values.ToKeyValuePairs().All(kv => call.HasQueryParam(kv.Key, kv.Value));
|
||||
}
|
||||
|
||||
internal static bool HasHeader(this FlurlCall call, string name, string valuePattern) {
|
||||
var val = call.HttpRequestMessage.GetHeaderValue(name);
|
||||
return val != null && MatchesPattern(val, valuePattern);
|
||||
internal static bool HasHeader(this FlurlCall call, string name, object value) {
|
||||
return call.Request.Headers.TryGetValue(name, out var val) && MatchesValue(val?.ToInvariantString(), value);
|
||||
}
|
||||
|
||||
internal static bool HasCookie(this FlurlCall call, string name, string valuePattern) {
|
||||
var headerVal = call.HttpRequestMessage.GetHeaderValue("Cookie");
|
||||
if (headerVal == null) return false;
|
||||
return (
|
||||
from kv in headerVal.Split(';')
|
||||
let parts = kv.SplitOnFirstOccurence("=")
|
||||
where parts.Length == 2
|
||||
let key = parts[0].Trim()
|
||||
where key == name
|
||||
let val = parts[1].Trim()
|
||||
where MatchesPattern(val, valuePattern)
|
||||
select 1).Any();
|
||||
internal static bool HasCookie(this FlurlCall call, string name, object value) {
|
||||
return call.Request.Cookies.TryGetValue(name, out var val) && MatchesValue(val, value);
|
||||
}
|
||||
|
||||
private static bool MatchesValue(string valueToMatch, object value) {
|
||||
if (value == null)
|
||||
return true;
|
||||
if (valueToMatch == null)
|
||||
return false;
|
||||
if (value is string s)
|
||||
return MatchesPattern(valueToMatch, s);
|
||||
return valueToMatch == value.ToInvariantString();
|
||||
}
|
||||
|
||||
internal static bool MatchesPattern(string textToCheck, string pattern) {
|
||||
// avoid regex'ing in simple cases
|
||||
if (string.IsNullOrEmpty(pattern) || pattern == "*") return true;
|
||||
if (string.IsNullOrEmpty(textToCheck)) return false;
|
||||
if (!pattern.Contains("*")) return textToCheck == pattern;
|
||||
|
||||
var regex = "^" + Regex.Escape(pattern).Replace("\\*", "(.*)") + "$";
|
||||
return Regex.IsMatch(textToCheck ?? "", regex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user