407 lines
16 KiB
C#
407 lines
16 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using System.Net.Http;
|
|
using System.Net.Http.Headers;
|
|
using Newtonsoft.Json.Linq;
|
|
using FluentAssertions;
|
|
using System.Collections.Concurrent;
|
|
|
|
namespace raven_integration
|
|
{
|
|
public static class Util
|
|
{
|
|
public const string OpEquality = "=";
|
|
public const string OpGreaterThan = ">";
|
|
public const string OpGreaterThanOrEqualTo = ">=";
|
|
public const string OpLessThan = "<";
|
|
public const string OpLessThanOrEqualTo = "<=";
|
|
public const string OpNotEqual = "!=";
|
|
public const string OpNotLike = "!%";
|
|
public const string OpStartsWith = "%-";
|
|
public const string OpEndsWith = "-%";
|
|
public const string OpContains = "-%-";
|
|
public const string OpNotContains = "!-%-";
|
|
|
|
private static HttpClient client { get; } = new HttpClient();
|
|
|
|
private static string API_BASE_URL = "http://localhost:7575/api/v8.0/";
|
|
//private static string API_BASE_URL = "https://test.helloayanova.com/api/v8.0/";
|
|
|
|
public static string TEST_DATA_FOLDER = @"..\..\..\testdata\";
|
|
|
|
public static ConcurrentDictionary<string, string> authDict = new ConcurrentDictionary<string, string>();//10,32
|
|
|
|
private static AutoId Auto { get; } = new AutoId(0);
|
|
|
|
public static string Uniquify(string s)
|
|
{
|
|
// return s + " " + Auto.GetNext().ToString();
|
|
return s + " " + (Auto.GetNext() + ((DateTimeOffset)DateTime.Now).ToUnixTimeMilliseconds()).ToString();
|
|
}
|
|
|
|
public async static Task<string> GetTokenAsync(string login, string password = null)
|
|
{
|
|
// Console.WriteLine($"GetTokenAsync:{login}");
|
|
//System.Diagnostics.Trace.WriteLine($"GetTokenAsync:{login}");
|
|
|
|
if (password == null)
|
|
password = login;
|
|
|
|
if (!authDict.ContainsKey(login))
|
|
{
|
|
dynamic creds = new JObject();
|
|
creds.login = login;
|
|
creds.password = password;
|
|
|
|
ApiResponse a = await Util.PostAsync("Auth", null, creds.ToString());
|
|
//Put this in when having concurrency issue during auth and old style dl token creation during login
|
|
ValidateDataReturnResponseOk(a);
|
|
|
|
authDict[login] = a.ObjectResponse["data"]["token"].Value<string>();
|
|
}
|
|
return authDict[login];
|
|
}
|
|
|
|
|
|
|
|
static bool bInitialized = false;
|
|
private static void init()
|
|
{
|
|
if (bInitialized) return;
|
|
if (!System.IO.Directory.Exists(TEST_DATA_FOLDER))
|
|
throw new ArgumentOutOfRangeException($"Test data folder {TEST_DATA_FOLDER} not found, current folder is {System.AppDomain.CurrentDomain.BaseDirectory}");
|
|
|
|
client.DefaultRequestHeaders.Accept.Clear();
|
|
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
|
bInitialized = true;
|
|
}
|
|
|
|
public static string CleanApiRoute(string route)
|
|
{
|
|
route = route.TrimStart('/');
|
|
return API_BASE_URL + route;
|
|
}
|
|
|
|
public async static Task<ApiResponse> GetAsync(string route, string authToken = null, string bodyJsonData = null)
|
|
{
|
|
init();
|
|
|
|
var requestMessage = new HttpRequestMessage(HttpMethod.Get, CleanApiRoute(route));
|
|
if (!string.IsNullOrWhiteSpace(authToken))
|
|
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
|
|
|
if (!string.IsNullOrWhiteSpace(bodyJsonData))
|
|
requestMessage.Content = new StringContent(bodyJsonData, System.Text.Encoding.UTF8, "application/json");
|
|
|
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
|
var responseAsString = await response.Content.ReadAsStringAsync();
|
|
|
|
return new ApiResponse() { HttpResponse = response, ObjectResponse = Parse(responseAsString) };
|
|
}
|
|
|
|
|
|
public async static Task<ApiTextResponse> GetTextResultAsync(string route, string authToken = null, string bodyJsonData = null)
|
|
{
|
|
init();
|
|
|
|
var requestMessage = new HttpRequestMessage(HttpMethod.Get, CleanApiRoute(route));
|
|
if (!string.IsNullOrWhiteSpace(authToken))
|
|
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
|
|
|
if (!string.IsNullOrWhiteSpace(bodyJsonData))
|
|
requestMessage.Content = new StringContent(bodyJsonData, System.Text.Encoding.UTF8, "application/json");
|
|
|
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
|
var responseAsString = await response.Content.ReadAsStringAsync();
|
|
|
|
return new ApiTextResponse() { HttpResponse = response, TextResponse = responseAsString };
|
|
}
|
|
|
|
public static async Task<HttpResponseMessage> DownloadFileAsync(string route, string authToken = null)
|
|
{
|
|
|
|
init();
|
|
var requestMessage = new HttpRequestMessage(HttpMethod.Get, CleanApiRoute(route));
|
|
if (!string.IsNullOrWhiteSpace(authToken))
|
|
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
|
|
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
|
return response;
|
|
// if (response.IsSuccessStatusCode)
|
|
// {
|
|
// return await response.Content.ReadAsByteArrayAsync();
|
|
// }
|
|
|
|
// return null;
|
|
}
|
|
|
|
|
|
public async static Task<ApiResponse> PostAsync(string route, string authToken = null, string postJson = null)
|
|
{
|
|
init();
|
|
|
|
var requestMessage = new HttpRequestMessage(HttpMethod.Post, CleanApiRoute(route));
|
|
if (!string.IsNullOrWhiteSpace(authToken))
|
|
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
|
|
|
if (!string.IsNullOrWhiteSpace(postJson))
|
|
requestMessage.Content = new StringContent(postJson, System.Text.Encoding.UTF8, "application/json");
|
|
|
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
|
var responseAsString = await response.Content.ReadAsStringAsync();
|
|
|
|
return new ApiResponse() { HttpResponse = response, ObjectResponse = Parse(responseAsString) };
|
|
}
|
|
|
|
public async static Task<ApiResponse> PostFormDataAsync(string route, MultipartFormDataContent formContent, string authToken = null)
|
|
{
|
|
init();
|
|
|
|
var requestMessage = new HttpRequestMessage(HttpMethod.Post, CleanApiRoute(route));
|
|
if (!string.IsNullOrWhiteSpace(authToken))
|
|
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
|
|
|
requestMessage.Content = formContent;
|
|
|
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
|
var responseAsString = await response.Content.ReadAsStringAsync();
|
|
|
|
return new ApiResponse() { HttpResponse = response, ObjectResponse = Parse(responseAsString) };
|
|
}
|
|
|
|
|
|
public async static Task<ApiResponse> PutAsync(string route, string authToken = null, string putJson = null)
|
|
{
|
|
init();
|
|
|
|
var requestMessage = new HttpRequestMessage(HttpMethod.Put, CleanApiRoute(route));
|
|
if (!string.IsNullOrWhiteSpace(authToken))
|
|
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
|
|
|
if (!string.IsNullOrWhiteSpace(putJson))
|
|
requestMessage.Content = new StringContent(putJson, System.Text.Encoding.UTF8, "application/json");
|
|
|
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
|
var responseAsString = await response.Content.ReadAsStringAsync();
|
|
|
|
return new ApiResponse() { HttpResponse = response, ObjectResponse = Parse(responseAsString) };
|
|
}
|
|
|
|
|
|
public async static Task<ApiResponse> PatchAsync(string route, string authToken = null, string patchJson = null)
|
|
{
|
|
init();
|
|
|
|
var method = new HttpMethod("PATCH");
|
|
|
|
var requestMessage = new HttpRequestMessage(method, CleanApiRoute(route));
|
|
if (!string.IsNullOrWhiteSpace(authToken))
|
|
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
|
|
|
if (!string.IsNullOrWhiteSpace(patchJson))
|
|
requestMessage.Content = new StringContent(patchJson, System.Text.Encoding.UTF8, "application/json-patch+json");
|
|
|
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
|
var responseAsString = await response.Content.ReadAsStringAsync();
|
|
|
|
return new ApiResponse() { HttpResponse = response, ObjectResponse = Parse(responseAsString) };
|
|
}
|
|
|
|
|
|
public async static Task<ApiResponse> DeleteAsync(string route, string authToken = null)
|
|
{
|
|
init();
|
|
|
|
var requestMessage = new HttpRequestMessage(HttpMethod.Delete, CleanApiRoute(route));
|
|
if (!string.IsNullOrWhiteSpace(authToken))
|
|
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
|
|
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
|
var responseAsString = await response.Content.ReadAsStringAsync();
|
|
|
|
return new ApiResponse() { HttpResponse = response, ObjectResponse = Parse(responseAsString) };
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="jsonString"></param>
|
|
/// <returns></returns>
|
|
private static JObject Parse(string jsonString)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(jsonString))
|
|
{
|
|
return null;
|
|
}
|
|
return JObject.Parse(jsonString);
|
|
}
|
|
|
|
//https://www.newtonsoft.com/json/help/html/FromObject.htm
|
|
private static string ObjectToJsonString(object o)
|
|
{
|
|
JObject j = (JObject)JToken.FromObject(o);
|
|
return j.ToString();
|
|
}
|
|
|
|
public static void ValidateDataReturnResponseOk(ApiResponse a)
|
|
{
|
|
a.ObjectResponse.Should().NotBeNull("No response was found at all?! Nothing to validate");
|
|
|
|
var ErrorMessage = string.Empty;
|
|
var ERR = a.ObjectResponse["error"];
|
|
if (ERR != null)
|
|
{
|
|
var ecode = ERR["code"];
|
|
if (ecode != null)
|
|
ErrorMessage += $"CODE: {ecode} ";
|
|
|
|
var emsg = ERR["message"];
|
|
if (emsg != null)
|
|
ErrorMessage += $"MESSAGE: {emsg} ";
|
|
|
|
var etarget = ERR["target"];
|
|
if (etarget != null)
|
|
ErrorMessage += $"TARGET: {etarget} ";
|
|
}
|
|
|
|
a.ObjectResponse["error"].Should().BeNull("because there should not be an error on an api call, error was: {0}", ErrorMessage);
|
|
a.ObjectResponse["data"].Should().NotBeNull("A result should be returned");
|
|
}
|
|
|
|
public static void ValidateNoErrorInResponse(ApiResponse a)
|
|
{
|
|
a.ObjectResponse["error"].Should().BeNull("There should not be an error on an api call");
|
|
}
|
|
|
|
public static void ValidateHTTPStatusCode(ApiResponse a, int DesiredStatusCode)
|
|
{
|
|
((int)a.HttpResponse.StatusCode).Should().Be(DesiredStatusCode);
|
|
}
|
|
|
|
public static void ValidateHTTPStatusCode(ApiTextResponse t, int DesiredStatusCode)
|
|
{
|
|
((int)t.HttpResponse.StatusCode).Should().Be(DesiredStatusCode);
|
|
}
|
|
|
|
/// <summary>
|
|
/// validate a not found response
|
|
/// </summary>
|
|
/// <param name="a"></param>
|
|
public static void ValidateResponseNotFound(ApiResponse a)
|
|
{
|
|
((int)a.HttpResponse.StatusCode).Should().Be(404);
|
|
a.ObjectResponse["error"].Should().NotBeNull("There should be an error on the api call");
|
|
a.ObjectResponse["error"]["code"].Value<int>().Should().Be(2010);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// validate a concurrency error
|
|
/// </summary>
|
|
/// <param name="a"></param>
|
|
public static void ValidateConcurrencyError(ApiResponse a)
|
|
{
|
|
((int)a.HttpResponse.StatusCode).Should().Be(409);
|
|
a.ObjectResponse["error"].Should().NotBeNull("There should be an error on the api call");
|
|
a.ObjectResponse["error"]["code"].Value<int>().Should().Be(2005);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// validate that the call violates referential integrity
|
|
/// </summary>
|
|
/// <param name="a"></param>
|
|
public static void ValidateViolatesReferentialIntegrityError(ApiResponse a)
|
|
{
|
|
((int)a.HttpResponse.StatusCode).Should().Be(400);
|
|
a.ObjectResponse["error"].Should().NotBeNull("There should be an error on the api call");
|
|
a.ObjectResponse["error"]["code"].Value<int>().Should().Be(2200);
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// validate a bad ModelState response
|
|
/// </summary>
|
|
/// <param name="a"></param>
|
|
public static void ValidateBadModelStateResponse(ApiResponse a, string CheckFirstTargetExists = null)
|
|
{
|
|
((int)a.HttpResponse.StatusCode).Should().Be(400);
|
|
a.ObjectResponse["error"].Should().NotBeNull("There should be an error on the api call");
|
|
a.ObjectResponse["error"]["code"].Value<int>().Should().Be(2200);
|
|
a.ObjectResponse["error"]["details"].Should().NotBeNull("There should be error details on the api call");
|
|
if (!string.IsNullOrWhiteSpace(CheckFirstTargetExists))
|
|
{
|
|
a.ObjectResponse["error"]["details"][0]["target"].Value<string>().Should().Be(CheckFirstTargetExists);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
// public enum ValidationErrorType
|
|
// {
|
|
// RequiredPropertyEmpty = 1,
|
|
// LengthExceeded = 2,
|
|
// NotUnique = 3,
|
|
// StartDateMustComeBeforeEndDate = 4,
|
|
// InvalidValue = 5
|
|
|
|
// }
|
|
|
|
/// <summary>
|
|
/// assert contains validation target and error code
|
|
/// </summary>
|
|
/// <param name="a"></param>
|
|
/// <param name="target"></param>
|
|
/// <param name="error"></param>
|
|
public static void ShouldContainValidationError(ApiResponse a, string target, string error, string message = null)
|
|
{
|
|
a.ObjectResponse["error"]["details"].Should().NotBeNull("There should be Details on the api call");
|
|
if (message != null)
|
|
{
|
|
a.ObjectResponse["error"]["details"].Should().Contain(
|
|
m => m["target"].Value<string>() == target &&
|
|
m["error"].Value<string>() == error &&
|
|
m["message"].Value<string>() == message);
|
|
}
|
|
else
|
|
{
|
|
a.ObjectResponse["error"]["details"].Should().Contain(m => m["target"].Value<string>() == target && m["error"].Value<string>() == error);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// validate server exception response
|
|
/// </summary>
|
|
/// <param name="a"></param>
|
|
public static void ValidateServerExceptionResponse(ApiResponse a)
|
|
{
|
|
((int)a.HttpResponse.StatusCode).Should().Be(500);
|
|
a.ObjectResponse["error"].Should().NotBeNull("There should be an error on the api call");
|
|
a.ObjectResponse["error"]["code"].Value<int>().Should().Be(2002);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Validate an expected api error code and http code response
|
|
/// </summary>
|
|
/// <param name="a"></param>
|
|
/// <param name="apiErrorCode"></param>
|
|
/// <param name="httpStatusCode"></param>
|
|
public static void ValidateErrorCodeResponse(ApiResponse a, int apiErrorCode, int httpStatusCode)
|
|
{
|
|
((int)a.HttpResponse.StatusCode).Should().Be(httpStatusCode);
|
|
a.ObjectResponse["error"].Should().NotBeNull("There should be an error on the api call");
|
|
a.ObjectResponse["error"]["code"].Value<int>().Should().Be(apiErrorCode);
|
|
}
|
|
|
|
|
|
|
|
|
|
}//eoc
|
|
}//eons
|