Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5718ec0
Added NTLM authentication and small updates
mihaj Nov 19, 2020
e54faf7
Merge branch 'main' into develop
mihaj Dec 7, 2020
8e60581
Upload files with multipart content type
mihaj Dec 7, 2020
8db309a
Merge branch 'develop' of https://github.com/qatoolkit/qatoolkit-engi…
mihaj Dec 7, 2020
280b19a
Merge branch 'main' into develop
mihaj Dec 7, 2020
f0f9f5e
CreateHttpRequest override that accepts HttpRequest object
mihaj Dec 12, 2020
48787a2
Merge branch 'main' into develop
mihaj Dec 12, 2020
df94c4e
Merge branch 'develop' of https://github.com/qatoolkit/qatoolkit-engi…
mihaj Dec 12, 2020
2557cc8
Merge branch 'main' into develop
mihaj Dec 12, 2020
f05c3cd
Asserter has new methods ResponseStatusCodeIsSuccess and ResponseBody…
mihaj Dec 14, 2020
9dc1f90
Merge branch 'main' into develop
mihaj Dec 14, 2020
4f55262
HttpTester client now has WithPathReplacementValues, bug fix with que…
mihaj Dec 14, 2020
3a58192
Merge branch 'main' into develop
mihaj Dec 14, 2020
b3ba223
maintenance
mihaj Dec 30, 2020
3d5b02f
year update
mihaj Jan 2, 2021
9989309
Http duration added, XML deserializer for HTTP response content
mihaj Feb 22, 2021
4deb763
Merge branch 'main' into develop
mihaj Feb 22, 2021
c99d168
HTTP authentication with client certificate
mihaj Apr 13, 2021
c6e3ba2
Merge branch 'main' into develop
mihaj Apr 13, 2021
2bc133a
nuget updates
mihaj Aug 17, 2021
6b7ea84
Merge branch 'main' into develop
mihaj Aug 17, 2021
4787e81
nuget updates
mihaj Aug 17, 2021
5795435
Implementation of assert named ResponseContentTypeEquals (#32)
mihaj Nov 1, 2021
1c95e75
Merge branch 'main' into develop
mihaj Nov 1, 2021
d785995
asserter updates (#34)
mihaj Nov 3, 2021
8304834
Merge branch 'main' into develop
mihaj Nov 3, 2021
df7891e
removed duplicate function
mihaj Nov 3, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<Project>
<PropertyGroup>
<Version>0.3.3</Version>
<Version>0.3.4</Version>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using QAToolKit.Engine.HttpTester.Exceptions;
using System;
using System.Runtime.Serialization;
using Xunit;

namespace QAToolKit.Engine.HttpTester.Test.Exceptions
Expand Down
6 changes: 2 additions & 4 deletions src/QAToolKit.Engine.HttpTester.Test/HttpTestAsserterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Xunit;

namespace QAToolKit.Engine.HttpTester.Test
{
{
public class HttpTestAsserterTests
{
[Fact]
Expand Down Expand Up @@ -120,7 +118,7 @@ public async Task HttpTestAsserterHeaderMissing_Fails()
var httpDuration = client.HttpDuration;
Assert.Throws<ArgumentNullException>(() => asserter
.ResponseContentContains("scott")
.RequestDurationEquals(duration, (x) => x < 2000)
.RequestDurationEquals(duration, (x) => x < Convert.ToInt64("2000"), "x < 2000")
.RequestDurationEquals(httpDuration, (x) => x < 1800)
.ResponseStatusCodeEquals(HttpStatusCode.OK)
.ResponseContentTypeEquals("application/json")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Runtime.Serialization;

namespace QAToolKit.Engine.HttpTester.Exceptions
{
Expand Down
99 changes: 70 additions & 29 deletions src/QAToolKit.Engine.HttpTester/HttpTestAsserter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using QAToolKit.Engine.HttpTester.Models;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
Expand All @@ -24,7 +25,8 @@ public class HttpTestAsserter : IHttpTestAsserter
/// <param name="httpResponseMessage"></param>
public HttpTestAsserter(HttpResponseMessage httpResponseMessage)
{
_httpResponseMessage = httpResponseMessage ?? throw new ArgumentNullException($"{nameof(httpResponseMessage)} is null.");
_httpResponseMessage = httpResponseMessage ??
throw new ArgumentNullException($"{nameof(httpResponseMessage)} is null.");
_assertResults = new List<AssertResult>();
}

Expand All @@ -40,8 +42,8 @@ public IEnumerable<AssertResult> AssertAll()
/// <summary>
/// HTTP body contains a string (ignores case)
/// </summary>
/// <param name="keyword"></param>
/// <param name="caseInsensitive"></param>
/// <param name="keyword">Check if the HTTP response body contains a keyword.</param>
/// <param name="caseInsensitive">Use case sensitive string comparison.</param>
/// <returns></returns>
public IHttpTestAsserter ResponseContentContains(string keyword, bool caseInsensitive = true)
{
Expand All @@ -52,20 +54,27 @@ public IHttpTestAsserter ResponseContentContains(string keyword, bool caseInsens

var bodyString = _httpResponseMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult();

_assertResults.Add(new AssertResult()
var assertResult = new AssertResult()
{
Name = nameof(ResponseContentContains),
Message = $"Body contains '{keyword}'.",
IsTrue = caseInsensitive ? StringHelper.ContainsCaseInsensitive(bodyString, keyword) : bodyString.Contains(keyword)
});
Name = nameof(ResponseContentContains)
};

assertResult.IsTrue = caseInsensitive
? StringHelper.ContainsCaseInsensitive(bodyString, keyword)
: bodyString.Contains(keyword);
assertResult.Message = assertResult.IsTrue
? $"Response body contains keyword '{keyword}'."
: $"Response body does not contain keyword '{keyword}'.";

_assertResults.Add(assertResult);

return this;
}

/// <summary>
/// Check if the response contains specified Content Type
/// </summary>
/// <param name="contentType"></param>
/// <param name="contentType">Check if the response content type equals the parameter.</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public IHttpTestAsserter ResponseContentTypeEquals(string contentType)
Expand All @@ -75,12 +84,12 @@ public IHttpTestAsserter ResponseContentTypeEquals(string contentType)
throw new ArgumentNullException($"{nameof(contentType)} is null.");
}

var bodyString = _httpResponseMessage.Content.Headers.ContentType;
var responseContentType = _httpResponseMessage.Content.Headers.ContentType.MediaType;

_assertResults.Add(new AssertResult()
{
Name = nameof(ResponseContentTypeEquals),
Message = $"Response content-type equals '{contentType}'.",
Message = $"Expected content-type = '{contentType}', actual = '{responseContentType}'.",
IsTrue = _httpResponseMessage.Content.Headers.ContentType.MediaType == contentType
});

Expand All @@ -90,26 +99,52 @@ public IHttpTestAsserter ResponseContentTypeEquals(string contentType)
/// <summary>
/// Verify request duration
/// </summary>
/// <param name="duration"></param>
/// <param name="predicateFunction"></param>
/// <param name="duration">Actual duration of the HTTP request execution</param>
/// <param name="predicateFunction">It's a function that validates the duration</param>
/// <param name="predicateFunctionExpression">String predicateFunctionExpression for the report. If set it will be used in the assert result message.</param>
/// <returns></returns>
public IHttpTestAsserter RequestDurationEquals(long duration, Func<long, bool> predicateFunction)
public IHttpTestAsserter RequestDurationEquals(long duration, Expression<Func<long, bool>> predicateFunction, string predicateFunctionExpression = null)
{
var isTrue = predicateFunction.Invoke(duration);
_assertResults.Add(new AssertResult()
var isTrue = predicateFunction.Compile()(duration);

var assertResult = new AssertResult()
{
Name = nameof(RequestDurationEquals),
Message = $"Duration is '{duration}'.",
IsTrue = isTrue
});
};

if (isTrue)
{
if (string.IsNullOrEmpty(predicateFunctionExpression))
{
assertResult.Message = $"Duration is '{duration}ms' and is valid.";
}
else
{
assertResult.Message = $"Duration is '{duration}ms' and is valid with predicateFunctionExpression '{predicateFunctionExpression}'.";
}
}
else
{
if (string.IsNullOrEmpty(predicateFunctionExpression))
{
assertResult.Message = $"Duration is '{duration}ms' and is invalid.";
}
else
{
assertResult.Message = $"Duration is '{duration}ms' and is invalid with predicateFunctionExpression '{predicateFunctionExpression}'.";
}
}

_assertResults.Add(assertResult);

return this;
}

/// <summary>
/// HTTP response contains a header
/// </summary>
/// <param name="headerName"></param>
/// <param name="headerName">Check if the HTTP response contains the header with the name.</param>
/// <returns></returns>
public IHttpTestAsserter ResponseHasHttpHeader(string headerName)
{
Expand All @@ -118,27 +153,33 @@ public IHttpTestAsserter ResponseHasHttpHeader(string headerName)
throw new ArgumentNullException($"{nameof(headerName)} is null.");
}

_assertResults.Add(new AssertResult()
var assertResult = new AssertResult
{
Name = nameof(ResponseHasHttpHeader),
Message = $"Contains header '{headerName}'.",
IsTrue = _httpResponseMessage.Headers.TryGetValues(headerName, out var values)
});
};

assertResult.Message = assertResult.IsTrue
? $"Response message contains header '{headerName}'."
: $"Response message does not contain header '{headerName}'.";

_assertResults.Add(assertResult);

return this;
}

/// <summary>
/// Verify if response code equals
/// </summary>
/// <param name="httpStatusCode"></param>
/// <param name="httpStatusCode">Check if the HTTP response status code equals to this parameter.</param>
/// <returns></returns>
public IHttpTestAsserter ResponseStatusCodeEquals(HttpStatusCode httpStatusCode)
{
_assertResults.Add(new AssertResult()
{
Name = nameof(ResponseStatusCodeEquals),
Message = $"Expected status code is '{httpStatusCode}' return code is '{_httpResponseMessage.StatusCode}'.",
Message =
$"Expected status code = '{httpStatusCode}', actual = '{_httpResponseMessage.StatusCode}'.",
IsTrue = _httpResponseMessage.StatusCode == httpStatusCode
});

Expand All @@ -154,7 +195,7 @@ public IHttpTestAsserter ResponseStatusCodeIsSuccess()
_assertResults.Add(new AssertResult()
{
Name = nameof(ResponseStatusCodeIsSuccess),
Message = $"Expected status code is '2xx' return code is '{_httpResponseMessage.StatusCode}'.",
Message = $"Expected status code = '2xx', actual = '{_httpResponseMessage.StatusCode}'.",
IsTrue = _httpResponseMessage.IsSuccessStatusCode
});

Expand All @@ -172,11 +213,11 @@ public IHttpTestAsserter ResponseBodyIsEmpty()
_assertResults.Add(new AssertResult()
{
Name = nameof(ResponseBodyIsEmpty),
Message = $"Expected empty body, returned body is '{bodyString}'.",
Message = $"Expected empty response body, actual = '{bodyString}'.",
IsTrue = string.IsNullOrEmpty(bodyString)
});

return this;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using QAToolKit.Engine.HttpTester.Models;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Net;
using System.Net.Http.Headers;

Expand All @@ -18,13 +19,15 @@ public interface IHttpTestAsserter
/// <param name="caseInsensitive"></param>
/// <returns></returns>
IHttpTestAsserter ResponseContentContains(string keyword, bool caseInsensitive = true);

/// <summary>
/// Verify request duration
/// </summary>
/// <param name="duration"></param>
/// <param name="predicateFunction"></param>
/// <param name="predicateFunctionExpression"></param>
/// <returns></returns>
IHttpTestAsserter RequestDurationEquals(long duration, Func<long, bool> predicateFunction);
IHttpTestAsserter RequestDurationEquals(long duration, Expression<Func<long, bool>> predicateFunction, string predicateFunctionExpression = null);
/// <summary>
/// Verify if response code equals
/// </summary>
Expand Down