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(); public static string API_BASE_URL = "http://localhost:7575/api/v8.0/"; //public static string API_BASE_URL = "https://test.helloayanova.com/api/v8.0/"; public static string TEST_DATA_FOLDER = @"..\..\..\testdata\"; public static ConcurrentDictionary authDict = new ConcurrentDictionary();//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 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(); } 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 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 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 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 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 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 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 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 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) }; } /// /// /// /// /// 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) { ErrorMessage=a.ObjectResponse.ToString(); // 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 result 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); } /// /// validate a not found response /// /// 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().Should().Be(2010); } /// /// validate a concurrency error /// /// 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().Should().Be(2005); } /// /// validate that the call violates referential integrity /// /// 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().Should().Be(2200); } /// /// validate a bad ModelState response /// /// 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().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().Should().Be(CheckFirstTargetExists); } } // public enum ValidationErrorType // { // RequiredPropertyEmpty = 1, // LengthExceeded = 2, // NotUnique = 3, // StartDateMustComeBeforeEndDate = 4, // InvalidValue = 5 // } /// /// assert contains validation target and error code /// /// /// /// 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() == target && m["error"].Value() == error && m["message"].Value() == message); } else { a.ObjectResponse["error"]["details"].Should().Contain(m => m["target"].Value() == target && m["error"].Value() == error); } } /// /// validate server exception response /// /// 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().Should().Be(2002); } /// /// Validate an expected api error code and http code response /// /// /// /// 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().Should().Be(apiErrorCode); } public static string GenerateCustomFieldsJsonString( string c1 = null, string c2 = null, string c3 = null, string c4 = null, string c5 = null, string c6 = null, string c7 = null, string c8 = null, string c9 = null, string c10 = null, string c11 = null, string c12 = null, string c13 = null, string c14 = null, string c15 = null, string c16 = null ) { //Custom fields //"[{c1:"blah"}] dynamic dCustomField = new JObject(); dCustomField.c1 = c1; dCustomField.c2 = c2; dCustomField.c3 = c3; dCustomField.c4 = c4; dCustomField.c5 = c5; dCustomField.c6 = c6; dCustomField.c7 = c7; dCustomField.c8 = c8; dCustomField.c9 = c9; dCustomField.c10 = c10; dCustomField.c11 = c11; dCustomField.c12 = c12; dCustomField.c13 = c13; dCustomField.c14 = c14; dCustomField.c15 = c15; dCustomField.c16 = c16; return dCustomField.ToString(); } }//eoc }//eons