using System; using Xunit; using Newtonsoft.Json.Linq; using FluentAssertions; using System.Collections.Generic; using System.Collections.Concurrent; namespace raven_integration { public class PickListAllTests { //NOTE: in order not to interfere in each other will use Project picklist to test with standard unmodified picklist template //and will use Customer pick-list to test the template functionality /// /// Test all Template editing related routes /// [Fact] public async Task CustomerPickListTemplatesOps() { //NOTE: Due to there being only one possible template per type, this test will need to test ALL potential tests in one function //and only for the Customer picklist in order to not step over other potential tests running in parallel //Customer by default in sample data does not include account number so add that field for this test //should not break anything else //Customer TEMPLATE //default template in eval data does not include account number // { // "id": 8, // "template": "[{\"fld\":\"customername\"},{\"fld\":\"CustomerPhone1\"},{\"fld\":\"CustomerAccountNumber\"}]" // } const int AY_OBJECT_TYPE_CUSTOMER = 8; dynamic d = new JObject(); d.Id = AY_OBJECT_TYPE_CUSTOMER;//Customer type //custom template, add customer account number dynamic dTemplateArray = new JArray(); dynamic df = new JObject(); df.fld = "customername"; dTemplateArray.Add(df); df = new JObject(); df.fld = "CustomerPhone1"; dTemplateArray.Add(df); df = new JObject(); df.fld = "CustomerAccountNumber"; dTemplateArray.Add(df); d.Template = dTemplateArray.ToString(Newtonsoft.Json.Formatting.None); //replace the Customer template at the server ApiResponse a = await Util.PostAsync("pick-list/template", await Util.GetTokenAsync("BizAdmin"), d.ToString(Newtonsoft.Json.Formatting.None)); Util.ValidateHTTPStatusCode(a, 204); //RETRIEVE //Get one a = await Util.GetAsync($"pick-list/template/{AY_OBJECT_TYPE_CUSTOMER}/", await Util.GetTokenAsync("BizAdmin")); Util.ValidateDataReturnResponseOk(a); //assert contains three records ONLY and the one we added var templateArray = JArray.Parse(a.ObjectResponse["data"]["template"].Value()); templateArray.Count.Should().Be(3); templateArray[2]["fld"].Value().Should().Be("CustomerAccountNumber"); //CONFIRM THE CUSTOM PICKLIST TEMPLATE WORKS PROPERLY //MAKE THE TEST Customer //make a unique string for this iteration of this test only var UniquePhrase = Util.Uniquify("pick").Replace(" ", ""); d = new JObject(); d.name = Util.Uniquify("CustomerPickListTemplatesOps") + UniquePhrase; d.active = true; d.accountNumber = UniquePhrase; a = await Util.PostAsync("Customer", await Util.GetTokenAsync("superuser", "l3tm3in"), d.ToString()); Util.ValidateDataReturnResponseOk(a); long ExpectedObjectId = a.ObjectResponse["data"]["id"].Value(); //GET PICKLIST FOR unique phrase query sb only employee number due to custom template a = await Util.PostAsync("pick-list/list", await Util.GetTokenAsync("BizAdmin"), $"{{\"ayaType\":8,\"query\":\"{UniquePhrase}\"}}"); Util.ValidateDataReturnResponseOk(a); var pickList = ((JArray)a.ObjectResponse["data"]); pickList.Count.Should().Be(1); pickList[0]["id"].Value().Should().Be(ExpectedObjectId); //DELETE TEST CUSTOMER NO LONGER NEEDED a = await Util.DeleteAsync("Customer/" + ExpectedObjectId.ToString(), await Util.GetTokenAsync("superuser", "l3tm3in")); Util.ValidateHTTPStatusCode(a, 204); // RESET TEMPLATE TO DEFAULT //Note deleting causes server to replace with default a = await Util.DeleteAsync($"pick-list/template/{AY_OBJECT_TYPE_CUSTOMER}/", await Util.GetTokenAsync("BizAdmin")); Util.ValidateHTTPStatusCode(a, 204); //RETRIEVE (Confirm it's back to default) //Get one a = await Util.GetAsync($"pick-list/template/{AY_OBJECT_TYPE_CUSTOMER}/", await Util.GetTokenAsync("BizAdmin")); Util.ValidateDataReturnResponseOk(a); //assert contains default template record ONLY and it's the one we set templateArray = JArray.Parse(a.ObjectResponse["data"]["template"].Value()); templateArray.Count.Should().Be(2); templateArray[0]["fld"].Value().Should().Be("customername"); //Now test error conditions.... //BAD FIELD NAME VALIDATION ERROR d = new JObject(); d.Id = AY_OBJECT_TYPE_CUSTOMER; //template, simple test, nothing fancy dTemplateArray = new JArray(); df = new JObject(); df.fld = "DOES_NOT_EXIST";//<-- ERROR BAD FIELD NAME dTemplateArray.Add(df); d.Template = dTemplateArray.ToString(Newtonsoft.Json.Formatting.None); a = await Util.PostAsync("pick-list/template", await Util.GetTokenAsync("BizAdmin"), d.ToString(Newtonsoft.Json.Formatting.None)); //"{\"error\":{\"code\":\"2200\",\"details\":[{\"message\":\"Template array item 0, fld property value \\\"DOES_NOT_EXIST\\\" is not a valid value for AyaType specified\",\"target\":\"Template\",\"error\":\"2203\"}],\"message\":\"Object did not pass validation\"}}" Util.ValidateErrorCodeResponse(a, 2200, 400); Util.ShouldContainValidationError(a, "Template", "2203"); //BAD AYATYPE ERROR d = new JObject(); d.Id = 0;//<==ERROR NO_TYPE, INVALID //template, simple test, nothing fancy dTemplateArray = new JArray(); df = new JObject(); df.fld = "customername"; dTemplateArray.Add(df); d.Template = dTemplateArray.ToString(Newtonsoft.Json.Formatting.None); //replace the template at the server a = await Util.PostAsync("pick-list/template", await Util.GetTokenAsync("BizAdmin"), d.ToString(Newtonsoft.Json.Formatting.None)); //"{\"error\":{\"code\":\"2200\",\"details\":[{\"message\":\"Template array item 0, fld property value \\\"DOES_NOT_EXIST\\\" is not a valid value for AyaType specified\",\"target\":\"Template\",\"error\":\"2203\"}],\"message\":\"Object did not pass validation\"}}" Util.ValidateErrorCodeResponse(a, 2200, 400); Util.ShouldContainValidationError(a, "ayaType", "2203"); //RIGHTS ISSUE, //currently only BizAdmin can change a picklist template d = new JObject(); d.Id = AY_OBJECT_TYPE_CUSTOMER; //template, simple test, nothing fancy dTemplateArray = new JArray(); df = new JObject(); df.fld = "customername"; dTemplateArray.Add(df); d.Template = dTemplateArray.ToString(Newtonsoft.Json.Formatting.None); //ERROR NO RIGHTS USER a = await Util.PostAsync("pick-list/template", await Util.GetTokenAsync("CustomerRestricted"), d.ToString(Newtonsoft.Json.Formatting.None)); //"{\"error\":{\"code\":\"2004\",\"message\":\"User not authorized for this resource operation (insufficient rights)\"}}" Util.ValidateErrorCodeResponse(a, 2004, 403); //EMPTY TEMPLATE VALIDATION ERROR d = new JObject(); d.Id = AY_OBJECT_TYPE_CUSTOMER; d.Template = "";//<-- ERROR no template a = await Util.PostAsync("pick-list/template", await Util.GetTokenAsync("BizAdmin"), d.ToString(Newtonsoft.Json.Formatting.None)); Util.ValidateErrorCodeResponse(a, 2200, 400); Util.ShouldContainValidationError(a, "Template", "2201"); //MALFORMED TEMPLATE JSON ERROR d = new JObject(); d.Id = AY_OBJECT_TYPE_CUSTOMER; dTemplateArray = new JArray(); df = new JObject(); df.fld = "customername"; dTemplateArray.Add(df); string sTemplate = dTemplateArray.ToString(Newtonsoft.Json.Formatting.None); d.Template = sTemplate.Substring(2);//<-- ERROR missing first two characters of json template array a = await Util.PostAsync("pick-list/template", await Util.GetTokenAsync("BizAdmin"), d.ToString(Newtonsoft.Json.Formatting.None)); //"{\"error\":{\"code\":\"2200\",\"details\":[{\"message\":\"Template is not valid JSON string: Error reading JArray from JsonReader. Current JsonReader item is not an array: String. Path '', line 1, position 5.\",\"target\":\"Template\",\"error\":\"2203\"}],\"message\":\"Object did not pass validation\"}}" Util.ValidateErrorCodeResponse(a, 2200, 400); Util.ShouldContainValidationError(a, "Template", "2203"); } /// /// test get templates list /// [Fact] public async Task PickListTemplateList() { //RETRIEVE ApiResponse a = await Util.GetAsync("pick-list/template/list", await Util.GetTokenAsync("BizAdmin")); Util.ValidateDataReturnResponseOk(a); //assert contains at least 16 records at time of writing this test var templateList = ((JArray)a.ObjectResponse["data"]); templateList.Count.Should().BeGreaterThan(16); templateList[0]["id"].Value().Should().Be(10);//first one should be a contract } /// /// test get picklist fields list for User template /// [Fact] public async Task UserPickListTemplateFieldList() { //RETRIEVE USER PICKLIST FIELDS ApiResponse a = await Util.GetAsync("pick-list/template/ListFields/3", await Util.GetTokenAsync("BizAdmin")); Util.ValidateDataReturnResponseOk(a); //assert contains at least two records (as we only have two at time of writing this test) var templateList = ((JArray)a.ObjectResponse["data"]); templateList.Count.Should().BeGreaterThan(3); templateList[0]["fieldKey"].Value().Should().Be("useractive");//first one should be a useractive field } /// /// test get picklist for User without query /// [Fact] public async Task FetchUserPickListNoQuery() { //RETRIEVE PICKLIST no filter ApiResponse a = await Util.PostAsync("pick-list/list", await Util.GetTokenAsync("BizAdmin"),"{ayaType: 3}"); Util.ValidateDataReturnResponseOk(a); //assert contains 100 records (current picklist maximum count) var pickList = ((JArray)a.ObjectResponse["data"]); pickList.Count.Should().BeGreaterThan(10);// a bunch } /// /// test get picklist for single predefined value only /// [Fact] public async Task FetchUserPickListPreDefined() { //fetch the SuperUser account which always exists ApiResponse a = await Util.PostAsync("pick-list/list", await Util.GetTokenAsync("BizAdmin"),"{\"ayaType\":3,\"preselectedIds\":[1],\"listVariant\":\"inside\"}"); Util.ValidateDataReturnResponseOk(a); //assert contains 1 record var pickList = ((JArray)a.ObjectResponse["data"]); pickList.Count.Should().Be(1); pickList[0]["id"].Value().Should().Be(1); } /// /// test get picklist for user with basic autocomplete query only /// [Fact] public async Task FetchUserPickListAutoComplete() { //make key user var UserNameStart = "FetchUserPickListAutoComplete_a1b2c3"; long IncludedUserId = 0; //CREATE TEST USERS //included user dynamic w = new JObject(); w.name = Util.Uniquify(UserNameStart); w.customFields = Util.UserRequiredCustomFieldsJsonString(); w.notes = "blah"; w.active = true; w.usertype = 1; ApiResponse a = await Util.PostAsync("user", await Util.GetTokenAsync("superuser", "l3tm3in"), w.ToString()); Util.ValidateDataReturnResponseOk(a); IncludedUserId = a.ObjectResponse["data"]["id"].Value(); //RETRIEVE USER PICKLIST with name filter //a = await Util.GetAsync("pick-list/list?ayaType=3&query=a1b2c3", await Util.GetTokenAsync("BizAdmin")); a = await Util.PostAsync("pick-list/list", await Util.GetTokenAsync("BizAdmin"), "{ \"ayaType\": 3, \"query\": \"a1b\", \"listVariant\": \"inside\"}"); Util.ValidateDataReturnResponseOk(a); var pickList = ((JArray)a.ObjectResponse["data"]); pickList.Count.Should().BeGreaterThan(0); pickList[0]["name"].Value().Should().Contain("_a1b2c3"); //DELETE USERS a = await Util.DeleteAsync("user/" + IncludedUserId.ToString(), await Util.GetTokenAsync("BizAdmin")); Util.ValidateHTTPStatusCode(a, 204); } /// /// /// [Fact] public async Task FetchUserPickListTags() { //make key user var UserNameStart = "FetchUserPickListTags"; long IncludedUserId = 0; //CREATE TEST USERS //included user dynamic w = new JObject(); w.name = Util.Uniquify(UserNameStart); w.customFields = Util.UserRequiredCustomFieldsJsonString(); w.notes = "blah"; w.active = true; w.usertype = 1; //Tags dynamic InclusiveTagsArray = new JArray(); InclusiveTagsArray.Add("plred"); InclusiveTagsArray.Add("plblue"); w.tags = InclusiveTagsArray; ApiResponse a = await Util.PostAsync("user", await Util.GetTokenAsync("superuser", "l3tm3in"), w.ToString()); Util.ValidateDataReturnResponseOk(a); IncludedUserId = a.ObjectResponse["data"]["id"].Value(); //RETRIEVE USER PICKLIST with tag query //a = await Util.PostAsync("pick-list/list", await Util.GetTokenAsync("BizAdmin"), "{ \"ayaType\": 3, \"query\": \"..lblu\", \"listVariant\": \"inside\"}"); a = await Util.PostAsync("pick-list/list", await Util.GetTokenAsync("BizAdmin"), "{ \"ayaType\": 3, \"query\": \"..lblu\"}"); //a = await Util.PostAsync("pick-list/list?ayaType=3&query=..lblu", await Util.GetTokenAsync("BizAdmin")); Util.ValidateDataReturnResponseOk(a); var pickList = ((JArray)a.ObjectResponse["data"]); pickList.Count.Should().BeGreaterOrEqualTo(1);//prior failed test runs may cause dupe tagged items //this can fail if the test failed before and doesn't really bring any value to the test // pickList[0]["id"].Value().Should().Be(IncludedUserId); //DELETE USERS a = await Util.DeleteAsync("user/" + IncludedUserId.ToString(), await Util.GetTokenAsync("BizAdmin")); Util.ValidateHTTPStatusCode(a, 204); } /// /// test get picklist based on active / inactive status /// [Fact] public async Task FetchUserPickListInactiveActive() { //unique for this iteration of test so don't have to regen the data var UniquePhrase = Util.Uniquify("pick").Replace(" ", ""); //make key user var UserNameStart = $"FetchUserPickListInactiveActive-{UniquePhrase}-"; List ActiveUserIdList = new List(); List NotActiveUserIdList = new List(); //CREATE 4 TEST USERS //two active and two non active //first active user dynamic w = new JObject(); w.name = Util.Uniquify(UserNameStart); w.customFields = Util.UserRequiredCustomFieldsJsonString(); w.notes = "blah"; w.active = true; w.usertype = 1; ApiResponse a = await Util.PostAsync("user", await Util.GetTokenAsync("superuser", "l3tm3in"), w.ToString()); Util.ValidateDataReturnResponseOk(a); ActiveUserIdList.Add(a.ObjectResponse["data"]["id"].Value()); //second active user w.name = Util.Uniquify(UserNameStart); a = await Util.PostAsync("user", await Util.GetTokenAsync("superuser", "l3tm3in"), w.ToString()); Util.ValidateDataReturnResponseOk(a); ActiveUserIdList.Add(a.ObjectResponse["data"]["id"].Value()); //first NON active user w.name = Util.Uniquify(UserNameStart); w.active = false; a = await Util.PostAsync("user", await Util.GetTokenAsync("superuser", "l3tm3in"), w.ToString()); Util.ValidateDataReturnResponseOk(a); NotActiveUserIdList.Add(a.ObjectResponse["data"]["id"].Value()); //second NON active user w.name = Util.Uniquify(UserNameStart); w.active = false; a = await Util.PostAsync("user", await Util.GetTokenAsync("superuser", "l3tm3in"), w.ToString()); Util.ValidateDataReturnResponseOk(a); NotActiveUserIdList.Add(a.ObjectResponse["data"]["id"].Value()); //CONFIRM BOTH INACTIVE AND ACTIVE a = await Util.PostAsync("pick-list/list", await Util.GetTokenAsync("BizAdmin"), $"{{ \"ayaType\": 3, \"query\": \"{UserNameStart}\", \"inactive\":\"True\"}}"); //a = await Util.GetAsync("pick-list/list?ayaType=3&query=ickListInactiveAct&inactive=true", await Util.GetTokenAsync("BizAdmin")); Util.ValidateDataReturnResponseOk(a); var pickList = ((JArray)a.ObjectResponse["data"]); //assert contains at least two records pickList.Count.Should().BeGreaterThan(1); int nActiveMatches = 0; int nInactiveMatches = 0; foreach (JObject o in pickList) { if (ActiveUserIdList.Contains(o["id"].Value())) nActiveMatches++; if (NotActiveUserIdList.Contains(o["id"].Value())) nInactiveMatches++; } nActiveMatches.Should().Be(ActiveUserIdList.Count); nInactiveMatches.Should().Be(NotActiveUserIdList.Count); //CONFIRM ACTIVE ONLY //a = await Util.GetAsync("pick-list/list?ayaType=3&query=ickListInactiveAct", await Util.GetTokenAsync("BizAdmin")); a = await Util.PostAsync("pick-list/list", await Util.GetTokenAsync("BizAdmin"), $"{{ \"ayaType\": 3, \"query\": \"{UserNameStart}\"}}"); Util.ValidateDataReturnResponseOk(a); pickList = ((JArray)a.ObjectResponse["data"]); //assert contains at least two records pickList.Count.Should().BeGreaterThan(1); nActiveMatches = 0; nInactiveMatches = 0; foreach (JObject o in pickList) { if (ActiveUserIdList.Contains(o["id"].Value())) nActiveMatches++; if (NotActiveUserIdList.Contains(o["id"].Value())) nInactiveMatches++; } nActiveMatches.Should().Be(ActiveUserIdList.Count); nInactiveMatches.Should().Be(0); //DELETE USERS foreach (long l in ActiveUserIdList) { a = await Util.DeleteAsync("user/" + l.ToString(), await Util.GetTokenAsync("BizAdmin")); Util.ValidateHTTPStatusCode(a, 204); } foreach (long l in NotActiveUserIdList) { a = await Util.DeleteAsync("user/" + l.ToString(), await Util.GetTokenAsync("BizAdmin")); Util.ValidateHTTPStatusCode(a, 204); } } //================================================== }//eoc }//eons