diff --git a/Directory.Build.props b/Directory.Build.props
index abb452e..eee5155 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,5 +1,5 @@
- 0.2.9
+ 0.2.11
\ No newline at end of file
diff --git a/src/QAToolKit.Engine.HttpTester.Test/Fixtures/BicycleFixture.cs b/src/QAToolKit.Engine.HttpTester.Test/Fixtures/BicycleFixture.cs
index 671dccf..a044426 100644
--- a/src/QAToolKit.Engine.HttpTester.Test/Fixtures/BicycleFixture.cs
+++ b/src/QAToolKit.Engine.HttpTester.Test/Fixtures/BicycleFixture.cs
@@ -15,6 +15,31 @@ public static Bicycle Get()
};
}
+ public static Bicycle GetCannondale()
+ {
+ return new Bicycle
+ {
+ Id = 2,
+ Name = "CAADX",
+ Brand = "Cannondale",
+ Type = BicycleType.Gravel
+ };
+ }
+
+ public static List GetCannondaleArray()
+ {
+ return new List()
+ {
+ new Bicycle()
+ {
+ Id = 2,
+ Name = "CAADX",
+ Brand = "Cannondale",
+ Type = BicycleType.Gravel
+ }
+ };
+ }
+
public static Bicycle GetFoil()
{
return new Bicycle
diff --git a/src/QAToolKit.Engine.HttpTester.Test/HttpTestAsserterTests.cs b/src/QAToolKit.Engine.HttpTester.Test/HttpTestAsserterTests.cs
index b52d28b..9b08823 100644
--- a/src/QAToolKit.Engine.HttpTester.Test/HttpTestAsserterTests.cs
+++ b/src/QAToolKit.Engine.HttpTester.Test/HttpTestAsserterTests.cs
@@ -31,7 +31,7 @@ public async Task HttpTestAsserterSimple_Success()
var duration = client.Duration;
var assertResults = asserter
.ResponseContentContains("scott")
- .RequestDurationEquals(duration, (x) => x < 1000)
+ .RequestDurationEquals(duration, (x) => x < 2000)
.ResponseStatusCodeEquals(HttpStatusCode.OK)
.ResponseHasHttpHeader("Date")
.AssertAll();
@@ -116,7 +116,7 @@ public async Task HttpTestAsserterHeaderMissing_Fails()
var duration = client.Duration;
Assert.Throws(() => asserter
.ResponseContentContains("scott")
- .RequestDurationEquals(duration, (x) => x < 1000)
+ .RequestDurationEquals(duration, (x) => x < 2000)
.ResponseStatusCodeEquals(HttpStatusCode.OK)
.ResponseHasHttpHeader(null)
.AssertAll());
diff --git a/src/QAToolKit.Engine.HttpTester.Test/HttpTesterClientTests.cs b/src/QAToolKit.Engine.HttpTester.Test/HttpTesterClientTests.cs
index c53b0ad..0b59a8f 100644
--- a/src/QAToolKit.Engine.HttpTester.Test/HttpTesterClientTests.cs
+++ b/src/QAToolKit.Engine.HttpTester.Test/HttpTesterClientTests.cs
@@ -548,7 +548,7 @@ public void HttpTesterClientBrochureUploadMultipartPresent_Fails()
.WithMultipart("Metadata.Year", "2000")
.WithMultipart("Metadata.Name", "Brochure 2000");
- var exception = Assert.Throws(() => client.WithJsonBody("1234"));
+ var exception = Assert.Throws(() => client.WithJsonBody("1234"));
Assert.StartsWith("Body multipart/form-data already defined", exception.Message);
}
}
@@ -617,5 +617,74 @@ public async Task HttpTesterClientAddGetHttpRequest_Success()
Assert.True(response.IsSuccessStatusCode);
}
}
+
+ [Fact]
+ public async Task HttpTesterClientGetBikeByIdRequest_Success()
+ {
+ var urlSource = new SwaggerUrlSource(options =>
+ {
+ options.AddBaseUrl(new Uri("https://qatoolkitapi.azurewebsites.net/"));
+ options.AddRequestFilters(new RequestFilter()
+ {
+ EndpointNameWhitelist = new string[] { "GetBike" }
+ });
+ options.UseSwaggerExampleValues = true;
+ });
+
+ var requests = await urlSource.Load(new Uri[] {
+ new Uri("https://qatoolkitapi.azurewebsites.net/swagger/v2/swagger.json")
+ });
+
+ using (var client = new HttpTesterClient())
+ {
+ var response = await client
+ .CreateHttpRequest(requests.FirstOrDefault())
+ .WithPathReplacementValues(new Dictionary() { { "id", "2" } })
+ .WithQueryParams(new Dictionary() { { "api-version", "2" } })
+ .Start();
+
+ var msg = await response.GetResponseBody();
+
+ var expecterResponse = BicycleFixture.GetCannondale().ToExpectedObject();
+ expecterResponse.ShouldEqual(msg);
+
+ Assert.True(client.Duration < 2000);
+ Assert.True(response.IsSuccessStatusCode);
+ }
+ }
+
+ [Fact]
+ public async Task HttpTesterClientGetBikesByTypeHttpRequest_Success()
+ {
+ var urlSource = new SwaggerUrlSource(options =>
+ {
+ options.AddBaseUrl(new Uri("https://qatoolkitapi.azurewebsites.net/"));
+ options.AddRequestFilters(new RequestFilter()
+ {
+ EndpointNameWhitelist = new string[] { "GetAllBikes" }
+ });
+ options.UseSwaggerExampleValues = true;
+ });
+
+ var requests = await urlSource.Load(new Uri[] {
+ new Uri("https://qatoolkitapi.azurewebsites.net/swagger/v2/swagger.json")
+ });
+
+ using (var client = new HttpTesterClient())
+ {
+ var response = await client
+ .CreateHttpRequest(requests.FirstOrDefault())
+ .WithQueryParams(new Dictionary() { { "api-version", "2" }, {"bicycleType", "1" } })
+ .Start();
+
+ var msg = await response.GetResponseBody>();
+
+ var expecterResponse = BicycleFixture.GetCannondaleArray().ToExpectedObject();
+ expecterResponse.ShouldEqual(msg);
+
+ Assert.True(client.Duration < 2000);
+ Assert.True(response.IsSuccessStatusCode);
+ }
+ }
}
}
diff --git a/src/QAToolKit.Engine.HttpTester/HttpTestAsserter.cs b/src/QAToolKit.Engine.HttpTester/HttpTestAsserter.cs
index 21dae33..6564097 100644
--- a/src/QAToolKit.Engine.HttpTester/HttpTestAsserter.cs
+++ b/src/QAToolKit.Engine.HttpTester/HttpTestAsserter.cs
@@ -3,7 +3,6 @@
using QAToolKit.Engine.HttpTester.Models;
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Net;
using System.Net.Http;
@@ -97,7 +96,7 @@ public IHttpTestAsserter ResponseHasHttpHeader(string headerName)
Name = nameof(ResponseHasHttpHeader),
Message = $"Contains header '{headerName}'.",
IsTrue = _httpResponseMessage.Headers.TryGetValues(headerName, out var values)
- });
+ });
return this;
}
diff --git a/src/QAToolKit.Engine.HttpTester/HttpTesterClient.cs b/src/QAToolKit.Engine.HttpTester/HttpTesterClient.cs
index 0c0b729..b2f305d 100644
--- a/src/QAToolKit.Engine.HttpTester/HttpTesterClient.cs
+++ b/src/QAToolKit.Engine.HttpTester/HttpTesterClient.cs
@@ -5,7 +5,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
@@ -67,6 +66,69 @@ public IHttpTesterClient CreateHttpRequest(Uri baseAddress, bool validateCertifi
return this;
}
+ ///
+ /// Create a HTTP tester client from QAToolKit HttpRequest object
+ ///
+ /// Create tester client with BaseUrl, Path, HttpMethod, Headers and URL Query paramteres read from HttpRequest object. Specify other values and parameters manually.
+ ///
+ ///
+ public IHttpTesterClient CreateHttpRequest(HttpRequest httpRequest, bool validateCertificate = true)
+ {
+ if (httpRequest == null)
+ throw new QAToolKitEngineHttpTesterException("'HttpRequest' is null. Pass in the valid object.");
+ if (HttpClient != null)
+ throw new QAToolKitEngineHttpTesterException("HttpClient is already instantiated. Create new 'HttpTesterClient'.");
+
+ var baseAddress = new Uri(httpRequest.BasePath);
+
+ HttpHandler = new HttpClientHandler();
+
+ if (!validateCertificate &&
+ (baseAddress.Scheme == Uri.UriSchemeHttp || baseAddress.Scheme == Uri.UriSchemeHttps))
+ {
+ HttpHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
+ HttpHandler.ServerCertificateCustomValidationCallback =
+ (httpRequestMessage, cert, cetChain, policyErrors) =>
+ {
+ return true;
+ };
+ }
+
+ HttpClient = new HttpClient(HttpHandler)
+ {
+ BaseAddress = baseAddress
+ };
+
+ if (string.IsNullOrEmpty(httpRequest.Path))
+ {
+ throw new QAToolKitEngineHttpTesterException("HttpRequest Path is required.");
+ }
+
+ _path = httpRequest.Path;
+
+ _httpMethod = httpRequest.Method;
+
+ //Query parameters
+ if (_queryParameters == null)
+ _queryParameters = new Dictionary();
+
+ foreach (var parameter in httpRequest.Parameters.Where(t => t.Location == Location.Query && t.Value != null))
+ {
+ _queryParameters.Add(parameter.Name, parameter.Value);
+ }
+
+ //Headers
+ if (_headers == null)
+ _headers = new Dictionary();
+
+ foreach (var header in httpRequest.Parameters.Where(t => t.Location == Location.Header && t.Value != null))
+ {
+ _headers.Add(header.Name, header.Value);
+ }
+
+ return this;
+ }
+
///
/// Add URL path to the HTTP client
///
@@ -74,11 +136,35 @@ public IHttpTesterClient CreateHttpRequest(Uri baseAddress, bool validateCertifi
///
public IHttpTesterClient WithPath(string urlPath)
{
+ if (urlPath == null)
+ throw new ArgumentException($"{nameof(urlPath)} is null.");
+
_path = urlPath;
return this;
}
+ ///
+ /// Replace URL path with path parametrs from passed dictionary
+ ///
+ ///
+ ///
+ public IHttpTesterClient WithPathReplacementValues(Dictionary pathParameters)
+ {
+ if (pathParameters == null)
+ throw new ArgumentException($"{nameof(pathParameters)} is null.");
+
+ if (string.IsNullOrEmpty(_path))
+ throw new QAToolKitEngineHttpTesterException("Uri Path is empty. Use 'WithPath' before calling 'WithPathReplacementValues'.");
+
+ foreach (var parameter in pathParameters)
+ {
+ _path = _path.Replace($"{{{parameter.Key}}}", parameter.Value);
+ }
+
+ return this;
+ }
+
///
/// Add HTTP headers to the HTTP client
///
@@ -86,6 +172,9 @@ public IHttpTesterClient WithPath(string urlPath)
///
public IHttpTesterClient WithHeaders(Dictionary headers)
{
+ if (headers == null)
+ throw new ArgumentException($"{nameof(headers)} is null.");
+
_headers = headers;
return this;
@@ -126,6 +215,9 @@ public IHttpTesterClient WithJsonBody(T bodyObject)
///
public IHttpTesterClient WithMethod(HttpMethod httpMethod)
{
+ if (httpMethod == null)
+ throw new ArgumentException($"{nameof(httpMethod)} is null.");
+
_httpMethod = httpMethod;
return this;
@@ -138,6 +230,9 @@ public IHttpTesterClient WithMethod(HttpMethod httpMethod)
///
public IHttpTesterClient WithQueryParams(Dictionary queryParameters)
{
+ if (queryParameters == null)
+ throw new ArgumentException($"{nameof(queryParameters)} is null.");
+
_queryParameters = queryParameters;
return this;
@@ -151,6 +246,11 @@ public IHttpTesterClient WithQueryParams(Dictionary queryParamet
///
public IHttpTesterClient WithBasicAuthentication(string userName, string password)
{
+ if (userName == null)
+ throw new ArgumentException($"{nameof(userName)} is null.");
+ if (password == null)
+ throw new ArgumentException($"{nameof(password)} is null.");
+
var authenticationString = $"{userName}:{password}";
var base64EncodedAuthenticationString = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(authenticationString));
HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", base64EncodedAuthenticationString);
@@ -165,6 +265,9 @@ public IHttpTesterClient WithBasicAuthentication(string userName, string passwor
///
public IHttpTesterClient WithBearerAuthentication(string accessToken)
{
+ if (accessToken == null)
+ throw new ArgumentException($"{nameof(accessToken)} is null.");
+
HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
return this;
@@ -255,75 +358,6 @@ public IHttpTesterClient WithMultipart(string httpContentName, string value)
return this;
}
- ///
- /// Create a HTTP tester client from QAToolKit HttpRequest object
- ///
- /// Create tester client with BaseUrl, Path, HttpMethod, Headers and URL Query paramteres read from HttpRequest object. Specify other values and parameters manually.
- ///
- ///
- public IHttpTesterClient CreateHttpRequest(HttpRequest httpRequest, bool validateCertificate = true)
- {
- if (httpRequest == null)
- {
- throw new QAToolKitEngineHttpTesterException("'HttpRequest' is null. Pass in the valid object.");
- }
-
- if (HttpClient != null)
- {
- throw new QAToolKitEngineHttpTesterException("HttpClient is already instantiated. Create new 'HttpTesterClient'.");
- }
-
- var baseAddress = new Uri(httpRequest.BasePath);
-
- HttpHandler = new HttpClientHandler();
-
- if (!validateCertificate &&
- (baseAddress.Scheme == Uri.UriSchemeHttp || baseAddress.Scheme == Uri.UriSchemeHttps))
- {
- HttpHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
- HttpHandler.ServerCertificateCustomValidationCallback =
- (httpRequestMessage, cert, cetChain, policyErrors) =>
- {
- return true;
- };
- }
-
- HttpClient = new HttpClient(HttpHandler)
- {
- BaseAddress = baseAddress
- };
-
-
- if (string.IsNullOrEmpty(httpRequest.Path))
- {
- throw new QAToolKitEngineHttpTesterException("HttpRequest Path is required.");
- }
-
- _path = httpRequest.Path;
-
- _httpMethod = httpRequest.Method;
-
- //Query parameters
- if (_queryParameters == null)
- _queryParameters = new Dictionary();
-
- foreach (var parameter in httpRequest.Parameters.Where(t => t.Location == Location.Query && t.Value != null))
- {
- _queryParameters.Add(parameter.Name, parameter.Value);
- }
-
- //Headers
- if (_headers == null)
- _headers = new Dictionary();
-
- foreach (var header in httpRequest.Parameters.Where(t => t.Location == Location.Header && t.Value != null))
- {
- _headers.Add(header.Name, header.Value);
- }
-
- return this;
- }
-
///
/// Start the HTTP request
///
@@ -331,34 +365,29 @@ public IHttpTesterClient CreateHttpRequest(HttpRequest httpRequest, bool validat
public async Task Start()
{
if (HttpClient == null)
- {
throw new QAToolKitEngineHttpTesterException("HttpClient is null. Create an object first with 'CreateHttpRequest'.");
- }
-
if (_httpMethod == null)
- {
throw new QAToolKitEngineHttpTesterException("Define method for a HTTP request.");
- }
-
if (_httpMethod == HttpMethod.Get && _body != null)
- {
throw new QAToolKitEngineHttpTesterException("'Get' method can not have a HTTP body.");
- }
- string queryString = "";
+ StringBuilder queryString = new StringBuilder();
if (_queryParameters != null)
{
- queryString = "?";
+ queryString.Append("?");
+ List array = new List();
foreach (var query in _queryParameters)
{
- queryString += $"{query.Key}={query.Value}";
+ array.Add($"{query.Key}={query.Value}");
}
+
+ queryString.Append(string.Join("&", array));
}
var sw = new Stopwatch();
sw.Start();
- using (var requestMessage = new HttpRequestMessage(_httpMethod, _path + queryString))
+ using (var requestMessage = new HttpRequestMessage(_httpMethod, _path + queryString.ToString()))
{
if (_headers != null)
{
@@ -406,4 +435,4 @@ protected virtual void Dispose(bool disposing)
HttpHandler?.Dispose();
}
}
-}
+}
\ No newline at end of file
diff --git a/src/QAToolKit.Engine.HttpTester/Interfaces/IHttpTesterClient.cs b/src/QAToolKit.Engine.HttpTester/Interfaces/IHttpTesterClient.cs
index f59a0d3..d892500 100644
--- a/src/QAToolKit.Engine.HttpTester/Interfaces/IHttpTesterClient.cs
+++ b/src/QAToolKit.Engine.HttpTester/Interfaces/IHttpTesterClient.cs
@@ -32,6 +32,12 @@ public interface IHttpTesterClient
///
IHttpTesterClient WithPath(string urlPath);
///
+ /// Replace URL path with path parameters from passed dictionary
+ ///
+ ///
+ ///
+ IHttpTesterClient WithPathReplacementValues(Dictionary pathParameters);
+ ///
/// Add HTTP method to the HTTP client
///
///