diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..8a3f0fd --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,28 @@ +{ + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md + "version": "0.2.0", + "configurations": [ + { + "name": ".NET Core Launch (console)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + // If you have changed target frameworks, make sure to update the program path. + "program": "${workspaceFolder}/bin/Debug/netcoreapp2.0/raven-integration.dll", + "args": [], + "cwd": "${workspaceFolder}", + // For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window + "console": "internalConsole", + "stopAtEntry": false, + "internalConsoleOptions": "openOnSessionStart" + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach", + "processId": "${command:pickProcess}" + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c2aabc7 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.codeLens": true +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..51afd6a --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,15 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "taskName": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/raven-integration.csproj" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/ApiResponse.cs b/ApiResponse.cs new file mode 100644 index 0000000..b626901 --- /dev/null +++ b/ApiResponse.cs @@ -0,0 +1,13 @@ +using System.Net.Http; +using Newtonsoft.Json.Linq; + +namespace raven_integration +{ + public class ApiResponse + { + public HttpResponseMessage HttpResponse {get;set;} + public JObject ObjectResponse {get;set;} + + + }//eoc +}//eons \ No newline at end of file diff --git a/ApiTextResponse.cs b/ApiTextResponse.cs new file mode 100644 index 0000000..6cad35a --- /dev/null +++ b/ApiTextResponse.cs @@ -0,0 +1,13 @@ +using System.Net.Http; +using Newtonsoft.Json.Linq; + +namespace raven_integration +{ + public class ApiTextResponse + { + public HttpResponseMessage HttpResponse {get;set;} + public string TextResponse {get;set;} + + + }//eoc +}//eons \ No newline at end of file diff --git a/Attachments/AttachmentTest.cs b/Attachments/AttachmentTest.cs new file mode 100644 index 0000000..bc77b88 --- /dev/null +++ b/Attachments/AttachmentTest.cs @@ -0,0 +1,182 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Net.Http; +using System.Net.Http.Headers; +using System.IO; + +namespace raven_integration +{ + //https://stackoverflow.com/questions/17725882/testing-asp-net-web-api-multipart-form-data-file-upload + public class AttachmentTest + { + /// + /// test attach CRUD + /// + [Fact] + public async void AttachmentUploadDownloadDeleteShouldWork() + { + + ////////////////////////////////////////// + //// Upload the files + MultipartFormDataContent formDataContent = new MultipartFormDataContent(); + + //Form data like the bizobject type and id + formDataContent.Add(new StringContent("2"), name: "AttachToObjectType"); + formDataContent.Add(new StringContent("1"), name: "AttachToObjectId"); + //or if testing non-existant this is probably safe: long.MaxValue + + + StreamContent file1 = new StreamContent(File.OpenRead($"{Util.TEST_DATA_FOLDER}\\test.png")); + file1.Headers.ContentType = new MediaTypeHeaderValue("image/png"); + file1.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data"); + file1.Headers.ContentDisposition.FileName = "test.png"; + formDataContent.Add(file1); + StreamContent file2 = new StreamContent(File.OpenRead($"{Util.TEST_DATA_FOLDER}\\test.zip")); + file2.Headers.ContentType = new MediaTypeHeaderValue("application/zip"); + file2.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data"); + file2.Headers.ContentDisposition.FileName = "test.zip"; + formDataContent.Add(file2); + + //create via inventory full test user as attachments use the role of the object attaching to + ApiResponse a = await Util.PostFormDataAsync("Attachment", formDataContent, await Util.GetTokenAsync("InventoryFull")); + + + Util.ValidateDataReturnResponseOk(a); + + + long lTestPngAttachmentId = a.ObjectResponse["data"][0]["id"].Value(); + long lTestZipAttachmentId = a.ObjectResponse["data"][1]["id"].Value(); + + //saw negative values on a db issue that I corrected (I think) + //Keeping these in case it arises again, if it does, see log, it's a db error with async issue of some kind + lTestPngAttachmentId.Should().BePositive(); + lTestZipAttachmentId.Should().BePositive(); + + ////////////////////////////////////////// + //// DOWNLOAD: Get the file attachment + + //Get the inventoryfull account download token + // { + // "data": { + // "dlkey": "w7iE1cXF8kOxo8eomd1r8A", + // "expires": "2018-04-25T23:45:39.05665" + // } + // } + a = await Util.GetAsync("Attachment/DownloadToken", await Util.GetTokenAsync("InventoryFull")); + Util.ValidateDataReturnResponseOk(a); + string downloadToken = a.ObjectResponse["data"]["dlkey"].Value(); + + //now get the file https://rockfish.ayanova.com/api/rfcaseblob/download/248?dlkey=9O2eDAAlZ0Wknj19SBK2iA + var dlresponse = await Util.DownloadFileAsync("Attachment/Download/" + lTestZipAttachmentId.ToString() + "?dlkey=" + downloadToken, await Util.GetTokenAsync("InventoryFull")); + + //ensure it's the zip file we expected + dlresponse.Content.Headers.ContentDisposition.FileName.Should().Be("test.zip"); + dlresponse.Content.Headers.ContentLength.Should().BeGreaterThan(2000); + + + ////////////////////////////////////////// + //// DELETE: Delete the file attachments + ApiResponse d = await Util.DeleteAsync("Attachment/" + lTestPngAttachmentId.ToString(), await Util.GetTokenAsync("InventoryFull")); + Util.ValidateHTTPStatusCode(d, 204); + + d = await Util.DeleteAsync("Attachment/" + lTestZipAttachmentId.ToString(), await Util.GetTokenAsync("InventoryFull")); + Util.ValidateHTTPStatusCode(d, 204); + + + } + + + + /// + /// test no rights + /// + [Fact] + public async void NoRightsTest() + { + + MultipartFormDataContent formDataContent = new MultipartFormDataContent(); + + formDataContent.Add(new StringContent("2"), name: "AttachToObjectType"); + formDataContent.Add(new StringContent("1"), name: "AttachToObjectId"); + + StreamContent file1 = new StreamContent(File.OpenRead($"{Util.TEST_DATA_FOLDER}\\test.png")); + file1.Headers.ContentType = new MediaTypeHeaderValue("image/png"); + file1.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data"); + file1.Headers.ContentDisposition.FileName = "test.png"; + formDataContent.Add(file1); + + //ERROR CONDITION: BizAdminLimited user should not be able to attach a file to a widget + ApiResponse a = await Util.PostFormDataAsync("Attachment", formDataContent, await Util.GetTokenAsync("BizAdminLimited")); + + //2004 unauthorized + Util.ValidateErrorCodeResponse(a, 2004, 401); + + } + + + /// + /// test not attachable + /// + [Fact] + public async void UnattachableTest() + { + MultipartFormDataContent formDataContent = new MultipartFormDataContent(); + + //Form data bizobject type and id + + //HERE IS THE ERROR CONDITION: LICENSE TYPE OBJECT WHICH IS UNATTACHABLE + formDataContent.Add(new StringContent("5"), name: "AttachToObjectType"); + formDataContent.Add(new StringContent("1"), name: "AttachToObjectId"); + + StreamContent file1 = new StreamContent(File.OpenRead($"{Util.TEST_DATA_FOLDER}\\test.png")); + file1.Headers.ContentType = new MediaTypeHeaderValue("image/png"); + file1.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data"); + file1.Headers.ContentDisposition.FileName = "test.png"; + formDataContent.Add(file1); + ApiResponse a = await Util.PostFormDataAsync("Attachment", formDataContent, await Util.GetTokenAsync("InventoryFull")); + + //2203 unattachable object + Util.ValidateErrorCodeResponse(a, 2203, 400); + + } + + + /// + /// test bad object values + /// + [Fact] + public async void BadObject() + { + MultipartFormDataContent formDataContent = new MultipartFormDataContent(); + + //Form data like the bizobject type and id + formDataContent.Add(new StringContent("2"), name: "AttachToObjectType"); + + //HERE IS THE ERROR CONDITION, A NON EXISTENT ID VALUE FOR THE WIDGET + formDataContent.Add(new StringContent(long.MaxValue.ToString()), name: "AttachToObjectId");//non-existent widget + + StreamContent file1 = new StreamContent(File.OpenRead($"{Util.TEST_DATA_FOLDER}\\test.png")); + file1.Headers.ContentType = new MediaTypeHeaderValue("image/png"); + file1.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data"); + file1.Headers.ContentDisposition.FileName = "test.png"; + formDataContent.Add(file1); + ApiResponse a = await Util.PostFormDataAsync("Attachment", formDataContent, await Util.GetTokenAsync("InventoryFull")); + + //2203 invalid attachment object + Util.ValidateErrorCodeResponse(a, 2203, 400); + + } + + + + + + + //================================================== + + }//eoc +}//eons diff --git a/Authentication/Auth.cs b/Authentication/Auth.cs new file mode 100644 index 0000000..9e9233f --- /dev/null +++ b/Authentication/Auth.cs @@ -0,0 +1,36 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; + +namespace raven_integration +{ + + public class Auth + { + /// + /// + /// + [Fact] + public async void BadLoginShouldNotWork() + { + //Expect status code 401 and result: + // {{ + // "error": { + // "code": "2003", + // "message": "Authentication failed" + // } + // }} + + dynamic d = new JObject(); + d.login = "BOGUS"; + d.password = "ACCOUNT"; + ApiResponse a = await Util.PostAsync("Auth", null, d.ToString()); + Util.ValidateErrorCodeResponse(a,2003,401); + } + + //================================================== + + }//eoc +}//eons + diff --git a/AutoId.cs b/AutoId.cs new file mode 100644 index 0000000..676fef9 --- /dev/null +++ b/AutoId.cs @@ -0,0 +1,26 @@ +using System; +using System.Threading.Tasks; +namespace raven_integration +{ + public class AutoId + { + private readonly object valueLock = new object(); + private uint currentValue; //postgre bigint + + public AutoId(uint initialValue) + { + currentValue = initialValue; + } + + public uint GetNext() + { + lock (valueLock) + { + currentValue += 1; + if (currentValue == 0) + currentValue += 1; + return currentValue; + } + } + } +} \ No newline at end of file diff --git a/AyaType/AyaType.cs b/AyaType/AyaType.cs new file mode 100644 index 0000000..17a2d86 --- /dev/null +++ b/AyaType/AyaType.cs @@ -0,0 +1,36 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace raven_integration +{ + + public class AyaType + { + + /// + /// + /// + [Fact] + public async void AyaTypeListShouldWork() + { + ApiResponse a = await Util.GetAsync("AyaType"); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + //there should be at least 8 of them (at time of writing late March 2018) + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterOrEqualTo(8); + + //Number 2 is widget and list is zero based so confirm: + a.ObjectResponse["data"][2]["id"].Value().Should().Be(2); + a.ObjectResponse["data"][2]["name"].Value().Should().Be("Widget [Attachable]"); + + } + + + //================================================== + + }//eoc +}//eons diff --git a/DataFilter/DataFilterCrud.cs b/DataFilter/DataFilterCrud.cs new file mode 100644 index 0000000..d337fd1 --- /dev/null +++ b/DataFilter/DataFilterCrud.cs @@ -0,0 +1,176 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace raven_integration +{ + + public class DataFilterCrud + { + + /// + /// Test all CRUD routes + /// + [Fact] + public async void CRUD() + { + //CREATE + dynamic d = new JObject(); + d.name = Util.Uniquify("Test DataFilter"); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + //"[{fld:"name",op:"!=",value:"Notequaltothis"},{fld:"tags",op:"Eq",value:"[23,456,54]"}] + dynamic dfilter = new JArray(); + dynamic df = new JObject(); + df.fld = "name"; + df.op = "%-"; + df.value = "Generic";//lots of seed widgets start with Generic + dfilter.Add(df); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + ApiResponse a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long Id = a.ObjectResponse["data"]["id"].Value(); + + + //RETRIEVE + //Get one + a = await Util.GetAsync("DataFilter/" + Id.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateDataReturnResponseOk(a); + a.ObjectResponse["data"]["name"].Value().Should().StartWith("Test DataFilter"); + + //Get as alternate user should work for public filter + a = await Util.GetAsync("DataFilter/" + Id.ToString(), await Util.GetTokenAsync("SubContractorLimited")); + Util.ValidateDataReturnResponseOk(a); + a.ObjectResponse["data"]["name"].Value().Should().StartWith("Test DataFilter"); + + + //UPDATE + + //PUT, make private + d["public"] = false; + d.name = Util.Uniquify("Put - Test DataFilter (privatized)"); + d.concurrencyToken = a.ObjectResponse["data"]["concurrencyToken"].Value(); + a = await Util.PutAsync("DataFilter/" + Id.ToString(), await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateHTTPStatusCode(a, 200); + + //check PUT worked + a = await Util.GetAsync("DataFilter/" + Id.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateNoErrorInResponse(a); + a.ObjectResponse["data"]["name"].Value().Should().Be(d.name.ToString()); + + + //FETCH DISALLOWED + //Get as alternate user should fail for private filter + a = await Util.GetAsync("DataFilter/" + Id.ToString(), await Util.GetTokenAsync("SubContractorLimited")); + Util.ValidateResponseNotFound(a); + + // //DELETE + ApiResponse DELETETestResponse = await Util.DeleteAsync("DataFilter/" + Id.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(DELETETestResponse, 204); + + } + + /// + /// + /// + [Fact] + public async void InvalidListKeyShouldFail() + { + //CREATE + dynamic d = new JObject(); + d.name = Util.Uniquify("Test DataFilter"); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "nonexistant"; + + //"[{fld:"name",op:"!=",value:"Notequaltothis"},{fld:"tags",op:"Eq",value:"[23,456,54]"}] + dynamic dfilter = new JArray(); + dynamic df = new JObject(); + df.fld = "name"; + df.op = "%-"; + df.value = "Generic";//lots of seed widgets start with Generic + dfilter.Add(df); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + ApiResponse a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateErrorCodeResponse(a, 2200, 400); + Util.ShouldContainValidationError(a, "ListKey", "InvalidValue"); + + } + + + /// + /// + /// + [Fact] + public async void InvalidFieldNameShouldFail() + { + //CREATE + dynamic d = new JObject(); + d.name = Util.Uniquify("Test DataFilter"); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + //"[{fld:"name",op:"!=",value:"Notequaltothis"},{fld:"tags",op:"Eq",value:"[23,456,54]"}] + dynamic dfilter = new JArray(); + dynamic df = new JObject(); + df.fld = "doesntexist"; + df.op = "%-"; + df.value = "Generic";//lots of seed widgets start with Generic + dfilter.Add(df); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + ApiResponse a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateErrorCodeResponse(a, 2200, 400); + Util.ShouldContainValidationError(a, "Filter", "InvalidValue"); + + } + + + + /// + /// + /// + [Fact] + public async void InvalidOperatorShouldFail() + { + //CREATE + dynamic d = new JObject(); + d.name = Util.Uniquify("Test DataFilter"); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + //"[{fld:"name",op:"!=",value:"Notequaltothis"},{fld:"tags",op:"Eq",value:"[23,456,54]"}] + dynamic dfilter = new JArray(); + dynamic df = new JObject(); + df.fld = "name"; + df.op = "wtf"; + df.value = "Generic";//lots of seed widgets start with Generic + dfilter.Add(df); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + ApiResponse a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateErrorCodeResponse(a, 2200, 400); + Util.ShouldContainValidationError(a, "Filter", "InvalidValue"); + + } + + + + //================================================== + + }//eoc +}//eons diff --git a/DataFilter/DataFilterFilteringLists.cs b/DataFilter/DataFilterFilteringLists.cs new file mode 100644 index 0000000..cb0c267 --- /dev/null +++ b/DataFilter/DataFilterFilteringLists.cs @@ -0,0 +1,6237 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace raven_integration +{ + + + /* + + EVERY TYPE, EVERY OP + + Using the widget object test all filtering options + for all data types, all operation types + + This is the supertest to always confirm the filtering code is working as expected. + + + */ + + public class DataFilterFilteringLists + { + + + + + + + /////////////////////////////////////////////////////////////////////////////// + //DATE + // + + #region DATE FILTER TESTS + + public const string TokenYesterday = "{[yesterday]}"; + public const string TokenToday = "{[today]}"; + public const string TokenTomorrow = "{[tomorrow]}"; + public const string TokenLastWeek = "{[lastweek]}"; + public const string TokenThisWeek = "{[thisweek]}"; + public const string TokenNextWeek = "{[nextweek]}"; + public const string TokenLastMonth = "{[lastmonth]}"; + public const string TokenThisMonth = "{[thismonth]}"; + public const string TokenNextMonth = "{[nextmonth]}"; + public const string TokenFourteenDayWindow = "{[14daywindow]}"; + public const string TokenPast = "{[past]}"; + public const string TokenFuture = "{[future]}"; + public const string TokenLastYear = "{[lastyear]}"; + public const string TokenThisYear = "{[thisyear]}"; + public const string TokenInTheLast3Months = "{[last3months]}"; + public const string TokenInTheLast6Months = "{[last6months]}"; + public const string TokenInTheLastYear = "{[lastcalendaryear]}"; + + //More business time frames + + public const string TokenYearToDate = "{[yeartodate]}"; + + public const string TokenPast90Days = "{[past90days]}"; + public const string TokenPast30Days = "{[past30days]}"; + public const string TokenPast24Hours = "{[past24hours]}"; + + + + + #region DATE REGULAR FILTERS + + /// + /// + /// + [Fact] + public async void DateOpEqualityFilterWorks() + { + + var WidgetNameStart = "DateOpEqualityFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = new DateTime(1968, 3, 12, 10, 0, 0).ToUniversalTime(); + w.endDate = new DateTime(1968, 3, 12, 11, 0, 0).ToUniversalTime(); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = new DateTime(1968, 3, 10, 10, 0, 0).ToUniversalTime(); + w.endDate = new DateTime(1968, 3, 10, 11, 0, 0).ToUniversalTime(); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = new DateTime(1968, 3, 12, 10, 0, 0).ToUniversalTime(); + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + + /// + /// + /// + [Fact] + public async void DateOpGreaterThanFilterWorks() + { + + var WidgetNameStart = "DateOpGreaterThanFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = new DateTime(1970, 3, 12, 10, 0, 0).ToUniversalTime(); + w.endDate = new DateTime(1970, 3, 12, 11, 0, 0).ToUniversalTime(); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = new DateTime(1968, 3, 10, 10, 0, 0).ToUniversalTime(); + w.endDate = new DateTime(1968, 3, 10, 11, 0, 0).ToUniversalTime(); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpGreaterThan; + FilterItem.value = new DateTime(1970, 3, 12, 9, 0, 0).ToUniversalTime(); + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + + /// + /// + /// + [Fact] + public async void DateOpGreaterThanOrEqualToFilterWorks() + { + + var WidgetNameStart = "DateOpGreaterThanOrEqualToFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = new DateTime(1970, 3, 12, 10, 0, 0).ToUniversalTime(); + w.endDate = new DateTime(1970, 3, 12, 11, 0, 0).ToUniversalTime(); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = new DateTime(1968, 3, 10, 10, 0, 0).ToUniversalTime(); + w.endDate = new DateTime(1968, 3, 10, 11, 0, 0).ToUniversalTime(); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpGreaterThanOrEqualTo; + FilterItem.value = new DateTime(1970, 3, 12, 10, 0, 0).ToUniversalTime(); + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void DateOpLessThanFilterWorks() + { + + var WidgetNameStart = "DateOpLessThanFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = new DateTime(1970, 3, 12, 10, 0, 0).ToUniversalTime(); + w.endDate = new DateTime(1970, 3, 12, 11, 0, 0).ToUniversalTime(); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = new DateTime(1970, 4, 10, 10, 0, 0).ToUniversalTime(); + w.endDate = new DateTime(1970, 4, 10, 11, 0, 0).ToUniversalTime(); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpLessThan; + FilterItem.value = new DateTime(1970, 3, 12, 11, 0, 0).ToUniversalTime(); + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + + /// + /// + /// + [Fact] + public async void DateOpLessThanOrEqualToFilterWorks() + { + + var WidgetNameStart = "DateOpLessThanOrEqualToFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = new DateTime(1970, 3, 12, 10, 0, 0).ToUniversalTime(); + w.endDate = new DateTime(1970, 3, 12, 11, 0, 0).ToUniversalTime(); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = new DateTime(1970, 4, 10, 10, 0, 0).ToUniversalTime(); + w.endDate = new DateTime(1970, 4, 10, 11, 0, 0).ToUniversalTime(); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpLessThanOrEqualTo; + FilterItem.value = new DateTime(1970, 3, 12, 10, 0, 0).ToUniversalTime(); + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + + /// + /// + /// + [Fact] + public async void DateOpNotEqualToFilterWorks() + { + + var WidgetNameStart = "DateOpNotEqualToFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = new DateTime(1970, 3, 12, 10, 0, 0).ToUniversalTime(); + w.endDate = new DateTime(1970, 3, 12, 11, 0, 0).ToUniversalTime(); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = new DateTime(1970, 4, 10, 10, 0, 0).ToUniversalTime(); + w.endDate = new DateTime(1970, 4, 10, 11, 0, 0).ToUniversalTime(); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpNotEqual; + FilterItem.value = new DateTime(1970, 4, 10, 10, 0, 0).ToUniversalTime(); + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + + /// + /// + /// + [Fact] + public async void DateTokenYesterdayFilterWorks() + { + + var WidgetNameStart = "DateTokenYesterdayFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = DateTime.UtcNow.AddDays(-1); + w.endDate = DateTime.UtcNow.AddHours(1).AddDays(-1); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = DateTime.UtcNow; + w.endDate = DateTime.UtcNow.AddHours(1); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = TokenYesterday; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + + /// + /// + /// + [Fact] + public async void DateTokenTodayFilterWorks() + { + + var WidgetNameStart = "DateTokenTodayFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = DateTime.UtcNow; + w.endDate = DateTime.UtcNow.AddHours(1); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = DateTime.UtcNow.AddDays(-1); + w.endDate = DateTime.UtcNow.AddHours(1).AddDays(-1); + + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = TokenToday; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void DateTokenTomorrowFilterWorks() + { + + var WidgetNameStart = "DateTokenTomorrowFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = DateTime.UtcNow.AddDays(1); + w.endDate = DateTime.UtcNow.AddDays(1).AddHours(1); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = DateTime.UtcNow; + w.endDate = DateTime.UtcNow.AddHours(1); + + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = TokenTomorrow; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void DateTokenLastWeekFilterWorks() + { + + var WidgetNameStart = "DateTokenLastWeekFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + //My theory is any date - 7 days is last week if you go sunday to sunday + w.startDate = DateTime.UtcNow.AddDays(-7); + w.endDate = DateTime.UtcNow.AddHours(1).AddDays(-7); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = DateTime.UtcNow; + w.endDate = DateTime.UtcNow.AddHours(1); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = TokenLastWeek; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void DateTokenThisWeekFilterWorks() + { + + var WidgetNameStart = "DateTokenThisWeekFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = DateTime.UtcNow; + w.endDate = DateTime.UtcNow.AddHours(1); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + //My theory is any date - 7 days is last week if you go sunday to sunday + w.startDate = DateTime.UtcNow.AddDays(-7); + w.endDate = DateTime.UtcNow.AddHours(1).AddDays(-7); + + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = TokenThisWeek; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void DateTokenNextWeekFilterWorks() + { + + var WidgetNameStart = "DateTokenNextWeekFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + //My theory is any date + 7 days is next week if you go sunday to sunday + w.startDate = DateTime.UtcNow.AddDays(7); + w.endDate = DateTime.UtcNow.AddHours(1).AddDays(7); + + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = DateTime.UtcNow; + w.endDate = DateTime.UtcNow.AddHours(1); + + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = TokenNextWeek; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void DateTokenLastMonthFilterWorks() + { + + var WidgetNameStart = "DateTokenLastMonthFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + //First day of this month minus 2 days equals second to last day of last month + w.startDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1, 00, 00, 00).AddDays(-2).ToUniversalTime(); + w.endDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1, 00, 00, 00).AddDays(-2).AddHours(1).ToUniversalTime(); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + //Put it right at midnight this month to ensure boundaries are respected + w.startDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1, 00, 00, 00).ToUniversalTime(); + w.endDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1, 00, 00, 00).AddHours(1).ToUniversalTime(); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = TokenLastMonth; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + + /// + /// + /// + [Fact] + public async void DateTokenThisMonthFilterWorks() + { + + var WidgetNameStart = "DateTokenThisMonthFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + //Put it right at midnight this month to ensure boundaries are respected + w.startDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1, 00, 00, 00).ToUniversalTime(); + w.endDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1, 00, 00, 00).AddHours(1).ToUniversalTime(); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + //First day of this month minus 2 days equals second to last day of last month + w.startDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1, 00, 00, 00).AddDays(-2).ToUniversalTime(); + w.endDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1, 00, 00, 00).AddDays(-2).AddHours(1).ToUniversalTime(); + + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = TokenThisMonth; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + + /// + /// + /// + [Fact] + public async void DateTokenNextMonthFilterWorks() + { + + var WidgetNameStart = "DateTokenNextMonthFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + //Put it right at midnight next month to ensure boundaries are respected + w.startDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1, 00, 00, 00).AddMonths(1).ToUniversalTime(); + w.endDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1, 00, 00, 00).AddMonths(1).AddHours(1).ToUniversalTime(); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + //First day of next month minus 1 second + w.startDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1, 00, 00, 00).AddMonths(1).AddSeconds(-1).ToUniversalTime(); + w.endDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1, 00, 00, 00).AddMonths(1).AddSeconds(-1).AddHours(1).ToUniversalTime(); + + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = TokenNextMonth; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + //SELECT *, xmin FROM AWIDGET where name Like 'DateTokenNextMonthFilterWorks%' AND startdate >'2019-01-01T15:59:59.0000000Z' AND startdate <'2019-02-01T16:00:00.0000000Z' + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void DateToken14DayWindowFilterWorks() + { + + var WidgetNameStart = "DateToken14DayWindowFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + + w.startDate = DateTime.UtcNow; + w.endDate = DateTime.UtcNow.AddHours(1); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + //9 days ago will be outside the 14 day window + w.startDate = DateTime.UtcNow.AddDays(-9); + w.endDate = DateTime.UtcNow.AddDays(-9).AddHours(1); + + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = TokenFourteenDayWindow; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + + /// + /// + /// + [Fact] + public async void DateTokenPastFilterWorks() + { + + var WidgetNameStart = "DateTokenPastFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + //Test if for the past, definitely going to be in the past when the list is fetched after saving, but will it work with the server on another machine?? + //Best to pad in 5 minutes to be on the safe side, these days no two computers on earth should be out by more than 5 minutes to UTC from each other + w.startDate = DateTime.UtcNow.AddMinutes(-5); + w.endDate = DateTime.UtcNow.AddMinutes(-5).AddHours(1); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + //8 days ago will be outside the 14 day window + w.startDate = DateTime.UtcNow.AddMonths(1); + w.endDate = DateTime.UtcNow.AddMonths(1).AddHours(1); + + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = TokenPast; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + /// + /// + /// + [Fact] + public async void DateTokenFutureFilterWorks() + { + + var WidgetNameStart = "DateTokenFutureFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + //#### + w.startDate = DateTime.UtcNow.AddMinutes(5); + w.endDate = DateTime.UtcNow.AddMinutes(5).AddHours(1); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + //#### + w.startDate = DateTime.UtcNow; + w.endDate = DateTime.UtcNow.AddHours(1); + + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = TokenFuture; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void DateTokenLastYearFilterWorks() + { + + var WidgetNameStart = "DateTokenLastYearFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + //#### + w.startDate = DateTime.UtcNow.AddYears(-1).AddMinutes(-5); + w.endDate = DateTime.UtcNow.AddYears(-1).AddMinutes(-5).AddHours(1); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + //#### + w.startDate = DateTime.UtcNow; + w.endDate = DateTime.UtcNow.AddHours(1); + + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = TokenLastYear; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + + + + /// + /// + /// + [Fact] + public async void DateTokenThisYearFilterWorks() + { + + var WidgetNameStart = "DateTokenThisYearFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + //#### + w.startDate = DateTime.UtcNow; + w.endDate = DateTime.UtcNow.AddHours(1); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + //#### + w.startDate = DateTime.UtcNow.AddYears(-1).AddMinutes(-5); + w.endDate = DateTime.UtcNow.AddYears(-1).AddMinutes(-5).AddHours(1); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = TokenThisYear; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + + + + /// + /// + /// + [Fact] + public async void DateTokenInTheLast3MonthsFilterWorks() + { + + var WidgetNameStart = "DateTokenInTheLast3MonthsFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + //#### + w.startDate = DateTime.UtcNow.AddMonths(-3).AddMinutes(5); + w.endDate = DateTime.UtcNow.AddMonths(-3).AddMinutes(5).AddHours(1); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + //#### + w.startDate = DateTime.UtcNow.AddMonths(-3).AddMinutes(-5); + w.endDate = DateTime.UtcNow.AddMonths(-3).AddMinutes(-5).AddHours(1); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = TokenInTheLast3Months; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void DateTokenInTheLast6MonthsFilterWorks() + { + + var WidgetNameStart = "DateTokenInTheLast6MonthsFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + //#### + w.startDate = DateTime.UtcNow.AddMonths(-6).AddMinutes(5); + w.endDate = DateTime.UtcNow.AddMonths(-6).AddMinutes(5).AddHours(1); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + //#### + w.startDate = DateTime.UtcNow.AddMonths(-6).AddMinutes(-5); + w.endDate = DateTime.UtcNow.AddMonths(-6).AddMinutes(-5).AddHours(1); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = TokenInTheLast6Months; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void DateTokenInTheLastYearFilterWorks() + { + + var WidgetNameStart = "DateTokenInTheLastYearFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + //#### + w.startDate = DateTime.UtcNow.AddDays(-365).AddMinutes(5); + w.endDate = DateTime.UtcNow.AddDays(-365).AddMinutes(5).AddHours(1); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + //#### + w.startDate = DateTime.UtcNow.AddDays(-365).AddMinutes(-5); + w.endDate = DateTime.UtcNow.AddDays(-365).AddMinutes(-5).AddHours(1); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = TokenInTheLastYear; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + #endregion DATE REGULAR FILTERS + + #region DATE TOKEN FILTERS + + + + + /// + /// + /// + [Fact] + public async void DateTokenYearToDateFilterWorks() + { + + var WidgetNameStart = "DateTokenYearToDateFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //BUILD DATES FOR THIS TEST + + DateTime InclusiveStartDate; + DateTime ExclusiveStartDate; + + //################################################################################## + var FilterToken = TokenYearToDate; + InclusiveStartDate = new DateTime(DateTime.Now.Year, 1, 1, 00, 5, 00).ToUniversalTime(); + ExclusiveStartDate = new DateTime(DateTime.Now.Year - 1, 4, 1, 00, 5, 00).ToUniversalTime(); + //################################################################################## + + + DateTime InclusiveEndDate = InclusiveStartDate.AddHours(1); + DateTime ExclusiveEndDate = ExclusiveStartDate.AddHours(1); + + //CREATE TEST WIDGETS + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = InclusiveStartDate; + w.endDate = InclusiveEndDate; + + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = ExclusiveStartDate; + w.endDate = ExclusiveEndDate; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = FilterToken; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + + /// + /// + /// + [Fact] + public async void DateTokenPast90DaysFilterWorks() + { + + var WidgetNameStart = "DateTokenPast90DaysFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //BUILD DATES FOR THIS TEST + + DateTime InclusiveStartDate; + DateTime ExclusiveStartDate; + + //################################################################################## + var FilterToken = TokenPast90Days; + InclusiveStartDate = DateTime.UtcNow.AddDays(-90).AddMinutes(5).ToUniversalTime(); + ExclusiveStartDate = DateTime.UtcNow.AddDays(-90).AddMinutes(-5).ToUniversalTime(); + //################################################################################## + + + DateTime InclusiveEndDate = InclusiveStartDate.AddHours(1); + DateTime ExclusiveEndDate = ExclusiveStartDate.AddHours(1); + + //CREATE TEST WIDGETS + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = InclusiveStartDate; + w.endDate = InclusiveEndDate; + + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = ExclusiveStartDate; + w.endDate = ExclusiveEndDate; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = FilterToken; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + /// + /// + /// + [Fact] + public async void DateTokenPast30DaysFilterWorks() + { + + var WidgetNameStart = "DateTokenPast30DaysFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //BUILD DATES FOR THIS TEST + + DateTime InclusiveStartDate; + DateTime ExclusiveStartDate; + + //################################################################################## + var FilterToken = TokenPast30Days; + InclusiveStartDate = DateTime.UtcNow.AddDays(-30).AddMinutes(5).ToUniversalTime(); + ExclusiveStartDate = DateTime.UtcNow.AddDays(-30).AddMinutes(-5).ToUniversalTime(); + //################################################################################## + + + DateTime InclusiveEndDate = InclusiveStartDate.AddHours(1); + DateTime ExclusiveEndDate = ExclusiveStartDate.AddHours(1); + + //CREATE TEST WIDGETS + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = InclusiveStartDate; + w.endDate = InclusiveEndDate; + + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = ExclusiveStartDate; + w.endDate = ExclusiveEndDate; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = FilterToken; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void DateTokenPast24HoursFilterWorks() + { + + var WidgetNameStart = "DateTokenPast24HoursFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //BUILD DATES FOR THIS TEST + + DateTime InclusiveStartDate; + DateTime ExclusiveStartDate; + + //################################################################################## + var FilterToken = TokenPast24Hours; + InclusiveStartDate = DateTime.UtcNow.AddHours(-24).AddMinutes(5).ToUniversalTime(); + ExclusiveStartDate = DateTime.UtcNow.AddHours(-24).AddMinutes(-5).ToUniversalTime(); + //################################################################################## + + + DateTime InclusiveEndDate = InclusiveStartDate.AddHours(1); + DateTime ExclusiveEndDate = ExclusiveStartDate.AddHours(1); + + //CREATE TEST WIDGETS + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = InclusiveStartDate; + w.endDate = InclusiveEndDate; + + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = ExclusiveStartDate; + w.endDate = ExclusiveEndDate; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //## INCLUSIVE FILTER + dynamic FilterItem = new JObject(); + FilterItem.fld = "startdate"; + FilterItem.op = Util.OpEquality; + FilterItem.value = FilterToken; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + #endregion date token filters + //======== + + #endregion date filter tests + + + + /////////////////////////////////////////////////////////////////////////////// + //TEXT + // + + #region STRING FILTER TESTS + + /// + /// + /// + [Fact] + public async void TextOpEqualityFilterWorks() + { + + var TestName = "TextOpEqualityFilterWorks"; + var WidgetRunNameStart = Util.Uniquify(TestName); + + List InclusiveWidgetIdList = new List(); + List ExclusiveWidgetIdList = new List(); + + //CREATE 4 TEST WIDGETS + //two inclusive and two not inclusive + + //first inclusive widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "aardvark"; + w.roles = 0; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second inclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //first exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "zebra"; + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetRunNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetRunNameStart; + dfilter.Add(DataFilterNameStart); + + //active bool test filter + dynamic DataFilterActive = new JObject(); + DataFilterActive.fld = "notes"; + DataFilterActive.op = Util.OpEquality; + DataFilterActive.value = "aardvark"; + dfilter.Add(DataFilterActive); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least two records + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(1); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (InclusiveWidgetIdList.Contains(o["id"].Value())) + InclusiveMatchCount++; + if (ExclusiveWidgetIdList.Contains(o["id"].Value())) + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().Be(InclusiveWidgetIdList.Count); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + foreach (long l in InclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + foreach (long l in ExclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + + + /// + /// Specifically test a string with an apostrophe in it (for inclusive) + /// + [Fact] + public async void TextApostropheOpEqualityFilterWorks() + { + + var TestName = "TextApostropheOpEqualityFilterWorks"; + var WidgetRunNameStart = Util.Uniquify(TestName); + + List InclusiveWidgetIdList = new List(); + List ExclusiveWidgetIdList = new List(); + + //CREATE 4 TEST WIDGETS + //two inclusive and two not inclusive + + //first inclusive widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "O'Flaherty's pub"; + w.roles = 0; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second inclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //first exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Outback steak house"; + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetRunNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetRunNameStart; + dfilter.Add(DataFilterNameStart); + + //active bool test filter + dynamic DataFilterActive = new JObject(); + DataFilterActive.fld = "notes"; + DataFilterActive.op = Util.OpEquality; + DataFilterActive.value = "O'Flaherty's pub"; + dfilter.Add(DataFilterActive); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least two records + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(1); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (InclusiveWidgetIdList.Contains(o["id"].Value())) + InclusiveMatchCount++; + if (ExclusiveWidgetIdList.Contains(o["id"].Value())) + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().Be(InclusiveWidgetIdList.Count); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + foreach (long l in InclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + foreach (long l in ExclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + /// + /// specifically test a string with an ampersand character in it for inclusive (finding it) + /// + [Fact] + public async void TextAmpersandOpEqualityFilterWorks() + { + + var TestName = "TextAmpersandOpEqualityFilterWorks"; + var WidgetRunNameStart = Util.Uniquify(TestName); + + List InclusiveWidgetIdList = new List(); + List ExclusiveWidgetIdList = new List(); + + //CREATE 4 TEST WIDGETS + //two inclusive and two not inclusive + + //first inclusive widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Bill & Ted's excellent adventure"; + w.roles = 0; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second inclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //first exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Strange things are afoot at the Circle-K"; + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetRunNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetRunNameStart; + dfilter.Add(DataFilterNameStart); + + //active bool test filter + dynamic DataFilterActive = new JObject(); + DataFilterActive.fld = "notes"; + DataFilterActive.op = Util.OpEquality; + DataFilterActive.value = "Bill & Ted's excellent adventure"; + dfilter.Add(DataFilterActive); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least two records + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(1); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (InclusiveWidgetIdList.Contains(o["id"].Value())) + InclusiveMatchCount++; + if (ExclusiveWidgetIdList.Contains(o["id"].Value())) + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().Be(InclusiveWidgetIdList.Count); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + foreach (long l in InclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + foreach (long l in ExclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + /// + /// specifically test a non english unicode string + /// + [Fact] + public async void TextUnicodeOpEqualityFilterWorks() + { + + var TestName = "TextUnicodeOpEqualityFilterWorks"; + var WidgetRunNameStart = Util.Uniquify(TestName); + + List InclusiveWidgetIdList = new List(); + List ExclusiveWidgetIdList = new List(); + + //CREATE 4 TEST WIDGETS + //two inclusive and two not inclusive + + //first inclusive widget + var InclusiveTestString = "Ādam Iñtërnâtiônàližætiøn"; + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = InclusiveTestString; + w.roles = 0; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second inclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //first exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Adam Internationalization"; + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetRunNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetRunNameStart; + dfilter.Add(DataFilterNameStart); + + //active bool test filter + dynamic DataFilterActive = new JObject(); + DataFilterActive.fld = "notes"; + DataFilterActive.op = Util.OpEquality; + DataFilterActive.value = InclusiveTestString; + dfilter.Add(DataFilterActive); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least two records + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(1); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (InclusiveWidgetIdList.Contains(o["id"].Value())) + InclusiveMatchCount++; + if (ExclusiveWidgetIdList.Contains(o["id"].Value())) + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().Be(InclusiveWidgetIdList.Count); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + foreach (long l in InclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + foreach (long l in ExclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void TextOpGreaterThanFilterWorks() + { + + var TestName = "TextOpGreaterThanFilterWorks"; + var WidgetRunNameStart = Util.Uniquify(TestName); + + List InclusiveWidgetIdList = new List(); + List ExclusiveWidgetIdList = new List(); + + //CREATE 4 TEST WIDGETS + //two inclusive and two not inclusive + + //first inclusive widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Alabama"; + w.roles = 0; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second inclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //first exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Aardvark"; + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetRunNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetRunNameStart; + dfilter.Add(DataFilterNameStart); + + //active bool test filter + dynamic DataFilterActive = new JObject(); + DataFilterActive.fld = "notes"; + DataFilterActive.op = Util.OpGreaterThan; + DataFilterActive.value = "Aardvark"; + dfilter.Add(DataFilterActive); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least two records + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(1); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (InclusiveWidgetIdList.Contains(o["id"].Value())) + InclusiveMatchCount++; + if (ExclusiveWidgetIdList.Contains(o["id"].Value())) + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().Be(InclusiveWidgetIdList.Count); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + foreach (long l in InclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + foreach (long l in ExclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void TextOpGreaterThanOrEqualToFilterWorks() + { + + var TestName = "TextOpGreaterThanOrEqualToFilterWorks"; + var WidgetRunNameStart = Util.Uniquify(TestName); + + List InclusiveWidgetIdList = new List(); + List ExclusiveWidgetIdList = new List(); + + //CREATE 4 TEST WIDGETS + //two inclusive and two not inclusive + + //first inclusive widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Bjorn"; + w.roles = 0; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second inclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //first exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Bing"; + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetRunNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetRunNameStart; + dfilter.Add(DataFilterNameStart); + + //active bool test filter + dynamic DataFilterActive = new JObject(); + DataFilterActive.fld = "notes"; + DataFilterActive.op = Util.OpGreaterThanOrEqualTo; + DataFilterActive.value = "Bjarn"; + dfilter.Add(DataFilterActive); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least two records + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(1); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (InclusiveWidgetIdList.Contains(o["id"].Value())) + InclusiveMatchCount++; + if (ExclusiveWidgetIdList.Contains(o["id"].Value())) + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().Be(InclusiveWidgetIdList.Count); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + foreach (long l in InclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + foreach (long l in ExclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void TextOpLessThanFilterWorks() + { + + var TestName = "TextOpLessThanFilterWorks"; + var WidgetRunNameStart = Util.Uniquify(TestName); + + List InclusiveWidgetIdList = new List(); + List ExclusiveWidgetIdList = new List(); + + //CREATE 4 TEST WIDGETS + //two inclusive and two not inclusive + + //first inclusive widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "California"; + w.roles = 0; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second inclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //first exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Cthulu"; + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetRunNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetRunNameStart; + dfilter.Add(DataFilterNameStart); + + //active bool test filter + dynamic DataFilterActive = new JObject(); + DataFilterActive.fld = "notes"; + DataFilterActive.op = Util.OpLessThan; + DataFilterActive.value = "Celery"; + dfilter.Add(DataFilterActive); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least two records + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(1); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (InclusiveWidgetIdList.Contains(o["id"].Value())) + InclusiveMatchCount++; + if (ExclusiveWidgetIdList.Contains(o["id"].Value())) + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().Be(InclusiveWidgetIdList.Count); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + foreach (long l in InclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + foreach (long l in ExclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void TextOpLessThanOrEqualToFilterWorks() + { + + var TestName = "TextOpLessThanOrEqualToFilterWorks"; + var WidgetRunNameStart = Util.Uniquify(TestName); + + List InclusiveWidgetIdList = new List(); + List ExclusiveWidgetIdList = new List(); + + //CREATE 4 TEST WIDGETS + //two inclusive and two not inclusive + + //first inclusive widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Donut"; + w.roles = 0; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second inclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //first exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Duvet"; + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetRunNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetRunNameStart; + dfilter.Add(DataFilterNameStart); + + //active bool test filter + dynamic DataFilterActive = new JObject(); + DataFilterActive.fld = "notes"; + DataFilterActive.op = Util.OpLessThanOrEqualTo; + DataFilterActive.value = "Dusseldorf"; + dfilter.Add(DataFilterActive); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least two records + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(1); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (InclusiveWidgetIdList.Contains(o["id"].Value())) + InclusiveMatchCount++; + if (ExclusiveWidgetIdList.Contains(o["id"].Value())) + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().Be(InclusiveWidgetIdList.Count); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + foreach (long l in InclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + foreach (long l in ExclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + /// + /// + /// + [Fact] + public async void TextOpNotEqualFilterWorks() + { + + var TestName = "TextOpNotEqualFilterWorks"; + var WidgetRunNameStart = Util.Uniquify(TestName); + + List InclusiveWidgetIdList = new List(); + List ExclusiveWidgetIdList = new List(); + + //CREATE 4 TEST WIDGETS + //two inclusive and two not inclusive + + //first inclusive widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Egg Salad Sandwich"; + w.roles = 0; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second inclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //first exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Elephant"; + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetRunNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetRunNameStart; + dfilter.Add(DataFilterNameStart); + + //active bool test filter + dynamic DataFilterActive = new JObject(); + DataFilterActive.fld = "notes"; + DataFilterActive.op = Util.OpNotEqual; + DataFilterActive.value = "Elephant"; + dfilter.Add(DataFilterActive); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least two records + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(1); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (InclusiveWidgetIdList.Contains(o["id"].Value())) + InclusiveMatchCount++; + if (ExclusiveWidgetIdList.Contains(o["id"].Value())) + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().Be(InclusiveWidgetIdList.Count); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + foreach (long l in InclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + foreach (long l in ExclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void TextOpNotContainsFilterWorks() + { + var TestName = "TextOpNotContainsFilterWorks"; + var WidgetRunNameStart = Util.Uniquify(TestName); + + List InclusiveWidgetIdList = new List(); + List ExclusiveWidgetIdList = new List(); + + //CREATE 4 TEST WIDGETS + //two inclusive and two not inclusive + + //first inclusive widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Gray poupon"; + w.roles = 0; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second inclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //first exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Get shorty"; + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetRunNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetRunNameStart; + dfilter.Add(DataFilterNameStart); + + //active bool test filter + dynamic DataFilterActive = new JObject(); + DataFilterActive.fld = "notes"; + DataFilterActive.op = Util.OpNotContains; + DataFilterActive.value = "short"; + dfilter.Add(DataFilterActive); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least two records + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(1); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (InclusiveWidgetIdList.Contains(o["id"].Value())) + InclusiveMatchCount++; + if (ExclusiveWidgetIdList.Contains(o["id"].Value())) + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().Be(InclusiveWidgetIdList.Count); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + foreach (long l in InclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + foreach (long l in ExclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void TextOpContainsFilterWorks() + { + var TestName = "TextOpContainsFilterWorks"; + var WidgetRunNameStart = Util.Uniquify(TestName); + + List InclusiveWidgetIdList = new List(); + List ExclusiveWidgetIdList = new List(); + + //CREATE 4 TEST WIDGETS + //two inclusive and two not inclusive + + //first inclusive widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Fast Freddy Freak"; + w.roles = 0; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second inclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //first exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Phineas Freak"; + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetRunNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetRunNameStart; + dfilter.Add(DataFilterNameStart); + + //active bool test filter + dynamic DataFilterActive = new JObject(); + DataFilterActive.fld = "notes"; + DataFilterActive.op = Util.OpContains; + DataFilterActive.value = "red"; + dfilter.Add(DataFilterActive); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least two records + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(1); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (InclusiveWidgetIdList.Contains(o["id"].Value())) + InclusiveMatchCount++; + if (ExclusiveWidgetIdList.Contains(o["id"].Value())) + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().Be(InclusiveWidgetIdList.Count); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + foreach (long l in InclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + foreach (long l in ExclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void TextOpStartsWithFilterWorks() + { + var TestName = "TextOpStartsWithFilterWorks"; + var WidgetRunNameStart = Util.Uniquify(TestName); + + List InclusiveWidgetIdList = new List(); + List ExclusiveWidgetIdList = new List(); + + //CREATE 4 TEST WIDGETS + //two inclusive and two not inclusive + + //first inclusive widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Granular"; + w.roles = 0; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second inclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //first exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Gus Grifferson"; + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetRunNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetRunNameStart; + dfilter.Add(DataFilterNameStart); + + //active bool test filter + dynamic DataFilterActive = new JObject(); + DataFilterActive.fld = "notes"; + DataFilterActive.op = Util.OpStartsWith; + DataFilterActive.value = "Gra"; + dfilter.Add(DataFilterActive); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least two records + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(1); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (InclusiveWidgetIdList.Contains(o["id"].Value())) + InclusiveMatchCount++; + if (ExclusiveWidgetIdList.Contains(o["id"].Value())) + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().Be(InclusiveWidgetIdList.Count); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + foreach (long l in InclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + foreach (long l in ExclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + + /// + /// + /// + [Fact] + public async void TextOpEndsWithFilterWorks() + { + var TestName = "TextOpEndsWithFilterWorks"; + var WidgetRunNameStart = Util.Uniquify(TestName); + + List InclusiveWidgetIdList = new List(); + List ExclusiveWidgetIdList = new List(); + + //CREATE 4 TEST WIDGETS + //two inclusive and two not inclusive + + //first inclusive widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Bo Horvat"; + w.roles = 0; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second inclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //first exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.notes = "Bo Duke"; + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetRunNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetRunNameStart; + dfilter.Add(DataFilterNameStart); + + //active bool test filter + dynamic DataFilterActive = new JObject(); + DataFilterActive.fld = "notes"; + DataFilterActive.op = Util.OpEndsWith; + DataFilterActive.value = "vat"; + dfilter.Add(DataFilterActive); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least two records + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(1); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (InclusiveWidgetIdList.Contains(o["id"].Value())) + InclusiveMatchCount++; + if (ExclusiveWidgetIdList.Contains(o["id"].Value())) + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().Be(InclusiveWidgetIdList.Count); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + foreach (long l in InclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + foreach (long l in ExclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + + + + + + //====================== + + #endregion string filter tests + + /////////////////////////////////////////////////////////////////////////////// + //INT + // + #region INTEGER TESTS + + /// + /// + /// + [Fact] + public async void IntegerOpEqualityFilterWorks() + { + + var WidgetNameStart = "IntegerDataFilterTest"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.active = true; + w.roles = 0; + w.count = 5; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.count = 3; + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify("Test INT DataFilter"); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //inclusive test filter + + dynamic FilterItem = new JObject(); + FilterItem.fld = "count"; + FilterItem.op = Util.OpEquality; + FilterItem.value = 5; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + /// + /// + /// + [Fact] + public async void IntegerOpGreaterThanFilterWorks() + { + + var WidgetNameStart = "IntegerOpGreaterThanFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.active = true; + w.roles = 0; + w.count = 55; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.count = -55; + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify("Test INT DataFilter"); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //inclusive test filter + + dynamic FilterItem = new JObject(); + FilterItem.fld = "count"; + FilterItem.op = Util.OpGreaterThan; + FilterItem.value = 54; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + /// + /// + /// + [Fact] + public async void IntegerOpGreaterThanOrEqualToFilterWorks() + { + + var WidgetNameStart = "IntegerOpGreaterThanOrEqualToFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.active = true; + w.roles = 0; + w.count = 555; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.count = 554; + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify("IntegerOpGreaterThanOrEqualToFilterWorks"); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //inclusive test filter + + dynamic FilterItem = new JObject(); + FilterItem.fld = "count"; + FilterItem.op = Util.OpGreaterThanOrEqualTo; + FilterItem.value = 555; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + + + /// + /// + /// + [Fact] + public async void IntegerOpLessThanFilterWorks() + { + + var WidgetNameStart = "IntegerOpLessThanFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.active = true; + w.roles = 0; + w.count = -5555; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.count = 5555; + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify("IntegerOpLessThanFilterWorks"); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //inclusive test filter + + dynamic FilterItem = new JObject(); + FilterItem.fld = "count"; + FilterItem.op = Util.OpLessThan; + FilterItem.value = 5555; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + + /// + /// + /// + [Fact] + public async void IntegerOpLessThanOrEqualToFilterWorks() + { + + var WidgetNameStart = "IntegerOpLessThanOrEqualToFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.active = true; + w.roles = 0; + w.count = -444; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.count = -443; + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify("IntegerOpLessThanOrEqualToFilterWorks"); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //inclusive test filter + + dynamic FilterItem = new JObject(); + FilterItem.fld = "count"; + FilterItem.op = Util.OpLessThanOrEqualTo; + FilterItem.value = -444; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + + + /// + /// + /// + [Fact] + public async void IntegerNotEqualToFilterWorks() + { + + var WidgetNameStart = "IntegerNotEqualToFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.active = true; + w.roles = 0; + w.count = 222; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.count = 223; + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify("IntegerNotEqualToFilterWorks"); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //inclusive test filter + + dynamic FilterItem = new JObject(); + FilterItem.fld = "count"; + FilterItem.op = Util.OpNotEqual; + FilterItem.value = 223; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + } + #endregion integer tests + + + /////////////////////////////////////////////////////////////////////////////// + //BOOL + // + + #region BOOLEAN TESTS + + /// + /// + /// + [Fact] + public async void BoolOpEqualityFilterWorks() + { + + //OPS: equal to, not equal to + //values: true, false + + var WidgetNameStart = "BoolDataFilterTest"; + + List ActiveWidgetIdList = new List(); + List NotActiveWidgetIdList = new List(); + + //CREATE 4 TEST WIDGETS + //two active and two non active + + //first active widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.active = true; + w.roles = 0; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ActiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second active widget + w.name = Util.Uniquify(WidgetNameStart); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ActiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //first NON active widget + w.name = Util.Uniquify(WidgetNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + NotActiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second NON active widget + w.name = Util.Uniquify(WidgetNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + NotActiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify("Test BOOL DataFilter"); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //active bool test filter + dynamic DataFilterActive = new JObject(); + DataFilterActive.fld = "active"; + DataFilterActive.op = Util.OpEquality; + DataFilterActive.value = true; + dfilter.Add(DataFilterActive); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least two records + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(1); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int nActiveMatches = 0; + int nInactiveMatches = 0; + foreach (JObject o in v) + { + if (ActiveWidgetIdList.Contains(o["id"].Value())) + nActiveMatches++; + if (NotActiveWidgetIdList.Contains(o["id"].Value())) + nInactiveMatches++; + } + + nActiveMatches.Should().Be(ActiveWidgetIdList.Count); + nInactiveMatches.Should().Be(0); + + //DELETE WIDGETS + foreach (long l in ActiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + foreach (long l in NotActiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + + + /// + /// + /// + [Fact] + public async void BoolOpNotEqualFilterWorks() + { + + //OPS: equal to, not equal to + //values: true, false + + var WidgetNameStart = "BoolDataFilterTest"; + + List ActiveWidgetIdList = new List(); + List NotActiveWidgetIdList = new List(); + + //CREATE 4 TEST WIDGETS + //two active and two non active + + //first active widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.active = true; + w.roles = 0; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ActiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second active widget + w.name = Util.Uniquify(WidgetNameStart); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ActiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //first NON active widget + w.name = Util.Uniquify(WidgetNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + NotActiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second NON active widget + w.name = Util.Uniquify(WidgetNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + NotActiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify("Test BOOL DataFilter"); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //active bool test filter + dynamic DataFilterActive = new JObject(); + DataFilterActive.fld = "active"; + DataFilterActive.op = Util.OpNotEqual; + DataFilterActive.value = true; + dfilter.Add(DataFilterActive); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least two records + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(1); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int nActiveMatches = 0; + int nInactiveMatches = 0; + foreach (JObject o in v) + { + if (ActiveWidgetIdList.Contains(o["id"].Value())) + nActiveMatches++; + if (NotActiveWidgetIdList.Contains(o["id"].Value())) + nInactiveMatches++; + } + + nInactiveMatches.Should().Be(NotActiveWidgetIdList.Count); + nActiveMatches.Should().Be(0); + + //DELETE WIDGETS + foreach (long l in ActiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + foreach (long l in NotActiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + #endregion boolean tests + + + /////////////////////////////////////////////////////////////////////////////// + //DECIMAL + // + #region DECIMAL TESTS + + /// + /// + /// + [Fact] + public async void DecimalOpEqualityFilterWorks() + { + + var WidgetNameStart = "DecimalOpEqualityFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.active = true; + w.roles = 0; + w.dollarAmount = 5.55; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.dollarAmount = 3.33; + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify("DecimalOpEqualityFilterWorks"); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //inclusive test filter + + dynamic FilterItem = new JObject(); + FilterItem.fld = "dollaramount"; + FilterItem.op = Util.OpEquality; + FilterItem.value = 5.55; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + /// + /// + /// + [Fact] + public async void DecimalOpGreaterThanFilterWorks() + { + + var WidgetNameStart = "DecimalOpGreaterThanFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.active = true; + w.roles = 0; + w.dollarAmount = 55.55; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.dollarAmount = -55.55; + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify("DecimalOpGreaterThanFilterWorks"); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //inclusive test filter + + dynamic FilterItem = new JObject(); + FilterItem.fld = "dollaramount"; + FilterItem.op = Util.OpGreaterThan; + FilterItem.value = 54.44; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + /// + /// + /// + [Fact] + public async void DecimalOpGreaterThanOrEqualToFilterWorks() + { + + var WidgetNameStart = "DecimalOpGreaterThanOrEqualToFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.active = true; + w.roles = 0; + w.dollarAmount = 555.55; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.dollarAmount = 554.54; + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify("DecimalOpGreaterThanOrEqualToFilterWorks"); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //inclusive test filter + + dynamic FilterItem = new JObject(); + FilterItem.fld = "dollaramount"; + FilterItem.op = Util.OpGreaterThanOrEqualTo; + FilterItem.value = 555.55; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + + + /// + /// + /// + [Fact] + public async void DecimalOpLessThanFilterWorks() + { + + var WidgetNameStart = "DecimalOpLessThanFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.active = true; + w.roles = 0; + w.dollarAmount = -5555.55; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.dollarAmount = 5555.55; + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify("DecimalOpLessThanFilterWorks"); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //inclusive test filter + + dynamic FilterItem = new JObject(); + FilterItem.fld = "dollaramount"; + FilterItem.op = Util.OpLessThan; + FilterItem.value = 5555.55; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + + /// + /// + /// + [Fact] + public async void DecimalOpLessThanOrEqualToFilterWorks() + { + + var WidgetNameStart = "DecimalOpLessThanOrEqualToFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.active = true; + w.roles = 0; + w.dollarAmount = -444.44; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.dollarAmount = -443.43; + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify("DecimalOpLessThanOrEqualToFilterWorks"); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //inclusive test filter + + dynamic FilterItem = new JObject(); + FilterItem.fld = "dollaramount"; + FilterItem.op = Util.OpLessThanOrEqualTo; + FilterItem.value = -444.44; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + + + /// + /// + /// + [Fact] + public async void DecimalNotEqualToFilterWorks() + { + + var WidgetNameStart = "DecimalNotEqualToFilterWorks"; + + long IncludedWidgetId = 0; + long ExcludedWidgetId = 0; + + //CREATE TEST WIDGETS + + //included widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.active = true; + w.roles = 0; + w.dollarAmount = 222.22; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + IncludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + //Excluded widget + w.name = Util.Uniquify(WidgetNameStart); + w.dollarAmount = 223.23; + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExcludedWidgetId = a.ObjectResponse["data"]["id"].Value(); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify("DecimalNotEqualToFilterWorks"); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + + //inclusive test filter + + dynamic FilterItem = new JObject(); + FilterItem.fld = "dollaramount"; + FilterItem.op = Util.OpNotEqual; + FilterItem.value = 223.23; + dfilter.Add(FilterItem); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least this test record + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (IncludedWidgetId == o["id"].Value()) + InclusiveMatchCount++; + if (ExcludedWidgetId == o["id"].Value())//whups + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().BeGreaterOrEqualTo(1); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + a = await Util.DeleteAsync("Widget/" + IncludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ExcludedWidgetId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + } + #endregion decimal tests + + /////////////////////////////////////////////////////////////////////////////// + //TAGS + // + #region TAG TESTS + + /// + /// + /// + [Fact] + public async void TagFilterWorks() + { + + var TestName = "TagFilterWorks"; + var WidgetRunNameStart = Util.Uniquify(TestName); + + List InclusiveWidgetIdList = new List(); + List ExclusiveWidgetIdList = new List(); + + //CREATE 4 TEST WIDGETS + //two inclusive and two not inclusive + + //first inclusive widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetRunNameStart); + //Tags + dynamic InclusiveTagsArray = new JArray(); + InclusiveTagsArray.Add("red-tag-test"); + InclusiveTagsArray.Add("orange-tag-test"); + InclusiveTagsArray.Add("yellow-tag-test"); + InclusiveTagsArray.Add("green-tag-test"); + InclusiveTagsArray.Add("blue-tag-test"); + InclusiveTagsArray.Add("indigo-tag-test"); + InclusiveTagsArray.Add("violet-tag-test"); + w.tags = InclusiveTagsArray; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second inclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //first exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + //Tags + dynamic ExclusiveTagsArray = new JArray(); + ExclusiveTagsArray.Add("crimson-tag-test"); + ExclusiveTagsArray.Add("amber-tag-test"); + ExclusiveTagsArray.Add("saffron-tag-test"); + ExclusiveTagsArray.Add("emerald-tag-test"); + ExclusiveTagsArray.Add("azure-tag-test"); + ExclusiveTagsArray.Add("red-tag-test"); + ExclusiveTagsArray.Add("blue-tag-test"); + ExclusiveTagsArray.Add("cobalt-tag-test"); + ExclusiveTagsArray.Add("magenta-tag-test"); + w.tags = ExclusiveTagsArray;//Missing green + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetRunNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetRunNameStart; + dfilter.Add(DataFilterNameStart); + + //active test filter + dynamic DataFilterActive = new JObject(); + DataFilterActive.fld = "tags"; + DataFilterActive.op = Util.OpEquality; + dynamic FilterTagsArray = new JArray(); + FilterTagsArray.Add("red-tag-test"); + FilterTagsArray.Add("green-tag-test");//green is the only one missing from the exclusive widget + FilterTagsArray.Add("blue-tag-test"); + DataFilterActive.value = FilterTagsArray; + dfilter.Add(DataFilterActive); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least two records + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(1); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (InclusiveWidgetIdList.Contains(o["id"].Value())) + InclusiveMatchCount++; + if (ExclusiveWidgetIdList.Contains(o["id"].Value())) + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().Be(InclusiveWidgetIdList.Count); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + foreach (long l in InclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + foreach (long l in ExclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + /// + /// + /// + [Fact] + public async void UnicodeTagFilterWorks() + { + + var TestName = "UnicodeTagFilterWorks"; + var WidgetRunNameStart = Util.Uniquify(TestName); + + List InclusiveWidgetIdList = new List(); + List ExclusiveWidgetIdList = new List(); + + //CREATE 4 TEST WIDGETS + //two inclusive and two not inclusive + + //first inclusive widget + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetRunNameStart); + //Tags + dynamic InclusiveTagsArray = new JArray(); + InclusiveTagsArray.Add("red-tag-test"); + InclusiveTagsArray.Add("orange-tag-test"); + InclusiveTagsArray.Add("Ādam Iñtërnâtiônàližætiøn"); + w.tags = InclusiveTagsArray; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second inclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + InclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //first exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + //Tags + dynamic ExclusiveTagsArray = new JArray(); + ExclusiveTagsArray.Add("crimson-tag-test"); + ExclusiveTagsArray.Add("amber-tag-test"); + ExclusiveTagsArray.Add("saffron-tag-test"); + ExclusiveTagsArray.Add("emerald-tag-test"); + ExclusiveTagsArray.Add("azure-tag-test"); + ExclusiveTagsArray.Add("red-tag-test"); + ExclusiveTagsArray.Add("blue-tag-test"); + ExclusiveTagsArray.Add("cobalt-tag-test"); + ExclusiveTagsArray.Add("magenta-tag-test"); + w.tags = ExclusiveTagsArray;//Missing green + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + //second exclusive widget + w.name = Util.Uniquify(WidgetRunNameStart); + w.active = false; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ExclusiveWidgetIdList.Add(a.ObjectResponse["data"]["id"].Value()); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetRunNameStart); + // d.ownerId = 1L; + d["public"] = true; + d.listKey = "widget"; + + dynamic dfilter = new JArray(); + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetRunNameStart; + dfilter.Add(DataFilterNameStart); + + //active test filter + dynamic DataFilterActive = new JObject(); + DataFilterActive.fld = "tags"; + DataFilterActive.op = Util.OpEquality; + dynamic FilterTagsArray = new JArray(); + FilterTagsArray.Add("red-tag-test"); + FilterTagsArray.Add("Ādam Iñtërnâtiônàližætiøn"); + DataFilterActive.value = FilterTagsArray; + dfilter.Add(DataFilterActive); + + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains at least two records + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(1); + var v = ((JArray)a.ObjectResponse["data"]); + List IDInResultList = new List(); + int InclusiveMatchCount = 0; + int ExclusiveMatchCount = 0; + foreach (JObject o in v) + { + if (InclusiveWidgetIdList.Contains(o["id"].Value())) + InclusiveMatchCount++; + if (ExclusiveWidgetIdList.Contains(o["id"].Value())) + ExclusiveMatchCount++; + } + + InclusiveMatchCount.Should().Be(InclusiveWidgetIdList.Count); + ExclusiveMatchCount.Should().Be(0); + + //DELETE WIDGETS + foreach (long l in InclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + foreach (long l in ExclusiveWidgetIdList) + { + a = await Util.DeleteAsync("Widget/" + l.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + #endregion tag tests + //================================================== + + }//eoc +}//eons diff --git a/DataFilter/DataFilterOrderBy.cs b/DataFilter/DataFilterOrderBy.cs new file mode 100644 index 0000000..f1d7686 --- /dev/null +++ b/DataFilter/DataFilterOrderBy.cs @@ -0,0 +1,439 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace raven_integration +{ + + + public class DataFilterOrderBy + { + + /// + /// + /// + [Fact] + public async void DefaultSortByIdWorks() + { + + var WidgetNameStart = Util.Uniquify("DefaultSortByIdWorks"); + + //CREATE 3 TEST WIDGETS TO TEST ORDER + long FirstInOrderWidgetId = 0; + long SecondInOrderWidgetId = 0; + long ThirdInOrderWidgetId = 0; + + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ThirdInOrderWidgetId = a.ObjectResponse["data"]["id"].Value(); + + w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + SecondInOrderWidgetId = a.ObjectResponse["data"]["id"].Value(); + + w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + FirstInOrderWidgetId = a.ObjectResponse["data"]["id"].Value(); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + d["public"] = true; + d.listKey = "widget"; + dynamic dfilter = new JArray(); + + + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + d.filter = dfilter.ToString();//it expects it to be a json string, not actual json + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("manager", "l3tm3in"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains exactly 3 records + ((JArray)a.ObjectResponse["data"]).Count.Should().Be(3); + + //assert the order returned + a.ObjectResponse["data"][0]["id"].Value().Should().Be(FirstInOrderWidgetId); + a.ObjectResponse["data"][1]["id"].Value().Should().Be(SecondInOrderWidgetId); + a.ObjectResponse["data"][2]["id"].Value().Should().Be(ThirdInOrderWidgetId); + + + a = await Util.DeleteAsync("Widget/" + FirstInOrderWidgetId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + SecondInOrderWidgetId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ThirdInOrderWidgetId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + + /// + /// + /// + [Fact] + public async void SortByFieldAscendingWorks() + { + + var WidgetNameStart = Util.Uniquify("SortByFieldAscendingWorks"); + + //CREATE 3 TEST WIDGETS TO TEST ORDER + long FirstInOrderWidgetId = 0; + long SecondInOrderWidgetId = 0; + long ThirdInOrderWidgetId = 0; + + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = DateTime.Now; + w.endDate = DateTime.Now.AddHours(1); + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + FirstInOrderWidgetId = a.ObjectResponse["data"]["id"].Value(); + + w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = DateTime.Now.AddHours(1); + w.endDate = DateTime.Now.AddHours(2); + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + SecondInOrderWidgetId = a.ObjectResponse["data"]["id"].Value(); + + w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.startDate = DateTime.Now.AddHours(2); + w.endDate = DateTime.Now.AddHours(3); + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ThirdInOrderWidgetId = a.ObjectResponse["data"]["id"].Value(); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + d["public"] = true; + d.listKey = "widget"; + + //FILTER IN BY NAME FOR TESTING THIS RUN ONLY + dynamic dfilter = new JArray(); + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + d.filter = dfilter.ToString(); + + //SORT ORDER ################### + dynamic dsortarray = new JArray(); + dynamic dsort = new JObject(); + dsort.fld = "startdate"; + dsort.dir = "+"; + dsortarray.Add(dsort); + d.sort = dsortarray.ToString(); + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("manager", "l3tm3in"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains exactly 3 records + ((JArray)a.ObjectResponse["data"]).Count.Should().Be(3); + + //assert the order returned + a.ObjectResponse["data"][0]["id"].Value().Should().Be(FirstInOrderWidgetId); + a.ObjectResponse["data"][1]["id"].Value().Should().Be(SecondInOrderWidgetId); + a.ObjectResponse["data"][2]["id"].Value().Should().Be(ThirdInOrderWidgetId); + + + a = await Util.DeleteAsync("Widget/" + FirstInOrderWidgetId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + SecondInOrderWidgetId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ThirdInOrderWidgetId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + + + /// + /// + /// + [Fact] + public async void SortByFieldDescendingWorks() + { + + var WidgetNameStart = Util.Uniquify("SortByFieldDescendingWorks"); + + //CREATE 3 TEST WIDGETS TO TEST ORDER + long FirstInOrderWidgetId = 0; + long SecondInOrderWidgetId = 0; + long ThirdInOrderWidgetId = 0; + + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.count = 999; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + FirstInOrderWidgetId = a.ObjectResponse["data"]["id"].Value(); + + w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.count = 666; + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + SecondInOrderWidgetId = a.ObjectResponse["data"]["id"].Value(); + + w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.count = 333; + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ThirdInOrderWidgetId = a.ObjectResponse["data"]["id"].Value(); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + d["public"] = true; + d.listKey = "widget"; + + //FILTER IN BY NAME FOR TESTING THIS RUN ONLY + dynamic dfilter = new JArray(); + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + d.filter = dfilter.ToString(); + + //SORT ORDER ################### + dynamic dsortarray = new JArray(); + dynamic dsort = new JObject(); + dsort.fld = "count"; + dsort.dir = "-"; + dsortarray.Add(dsort); + d.sort = dsortarray.ToString(); + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("manager", "l3tm3in"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains exactly 3 records + ((JArray)a.ObjectResponse["data"]).Count.Should().Be(3); + + //assert the order returned + a.ObjectResponse["data"][0]["id"].Value().Should().Be(FirstInOrderWidgetId); + a.ObjectResponse["data"][1]["id"].Value().Should().Be(SecondInOrderWidgetId); + a.ObjectResponse["data"][2]["id"].Value().Should().Be(ThirdInOrderWidgetId); + + + a = await Util.DeleteAsync("Widget/" + FirstInOrderWidgetId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + SecondInOrderWidgetId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ThirdInOrderWidgetId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + + + + + /// + /// + /// + [Fact] + public async void SortByMultipleFieldsWorks() + { + /* + + Created order: + dollaramount, count + 2,1 + 1,2 + 2,2 + 1,1 + + + sorted order: + dollar asc, count desc + 1,2 + 1,1 + 2,2 + 2,1 + + */ + var WidgetNameStart = Util.Uniquify("SortByMultipleFieldsWorks"); + + //CREATE 4 TEST WIDGETS TO TEST ORDER + long FirstInOrderWidgetId = 0; + long SecondInOrderWidgetId = 0; + long ThirdInOrderWidgetId = 0; + long FourthInOrderWidgetId = 0; + + dynamic w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.dollaramount = 2.22; + w.count = 1; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + FourthInOrderWidgetId = a.ObjectResponse["data"]["id"].Value(); + + w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.dollaramount = 1.11; + w.count = 2; + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + FirstInOrderWidgetId = a.ObjectResponse["data"]["id"].Value(); + + w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.dollaramount = 1.11; + w.count = 1; + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + SecondInOrderWidgetId = a.ObjectResponse["data"]["id"].Value(); + + w = new JObject(); + w.name = Util.Uniquify(WidgetNameStart); + w.dollaramount = 2.22; + w.count = 2; + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString()); + Util.ValidateDataReturnResponseOk(a); + ThirdInOrderWidgetId = a.ObjectResponse["data"]["id"].Value(); + + + //CREATE FILTER + dynamic d = new JObject(); + d.name = Util.Uniquify(WidgetNameStart); + d["public"] = true; + d.listKey = "widget"; + + //FILTER IN BY NAME FOR TESTING THIS RUN ONLY + dynamic dfilter = new JArray(); + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = WidgetNameStart; + dfilter.Add(DataFilterNameStart); + d.filter = dfilter.ToString(); + + //SORT ORDER ################### + dynamic dsortarray = new JArray(); + + //First column + dynamic dsort1 = new JObject(); + dsort1.fld = "dollaramount"; + dsort1.dir = "+"; + dsortarray.Add(dsort1); + + //Second column + dynamic dsort2 = new JObject(); + dsort2.fld = "count"; + dsort2.dir = "-"; + dsortarray.Add(dsort2); + + + d.sort = dsortarray.ToString(); + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("manager", "l3tm3in"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"Widget/listwidgets?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains exactly 3 records + ((JArray)a.ObjectResponse["data"]).Count.Should().Be(4); + + //assert the order returned + a.ObjectResponse["data"][0]["id"].Value().Should().Be(FirstInOrderWidgetId); + a.ObjectResponse["data"][1]["id"].Value().Should().Be(SecondInOrderWidgetId); + a.ObjectResponse["data"][2]["id"].Value().Should().Be(ThirdInOrderWidgetId); + a.ObjectResponse["data"][3]["id"].Value().Should().Be(FourthInOrderWidgetId); + + + a = await Util.DeleteAsync("Widget/" + FirstInOrderWidgetId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + SecondInOrderWidgetId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + ThirdInOrderWidgetId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("Widget/" + FourthInOrderWidgetId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + //======================================================================== + + }//eoc +}//eons diff --git a/Enum/EnumListOps.cs b/Enum/EnumListOps.cs new file mode 100644 index 0000000..bd8fba5 --- /dev/null +++ b/Enum/EnumListOps.cs @@ -0,0 +1,48 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; + +namespace raven_integration +{ + + public class EnumListOps + { + + + /// + /// + /// + [Fact] + public async void GetListOfEnumListsWorks() + { + ApiResponse a = await Util.GetAsync("AyaEnumPickList/listkeys", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(2); + a.ObjectResponse["data"][0]["key"].Value().Should().Be("usertypes"); + } + + /// + /// + /// + [Fact] + public async void GetSpecificEnumListWorks() + { + ApiResponse a = await Util.GetAsync("AyaEnumPickList/list/usertypes", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(5); + a.ObjectResponse["data"][3]["name"].Value().Should().Be("Client user"); + a.ObjectResponse["data"][3]["id"].Value().Should().Be(4); + } + + + + + //================================================== + + }//eoc +}//eons diff --git a/EventLog/EventLog.cs b/EventLog/EventLog.cs new file mode 100644 index 0000000..859197c --- /dev/null +++ b/EventLog/EventLog.cs @@ -0,0 +1,122 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace raven_integration +{ + + public class EventLog + { + + + + /// + /// + /// + [Fact] + public async void ObjectLogWorks() + { + //CRUD a widget and confirm it logs properly + //http://localhost:7575/api/v8.0/EventLog/UserLog?AyType=3&AyId=1 + //http://localhost:7575/api/v8.0/EventLog/ObjectLog?AyType=2&AyId=242 + //http://localhost:7575/api/v8.0/EventLog/UserLog?AyType=3&AyId=1&StartDate=2018-08-23&EndDate=2018-08-24 + + dynamic w = new JObject(); + w.name = Util.Uniquify("EventLog Test WIDGET"); + w.created = DateTime.Now.ToString(); + w.dollarAmount = 2.22m; + w.active = true; + w.roles = 0; + + ApiResponse r2 = await Util.PostAsync("Widget", await Util.GetTokenAsync("InventoryFull"), w.ToString()); + Util.ValidateDataReturnResponseOk(r2); + long w2Id = r2.ObjectResponse["data"]["id"].Value(); + + ApiResponse EventLogResponse = await Util.GetAsync($"EventLog/ObjectLog?AyType=2&AyId={w2Id}", await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(EventLogResponse, 200); + + //NOTE:was failing here, for no reason that makes any sense it thinks there are two created events by two users for the same widget. + //might have been some temporary bad code in the seeder at one point when I was experimenting with async stuff + + + ((JArray)EventLogResponse.ObjectResponse["data"]).Count.Should().Be(1);//only one event so far + EventLogResponse.ObjectResponse["data"][0]["date"].Value().Should().BeLessThan(new TimeSpan(1, 0, 0)).Before(DateTime.UtcNow);//should be less than one hour before now + EventLogResponse.ObjectResponse["data"][0]["userId"].Should().NotBeNull(); + EventLogResponse.ObjectResponse["data"][0]["event"].Value().Should().Be(1);//AyEvent 1 = created + EventLogResponse.ObjectResponse["data"][0]["textra"].Should().BeNullOrEmpty(); + + //Get current user doing modifications ID + long CurrentUserId = EventLogResponse.ObjectResponse["data"][0]["userId"].Value(); + + //RETRIEVE + + //Get one + ApiResponse r3 = await Util.GetAsync("Widget/" + w2Id.ToString(), await Util.GetTokenAsync("InventoryFull")); + Util.ValidateDataReturnResponseOk(r3); + r3.ObjectResponse["data"]["name"].Value().Should().Be(w.name.ToString()); + + EventLogResponse = await Util.GetAsync($"EventLog/ObjectLog?AyType=2&AyId={w2Id}", await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(EventLogResponse, 200); + ((JArray)EventLogResponse.ObjectResponse["data"]).Count.Should().Be(2); + EventLogResponse.ObjectResponse["data"][1]["date"].Value().Should().BeLessThan(new TimeSpan(1, 0, 0)).Before(DateTime.UtcNow);//should be less than one hour before now + EventLogResponse.ObjectResponse["data"][1]["userId"].Should().NotBeNull(); + EventLogResponse.ObjectResponse["data"][1]["event"].Value().Should().Be(2);//AyEvent 2 = retrieved + EventLogResponse.ObjectResponse["data"][1]["textra"].Should().BeNullOrEmpty(); + + + + //UPDATE + //PUT + + //update w2id + w.name = Util.Uniquify("UPDATED VIA PUT EVENTLOG TEST WIDGET"); + w.OwnerId = 1; + w.concurrencyToken = r2.ObjectResponse["data"]["concurrencyToken"].Value(); + ApiResponse PUTTestResponse = await Util.PutAsync("Widget/" + w2Id.ToString(), await Util.GetTokenAsync("InventoryFull"), w.ToString()); + Util.ValidateHTTPStatusCode(PUTTestResponse, 200); + + //check PUT worked + ApiResponse checkPUTWorked = await Util.GetAsync("Widget/" + w2Id.ToString(), await Util.GetTokenAsync("InventoryFull")); + Util.ValidateNoErrorInResponse(checkPUTWorked); + checkPUTWorked.ObjectResponse["data"]["name"].Value().Should().Be(w.name.ToString()); + uint concurrencyToken = PUTTestResponse.ObjectResponse["data"]["concurrencyToken"].Value(); + + EventLogResponse = await Util.GetAsync($"EventLog/ObjectLog?AyType=2&AyId={w2Id}", await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(EventLogResponse, 200); + ((JArray)EventLogResponse.ObjectResponse["data"]).Count.Should().Be(4); + EventLogResponse.ObjectResponse["data"][2]["date"].Value().Should().BeLessThan(new TimeSpan(1, 0, 0)).Before(DateTime.UtcNow);//should be less than one hour before now + EventLogResponse.ObjectResponse["data"][2]["userId"].Should().NotBeNull(); + EventLogResponse.ObjectResponse["data"][2]["event"].Value().Should().Be(3);//AyEvent 3 = Modified + EventLogResponse.ObjectResponse["data"][2]["textra"].Should().BeNullOrEmpty(); + + + //Check user log for basic accessibility + EventLogResponse = await Util.GetAsync($"EventLog/UserLog?AyType=3&AyId={CurrentUserId}", await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(EventLogResponse, 200); + ((JArray)EventLogResponse.ObjectResponse["data"]).Count.Should().BeGreaterOrEqualTo(4);//just one run of the above will be 4 events plus any others from other tests + //Not sure of any easy way to assert the User log is correct other than the count as other tests running concurrently could easily skew this + + + //DELETE + ApiResponse DELETETestResponse = await Util.DeleteAsync("Widget/" + w2Id.ToString(), await Util.GetTokenAsync("InventoryFull")); + Util.ValidateHTTPStatusCode(DELETETestResponse, 204); + + //All events should be cleared up on deletion with the sole exception of the deleted event + EventLogResponse = await Util.GetAsync($"EventLog/ObjectLog?AyType=2&AyId={w2Id}", await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(EventLogResponse, 200); + ((JArray)EventLogResponse.ObjectResponse["data"]).Count.Should().Be(1); + EventLogResponse.ObjectResponse["data"][0]["date"].Value().Should().BeLessThan(new TimeSpan(1, 0, 0)).Before(DateTime.UtcNow);//should be less than one hour before now + EventLogResponse.ObjectResponse["data"][0]["userId"].Should().NotBeNull(); + EventLogResponse.ObjectResponse["data"][0]["event"].Value().Should().Be(0);//AyEvent 0 = deleted + EventLogResponse.ObjectResponse["data"][0]["textra"].Value().Should().Be(w.name.ToString()); + + + } + + //================================================== + + }//eoc +}//eons diff --git a/ImportV7/ImportV7.cs b/ImportV7/ImportV7.cs new file mode 100644 index 0000000..ee18674 --- /dev/null +++ b/ImportV7/ImportV7.cs @@ -0,0 +1,57 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Net.Http; +using System.Net.Http.Headers; +using System.IO; + + +namespace raven_integration +{ + + public class ImportV7 + { + //================================================== + /// + /// Test Importv7 stuff + /// + [Fact] + public async void ImportV7FileRoutesShouldWork() + { + + string UploadFileName = "ayanova.data.dump.xxx.zip"; + + ////////////////////////////////////////// + //// Upload the files + MultipartFormDataContent formDataContent = new MultipartFormDataContent(); + + StreamContent file1 = new StreamContent(File.OpenRead($"{Util.TEST_DATA_FOLDER}\\{UploadFileName}")); + file1.Headers.ContentType = new MediaTypeHeaderValue("application/zip"); + file1.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data"); + file1.Headers.ContentDisposition.FileName = UploadFileName; + formDataContent.Add(file1); + + ApiResponse a = await Util.PostFormDataAsync("ImportAyaNova7", formDataContent, await Util.GetTokenAsync("OpsAdminFull")); + Util.ValidateDataReturnResponseOk(a); + + string importFileName = a.ObjectResponse["data"][0].Value(); + importFileName.Should().Be(UploadFileName); + + + ////////////////////////////////////////// + //// DELETE: Delete the file + ApiResponse d = await Util.DeleteAsync($"ImportAyaNova7/{UploadFileName}", await Util.GetTokenAsync("OpsAdminFull")); + Util.ValidateHTTPStatusCode(d, 204); + + + + } + + + //================================================== + + }//eoc +}//eons diff --git a/JobOperations/JobOperations.cs b/JobOperations/JobOperations.cs new file mode 100644 index 0000000..42bda16 --- /dev/null +++ b/JobOperations/JobOperations.cs @@ -0,0 +1,59 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace raven_integration +{ + + public class JobOperations + { + + /// + /// + /// + [Fact] + public async void TestJobShouldSubmit() + { + ApiResponse a = await Util.GetAsync("Widget/TestWidgetJob", await Util.GetTokenAsync("OpsAdminFull")); + //Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 202); + //should return something like this: + /* + { + "testJobId": 4 + } + */ + + String jobId = a.ObjectResponse["jobId"].Value(); + + //Get a list of operations + a = await Util.GetAsync("JobOperations", await Util.GetTokenAsync("OpsAdminFull")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + + + //there should be at least 1 + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterOrEqualTo(1); + + //See if our job is in there + bool bFound=false; + foreach(JToken t in a.ObjectResponse["data"]) + { + if(t["gId"].Value()==jobId) + bFound=true; + } + bFound.Should().BeTrue(); + + + + } + + + //================================================== + + }//eoc +}//eons diff --git a/Locale/Locale.cs b/Locale/Locale.cs new file mode 100644 index 0000000..b9f57fc --- /dev/null +++ b/Locale/Locale.cs @@ -0,0 +1,186 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; +using System.Collections.Generic; +using System.Threading.Tasks; +using System.Collections.Concurrent; +namespace raven_integration +{ + + public class Locale + { + + /* + + ImportLocale(ct, ResourceFolderPath, "en"); - id 1 + ImportLocale(ct, ResourceFolderPath, "es"); - id 2 + ImportLocale(ct, ResourceFolderPath, "fr"); - id 3 + ImportLocale(ct, ResourceFolderPath, "de"); - id 4 + */ + + [Fact] + public async void LocalePickListWorks() + { + //Get all + ApiResponse a = await Util.GetAsync("Locale/picklist", await Util.GetTokenAsync("ClientLimited"));//lowest level test user because there are no limits on this route except to be authenticated + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + //there should be at least 4 of them as there are 4 stock locales + ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(3); + } + + + [Fact] + public async void GetFullLocaleWorks() + { + //Get all + ApiResponse a = await Util.GetAsync("Locale/1", await Util.GetTokenAsync("ClientLimited"));//lowest level test user because there are no limits on this route except to be authenticated + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + //there should be dozens of keys but at times there might only be a few during development so at least verify there is more than one + ((JArray)a.ObjectResponse["data"]["localeItems"]).Count.Should().BeGreaterThan(0); + } + + + [Fact] + public async void GetSubsetWorks() + { + /* + { + "localeId": 0, + "keys": [ + "string" + ] + } + */ + + List keys = new List(); + keys.AddRange(new string[] { "AddressType", "ClientName", "RateName", "WorkorderService" }); + dynamic d = new JObject(); + //d.localeId = 1; + //d.keys = JToken.FromObject(keys); + d = JToken.FromObject(keys); + + ApiResponse a = await Util.PostAsync("Locale/subset", await Util.GetTokenAsync("ClientLimited"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + //there should be dozens of keys but at times there might only be a few during development so at least verify there is more than one + ((JArray)a.ObjectResponse["data"]).Count.Should().Be(4); + } + + + [Fact] + public async void DuplicateUpdateAndDeleteWorks() + { + /* + { + "id": 1, + "name": "CustomTest1" + } + */ + + //DUPLICATE + dynamic d = new JObject(); + d.id = 1; + d.name = Util.Uniquify("INTEGRATION-TEST-LOCALE"); + + ApiResponse a = await Util.PostAsync("Locale/Duplicate", await Util.GetTokenAsync("BizAdminFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 201); + //verify the object returned is as expected + a.ObjectResponse["data"]["name"].Value().Should().Be(d.name.ToString()); + a.ObjectResponse["data"]["stock"].Value().Should().Be(false); + a.ObjectResponse["data"]["id"].Value().Should().BeGreaterThan(4); + a.ObjectResponse["data"]["concurrencyToken"].Value().Should().BeGreaterThan(0); + ((JArray)a.ObjectResponse["data"]["localeItems"]).Count.Should().BeGreaterThan(0); + + long NewId = a.ObjectResponse["data"]["id"].Value(); + + //UPDATE + //Update locale name + + /* + + { + "id": 10, + "newText": "What the hell?", + "concurrencyToken": 25174 + } + + */ + dynamic d2 = new JObject(); + d2.id = NewId; + d2.newText = Util.Uniquify("INTEGRATION-TEST-LOCALE NAME UPDATE"); + d2.concurrencyToken = a.ObjectResponse["data"]["concurrencyToken"].Value(); + ApiResponse PUTTestResponse = await Util.PutAsync("Locale/UpdateLocaleName", await Util.GetTokenAsync("BizAdminFull"), d2.ToString()); + Util.ValidateHTTPStatusCode(PUTTestResponse, 200); + + + ApiResponse checkPUTWorked = await Util.GetAsync("Locale/" + NewId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateNoErrorInResponse(checkPUTWorked); + checkPUTWorked.ObjectResponse["data"]["name"].Value().Should().Be(d2.newText.ToString()); + //uint concurrencyToken = PUTTestResponse.ObjectResponse["data"]["concurrencyToken"].Value(); + + + //Update locale key + var FirstLocaleKey = ((JArray)a.ObjectResponse["data"]["localeItems"])[0]; + long UpdatedLocaleKeyId = FirstLocaleKey["id"].Value(); + d2.id = UpdatedLocaleKeyId; + d2.newText = Util.Uniquify("INTEGRATION-TEST-LOCALEITEM DISPLAY UPDATE"); + d2.concurrencyToken = FirstLocaleKey["concurrencyToken"].Value(); + + string UpdatedLocaleKey = FirstLocaleKey["key"].Value(); + + PUTTestResponse = await Util.PutAsync("Locale/UpdateLocaleItemDisplayText", await Util.GetTokenAsync("BizAdminFull"), d2.ToString()); + Util.ValidateHTTPStatusCode(PUTTestResponse, 200); + + //create user that is set to new locale so can use getSubset + var Login = Util.Uniquify("LOGIN"); + var Password = Util.Uniquify("PASSWORD"); + dynamic DUSER = new JObject(); + DUSER.name = Util.Uniquify("LocaleUpdateSubsetTestUser"); + DUSER.ownerId = 1L; + DUSER.active = true; + DUSER.login = Login; + DUSER.password = Password; + DUSER.roles = 0;//norole (any role can get a subset of locale keys) + DUSER.localeId = NewId;//random locale + DUSER.userType = 3;//non scheduleable + a = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), DUSER.ToString()); + Util.ValidateDataReturnResponseOk(a); + long DUSERID = a.ObjectResponse["data"]["id"].Value(); + + + + List keys = new List(); + keys.AddRange(new string[] { UpdatedLocaleKey }); + dynamic d3 = new JObject(); + //d3.localeId = NewId; + d3 = JToken.FromObject(keys); + + checkPUTWorked = await Util.PostAsync("Locale/subset", await Util.GetTokenAsync(Login, Password), d3.ToString()); + Util.ValidateDataReturnResponseOk(checkPUTWorked); + Util.ValidateHTTPStatusCode(checkPUTWorked, 200); + ((JArray)checkPUTWorked.ObjectResponse["data"]).Count.Should().Be(1); + var FirstLocaleKeyUpdated = ((JArray)checkPUTWorked.ObjectResponse["data"])[0]; + + FirstLocaleKeyUpdated["value"].Value().Should().Be(d2.newText.ToString()); + + //DELETE TEMPORARY USER SO CAN DELETE LOCALE + a = await Util.DeleteAsync("User/" + DUSERID.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + //DELETE TEMP LOCALE + a = await Util.DeleteAsync("Locale/" + NewId.ToString(), await Util.GetTokenAsync("BizAdminFull")); + Util.ValidateHTTPStatusCode(a, 204); + + + } + + + + //================================================== + + }//eoc +}//eons diff --git a/Locale/RequestedLocaleKeys.cs b/Locale/RequestedLocaleKeys.cs new file mode 100644 index 0000000..d068dfd --- /dev/null +++ b/Locale/RequestedLocaleKeys.cs @@ -0,0 +1,67 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; +using System.Collections.Generic; +using System.Threading.Tasks; +using System.Collections.Concurrent; +namespace raven_integration +{ + + public class RequestedLocaleKeys + { + + + + [Fact] + public async void RequestedLocaleKeysWorks() + { + //First determine if there is a requested key route because it's debug build dependent + //And doesn't exists if server was not debug built + ApiResponse a = await Util.GetAsync("BuildMode"); + Util.ValidateDataReturnResponseOk(a); + var BuildMode = a.ObjectResponse["data"]["buildMode"].Value(); + BuildMode.Should().BeOneOf((new string[] { "DEBUG", "RELEASE" })); + + if (BuildMode == "DEBUG") + { + + //Make a "list" of keys to fetch the values for + List keys = new List(); + keys.AddRange(new string[] { "HelpLicense", "ClientName" }); + dynamic d = new JObject(); + //d.localeId = 1; + d = JToken.FromObject(keys); + + //Fetch the values to force RAVEN to track at least these two + a = await Util.PostAsync("Locale/subset", await Util.GetTokenAsync("ClientLimited"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + //there should be dozens of keys but at times there might only be a few during development so at least verify there is more than one + ((JArray)a.ObjectResponse["data"]).Count.Should().Be(2); + + //Now ensure there are at least two keys in the fetched keys array + a = await Util.GetAsync("Locale/LocaleKeyCoverage", await Util.GetTokenAsync("ClientLimited")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + var RequestedKeyCount = a.ObjectResponse["data"]["requestedKeyCount"].Value(); + RequestedKeyCount.Should().BeGreaterOrEqualTo(2); + var NotRequestedKeyCount = a.ObjectResponse["data"]["notRequestedKeyCount"].Value(); + NotRequestedKeyCount.Should().BeGreaterThan(1);//For now at least, once we have this dialed in it will be zero ultimately + + //there should be dozens of keys but at times there might only be a few during development so at least verify there is more than one + ((JArray)a.ObjectResponse["data"]["requestedKeys"]).Count.Should().Be(RequestedKeyCount); + ((JArray)a.ObjectResponse["data"]["notRequestedKeys"]).Count.Should().Be(NotRequestedKeyCount); + + } + } + + + + + + //================================================== + + }//eoc +}//eons diff --git a/LogFiles/LogFiles.cs b/LogFiles/LogFiles.cs new file mode 100644 index 0000000..6e7f504 --- /dev/null +++ b/LogFiles/LogFiles.cs @@ -0,0 +1,32 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace raven_integration +{ + + public class LogFiles + { + + + + /// + /// + /// + [Fact] + public async void MostRecentLogShouldFetch() + { + ApiTextResponse t = await Util.GetTextResultAsync("LogFiles/log-ayanova.txt", await Util.GetTokenAsync("OpsAdminFull")); + Util.ValidateHTTPStatusCode(t, 200); + string[] ExpectedLogItems = {"|INFO|","|ERROR|", "|WARN|"};//assumes any log will have at least one of these items in it + t.TextResponse.Should().ContainAny(ExpectedLogItems); + + } + + //================================================== + + }//eoc +}//eons diff --git a/Metrics/Metrics.cs b/Metrics/Metrics.cs new file mode 100644 index 0000000..712f2ba --- /dev/null +++ b/Metrics/Metrics.cs @@ -0,0 +1,51 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace raven_integration +{ + + public class Metrics + { + + /// + /// + /// + [Fact] + public async void TextMetricsShouldFetch() + { + ApiTextResponse t = await Util.GetTextResultAsync("Metrics/TextSnapShot", await Util.GetTokenAsync("OpsAdminFull")); + + Util.ValidateHTTPStatusCode(t, 200); + + t.TextResponse.Should().StartWith("# TIMESTAMP:"); + + } + + + + /// + /// + /// + [Fact] + public async void JsonMetricsShouldFetch() + { + ApiResponse a = await Util.GetAsync("Metrics/JsonSnapShot", await Util.GetTokenAsync("OpsAdminFull")); + + Util.ValidateDataReturnResponseOk(a); + + a.ObjectResponse["data"]["timestamp"].Should().NotBeNull(); + ((JArray)a.ObjectResponse["data"]["contexts"]).Count.Should().BeGreaterThan(0); + + + + } + + + //================================================== + + }//eoc +}//eons diff --git a/Privacy/Privacy.cs b/Privacy/Privacy.cs new file mode 100644 index 0000000..5457b08 --- /dev/null +++ b/Privacy/Privacy.cs @@ -0,0 +1,28 @@ +using Xunit; +using FluentAssertions; + +namespace raven_integration +{ + + public class Privacy + { + + + + /// + /// + /// + [Fact] + public async void LogShouldNotContainPrivateData() + { + ApiResponse a = await Util.GetAsync("AyaType", await Util.GetTokenAsync("TEST_PRIVACY_USER_ACCOUNT")); + ApiTextResponse t = await Util.GetTextResultAsync("LogFiles/log-ayanova.txt", await Util.GetTokenAsync("TEST_PRIVACY_USER_ACCOUNT")); + Util.ValidateHTTPStatusCode(t, 200); + t.TextResponse.Should().NotContain("TEST_PRIVACY_USER_ACCOUNT"); + + } + + //================================================== + + }//eoc +}//eons diff --git a/Search/SearchOps.cs b/Search/SearchOps.cs new file mode 100644 index 0000000..aa11ef7 --- /dev/null +++ b/Search/SearchOps.cs @@ -0,0 +1,577 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using System.Linq; +using FluentAssertions; +using System.Collections.Generic; + +namespace raven_integration +{ + + public class SearchOps + { + + [Fact] + public async void PhraseOnlySearchShouldReturnCorrectResultsInOrder() + { + const string TEST_SEARCH_PHRASE = "simple dogs"; + + //CREATE A WIDGET + dynamic D = new JObject(); + D.name = Util.Uniquify("Search NOTES Test WIDGET"); + D.dollarAmount = 1.11m; + D.active = true; + D.roles = 0; + D.notes = "This record will match in notes: The quick brown and simple fox jumped over the six lazy dogs!"; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(a); + long MatchWidgetInNotesId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FIRST TEST USER WITH PHRASE IN NAME + D = new JObject(); + D.name = Util.Uniquify("Search NAME DOGS simple Test User"); + D.notes = "This user has the match in it's name"; + D.ownerId = 1L; + D.active = true; + D.login = Util.Uniquify("LOGIN"); + D.password = Util.Uniquify("PASSWORD"); + D.roles = 0;//norole + D.localeId = 1;//random locale + D.userType = 3;//non scheduleable + + a = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(a); + long MatchUserInNameId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE A SECOND TEST USER WITH PHRASE IN NOTES + D = new JObject(); + D.name = Util.Uniquify("Search NOTES Test User"); + D.notes = "This user has the match simple dogs in its notes"; + D.ownerId = 1L; + D.active = true; + D.login = Util.Uniquify("LOGIN"); + D.password = Util.Uniquify("PASSWORD"); + D.roles = 0;//norole + D.localeId = 1;//random locale + D.userType = 3;//non scheduleable + + a = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(a); + long MatchUserInNotesId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE A SECOND WIDGET + D = new JObject(); + D.name = Util.Uniquify("Search NAME simple as in dogs Test WIDGET"); + D.dollarAmount = 1.11m; + D.active = true; + D.roles = 0; + D.notes = "This Widget matches in name"; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(a); + long MatchWidgetInNameId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE A THIRD WIDGET + D = new JObject(); + D.name = Util.Uniquify("Search NO-MATCH THIRD Test WIDGET"); + D.dollarAmount = 1.11m; + D.active = true; + D.roles = 0; + D.notes = "This Widget should not be returned in the search as it only contains a single keyword in the name not both"; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(a); + long MatchNothingWidgetId = a.ObjectResponse["data"]["id"].Value(); + + + //Now see if can find those objects with a phrase search + dynamic SearchParameters = new JObject(); + + SearchParameters.phrase = TEST_SEARCH_PHRASE; + SearchParameters.nameOnly = false; + SearchParameters.typeOnly = 0;//no type + SearchParameters.maxResults = 0; + a = await Util.PostAsync("Search", await Util.GetTokenAsync("manager", "l3tm3in"), SearchParameters.ToString()); + Util.ValidateDataReturnResponseOk(a); + + //Now validate the return list + ((JArray)a.ObjectResponse["data"]["searchResults"]).Count.Should().BeGreaterOrEqualTo(3); + + //Turn the list into an array of id's + var v = ((JArray)a.ObjectResponse["data"]["searchResults"]); + List MatchingIdList = new List(); + foreach (JObject j in v) + { + MatchingIdList.Add(j["id"].Value()); + } + + //Ensure the expected items are returned + MatchingIdList.Should().Contain(MatchWidgetInNotesId, "ShouldContainMatchWidgetInNotesId"); + MatchingIdList.Should().Contain(MatchWidgetInNameId, "ShouldContainMatchWidgetInNameId"); + MatchingIdList.Should().Contain(MatchUserInNotesId, "ShouldContainMatchUserInNotesId"); + MatchingIdList.Should().Contain(MatchUserInNameId, "ShouldContainMatchUserInNameId"); + MatchingIdList.Should().NotContain(MatchNothingWidgetId, "ShouldNotContainMatchNothingWidgetId"); + + //Assert the order (roughly, this is kind of a waste of time, either the code is sorting or not, it's not going to change) + //first item must be a widget + a.ObjectResponse["data"]["searchResults"][0]["type"].Value().Should().Be(2); + + //final item must be a user + a.ObjectResponse["data"]["searchResults"][MatchingIdList.Count - 1]["type"].Value().Should().Be(3); + + + //FULL BODY SEARCH RIGHTS + //First up test a full record search returns no results due to insufficient rights + //even though the record exists + //Just re-run the above search exactly but with a no rights to full User or Widget role instead + + //Only BizAdmin* roles can read a full user record but anyone should be able to see names + //This search should return zero items + a = await Util.PostAsync("Search", await Util.GetTokenAsync("SubContractorLimited"), SearchParameters.ToString()); + Util.ValidateDataReturnResponseOk(a); + ((JArray)a.ObjectResponse["data"]["searchResults"]).Count.Should().Be(0, "User with no rights should not see any results in body search"); + + + //NAME ONLY SEARCH SHOULD WORK WITH NO RIGHTS TO READ FULL RECORD + //repeat same search but with nameOnly = true and should return at two records at least but not any of the body ones + SearchParameters = new JObject(); + SearchParameters.phrase = TEST_SEARCH_PHRASE; + SearchParameters.nameOnly = true; + SearchParameters.typeOnly = 0;//no type + SearchParameters.maxResults = 0; + a = await Util.PostAsync("Search", await Util.GetTokenAsync("SubContractorLimited"), SearchParameters.ToString()); + Util.ValidateDataReturnResponseOk(a); + ((JArray)a.ObjectResponse["data"]["searchResults"]).Count.Should().BeGreaterOrEqualTo(2); + //Check that list does *not* include the notes only records + MatchingIdList = new List(); + v = ((JArray)a.ObjectResponse["data"]["searchResults"]); + foreach (JObject j in v) + { + MatchingIdList.Add(j["id"].Value()); + } + MatchingIdList.Should().NotContain(MatchWidgetInNotesId, "ShouldNotContainMatchWidgetInNotesId"); + MatchingIdList.Should().Contain(MatchWidgetInNameId, "ShouldContainMatchWidgetInNameId"); + MatchingIdList.Should().NotContain(MatchUserInNotesId, "ShouldContainMatchUserInNotesId"); + MatchingIdList.Should().Contain(MatchUserInNameId, "ShouldContainMatchUserInNameId"); + MatchingIdList.Should().NotContain(MatchNothingWidgetId, "ShouldNotContainThirdWidget"); + + }//eot + + + + [Fact] + public async void WildCardStartsWithSearchShouldWork() + { + const string TEST_SEARCH_PHRASE = "hap* goose"; + + //CREATE A WIDGET + dynamic D = new JObject(); + D.name = Util.Uniquify("Wildcard startswith search test WIDGET"); + D.dollarAmount = 1.11m; + D.active = true; + D.roles = 0; + D.notes = "This record will match in notes: The quick brown and hapless goose"; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(a); + long MatchWidgetInNotesId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FIRST TEST USER WITH PHRASE IN NAME + D = new JObject(); + D.name = Util.Uniquify("Wildcard startswith search NAME happy goose Test User"); + D.notes = "This user has the match in it's name"; + D.ownerId = 1L; + D.active = true; + D.login = Util.Uniquify("LOGIN"); + D.password = Util.Uniquify("PASSWORD"); + D.roles = 0;//norole + D.localeId = 1;//random locale + D.userType = 3;//non scheduleable + + a = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(a); + long MatchUserInNameId = a.ObjectResponse["data"]["id"].Value(); + + + //Now see if can find those objects with a phrase search + dynamic SearchParameters = new JObject(); + + SearchParameters.phrase = TEST_SEARCH_PHRASE; + SearchParameters.nameOnly = false; + SearchParameters.typeOnly = 0;//no type + SearchParameters.maxResults = 0; + a = await Util.PostAsync("Search", await Util.GetTokenAsync("manager", "l3tm3in"), SearchParameters.ToString()); + Util.ValidateDataReturnResponseOk(a); + + //Now validate the return list + ((JArray)a.ObjectResponse["data"]["searchResults"]).Count.Should().BeGreaterOrEqualTo(2); + + //Turn the list into an array of id's + var v = ((JArray)a.ObjectResponse["data"]["searchResults"]); + List MatchingIdList = new List(); + foreach (JObject j in v) + { + MatchingIdList.Add(j["id"].Value()); + } + + //Ensure the expected items are returned + MatchingIdList.Should().Contain(MatchWidgetInNotesId, "ShouldContainMatchWidgetInNotesId"); + MatchingIdList.Should().Contain(MatchUserInNameId, "ShouldContainMatchUserInNameId"); + + }//eot + + + [Fact] + public async void WildCardEndsWithSearchShouldWork() + { + const string TEST_SEARCH_PHRASE = "goose *act"; + + //CREATE A WIDGET + dynamic D = new JObject(); + D.name = Util.Uniquify("Wildcard endswith search test WIDGET"); + D.dollarAmount = 1.11m; + D.active = true; + D.roles = 0; + D.notes = "This record will match in notes: react to the goose"; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(a); + long MatchWidgetInNotesId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FIRST TEST USER WITH PHRASE IN NAME + D = new JObject(); + D.name = Util.Uniquify("Wildcard endswith search NAME goose exact Test User"); + D.notes = "This user has the match in it's name"; + D.ownerId = 1L; + D.active = true; + D.login = Util.Uniquify("LOGIN"); + D.password = Util.Uniquify("PASSWORD"); + D.roles = 0;//norole + D.localeId = 1;//random locale + D.userType = 3;//non scheduleable + + a = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(a); + long MatchUserInNameId = a.ObjectResponse["data"]["id"].Value(); + + + //Now see if can find those objects with a phrase search + dynamic SearchParameters = new JObject(); + + SearchParameters.phrase = TEST_SEARCH_PHRASE; + SearchParameters.nameOnly = false; + SearchParameters.typeOnly = 0;//no type + SearchParameters.maxResults = 0; + a = await Util.PostAsync("Search", await Util.GetTokenAsync("manager", "l3tm3in"), SearchParameters.ToString()); + Util.ValidateDataReturnResponseOk(a); + + //Now validate the return list + ((JArray)a.ObjectResponse["data"]["searchResults"]).Count.Should().BeGreaterOrEqualTo(2); + + //Turn the list into an array of id's + var v = ((JArray)a.ObjectResponse["data"]["searchResults"]); + List MatchingIdList = new List(); + foreach (JObject j in v) + { + MatchingIdList.Add(j["id"].Value()); + } + + //Ensure the expected items are returned + MatchingIdList.Should().Contain(MatchWidgetInNotesId, "ShouldContainMatchWidgetInNotesId"); + MatchingIdList.Should().Contain(MatchUserInNameId, "ShouldContainMatchUserInNameId"); + + }//eot + + + + + [Fact] + public async void WildCardContainsSearchShouldWork() + { + const string TEST_SEARCH_PHRASE = "*cast* goose"; + + //CREATE A WIDGET + dynamic D = new JObject(); + D.name = Util.Uniquify("Wildcard contains search test WIDGET"); + D.dollarAmount = 1.11m; + D.active = true; + D.roles = 0; + D.notes = "This record will match in notes: broadcasting to the goose"; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(a); + long MatchWidgetInNotesId = a.ObjectResponse["data"]["id"].Value(); + + //CREATE FIRST TEST USER WITH PHRASE IN NAME + D = new JObject(); + D.name = Util.Uniquify("Wildcard contains search NAME goose elcastro Test User"); + D.notes = "This user has the match in it's name"; + D.ownerId = 1L; + D.active = true; + D.login = Util.Uniquify("LOGIN"); + D.password = Util.Uniquify("PASSWORD"); + D.roles = 0;//norole + D.localeId = 1;//random locale + D.userType = 3;//non scheduleable + + a = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(a); + long MatchUserInNameId = a.ObjectResponse["data"]["id"].Value(); + + + //Now see if can find those objects with a phrase search + dynamic SearchParameters = new JObject(); + + SearchParameters.phrase = TEST_SEARCH_PHRASE; + SearchParameters.nameOnly = false; + SearchParameters.typeOnly = 0;//no type + SearchParameters.maxResults = 0; + a = await Util.PostAsync("Search", await Util.GetTokenAsync("manager", "l3tm3in"), SearchParameters.ToString()); + Util.ValidateDataReturnResponseOk(a); + + //Now validate the return list + ((JArray)a.ObjectResponse["data"]["searchResults"]).Count.Should().BeGreaterOrEqualTo(2); + + //Turn the list into an array of id's + var v = ((JArray)a.ObjectResponse["data"]["searchResults"]); + List MatchingIdList = new List(); + foreach (JObject j in v) + { + MatchingIdList.Add(j["id"].Value()); + } + + //Ensure the expected items are returned + MatchingIdList.Should().Contain(MatchWidgetInNotesId, "ShouldContainMatchWidgetInNotesId"); + MatchingIdList.Should().Contain(MatchUserInNameId, "ShouldContainMatchUserInNameId"); + + }//eot + + + [Fact] + public async void TagSearchShouldWork() + { + const string TEST_SEARCH_PHRASE = "element* aardvark"; + + // //CREATE A TAG + // dynamic D = new JObject(); + // D.name = Util.Uniquify("TAGSEARCH"); + // ApiResponse a = await Util.PostAsync("Tag", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + // Util.ValidateDataReturnResponseOk(a); + // long TagId = a.ObjectResponse["data"]["id"].Value(); + + + var SearchTagPhrase = Util.Uniquify("TAGSEARCH"); + //Tags + dynamic TagsArray = new JArray(); + TagsArray.Add(SearchTagPhrase); + + //w.tags = InclusiveTagsArray; + + //CREATE A WIDGET + dynamic D = new JObject(); + D.name = Util.Uniquify("TAG search test WIDGET TAG AND PHRASE"); + D.dollarAmount = 1.11m; + D.active = true; + D.roles = 0; + D.notes = "This record will match in notes and tag: elementary my dear aardvark"; + D.tags = TagsArray; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(a); + long MatchWidgetInNotesId = a.ObjectResponse["data"]["id"].Value(); + + + + + //CREATE A WIDGET WITH TAG BUT NOT SEARCH PHRASE + D = new JObject(); + D.name = Util.Uniquify("TAG search test WIDGET TAG ONLY"); + D.dollarAmount = 1.11m; + D.active = true; + D.roles = 0; + D.notes = "This record will match in tag but no search phrase"; + D.tags = TagsArray; + + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(a); + long NoPhraseMatchWidgetInTagId = a.ObjectResponse["data"]["id"].Value(); + + + + //CREATE FIRST TEST USER WITH PHRASE IN NAME BUT NO TAG + D = new JObject(); + D.name = Util.Uniquify("Wildcard contains search NAME elementary aardvark Test User"); + D.notes = "This user has the match in it's name but no tag match"; + D.ownerId = 1L; + D.active = true; + D.login = Util.Uniquify("LOGIN"); + D.password = Util.Uniquify("PASSWORD"); + D.roles = 0;//norole + D.localeId = 1;//random locale + D.userType = 3;//non scheduleable + + a = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(a); + long MatchUserInNameId = a.ObjectResponse["data"]["id"].Value(); + + + //Now see if can find those objects with a phrase search + dynamic SearchParameters = new JObject(); + + SearchParameters.phrase = TEST_SEARCH_PHRASE + " " + SearchTagPhrase; + SearchParameters.nameOnly = false; + SearchParameters.typeOnly = 0;//no type + + a = await Util.PostAsync("Search", await Util.GetTokenAsync("manager", "l3tm3in"), SearchParameters.ToString()); + Util.ValidateDataReturnResponseOk(a); + + //Now validate the return list + ((JArray)a.ObjectResponse["data"]["searchResults"]).Count.Should().BeGreaterOrEqualTo(1); + + //Turn the list into an array of id's + var v = ((JArray)a.ObjectResponse["data"]["searchResults"]); + List MatchingIdList = new List(); + foreach (JObject j in v) + { + MatchingIdList.Add(j["id"].Value()); + } + + //Ensure the expected items are returned + MatchingIdList.Should().Contain(MatchWidgetInNotesId, "ShouldContainMatchWidgetInNotesId"); + MatchingIdList.Should().NotContain(MatchUserInNameId, "ShouldNotContainMatchUserInNameId"); + MatchingIdList.Should().NotContain(NoPhraseMatchWidgetInTagId, "ShouldNotContainNoPhraseMatchWidgetInTagId"); + + }//eot + + + + [Fact] + public async void ConstrainedBigDataSearchShouldHonourMaxResultsAndBeRelativelyFast() + { + //THIS test is a bit different in that it relies partly on the big dataset for testing + //so it has different paths depending upon if it's testing against the big data or not + const string TEST_SEARCH_PHRASE = "et*"; + + //Now see if can find those objects with a phrase search + dynamic SearchParameters = new JObject(); + + SearchParameters.phrase = TEST_SEARCH_PHRASE; + SearchParameters.nameOnly = false; + SearchParameters.typeOnly = 0;//no type + SearchParameters.maxResults = 1000;//default is 500 + + var watch = new System.Diagnostics.Stopwatch(); + watch.Start(); + ApiResponse a = await Util.PostAsync("Search", await Util.GetTokenAsync("manager", "l3tm3in"), SearchParameters.ToString()); + watch.Stop(); + + var TimeToSearch = watch.ElapsedMilliseconds; + + Util.ValidateDataReturnResponseOk(a); + + //Now validate the return list + var ResultCount = ((JArray)a.ObjectResponse["data"]["searchResults"]).Count; + //assert it's not unbounded + ResultCount.Should().BeLessOrEqualTo(1000); + + if (ResultCount > 999) + { + //assert the TotalResultsFound is greater than the results returned + var TotalResultsFound = a.ObjectResponse["data"]["totalResultsFound"].Value(); + //assert it's not unbounded + TotalResultsFound.Should().BeGreaterThan(ResultCount); + } + //5456 ms is the longest I've seen in initial testing with all 1000 results so setting 10% above + TimeToSearch.Should().BeLessThan(6000, "Constrained big data search should not be too slow"); + + }//eot + + + [Fact] + public async void UnboundBigDataSearchShouldBeRelativelyFast() + { + //THIS test is a bit different in that it relies partly on the big dataset for testing + //so it has different paths depending upon if it's testing against the big data or not + const string TEST_SEARCH_PHRASE = "et*"; + + //Now see if can find those objects with a phrase search + dynamic SearchParameters = new JObject(); + + SearchParameters.phrase = TEST_SEARCH_PHRASE; + SearchParameters.nameOnly = false; + SearchParameters.typeOnly = 0;//no type + SearchParameters.maxResults = 0;//0=return all results + + var watch = new System.Diagnostics.Stopwatch(); + watch.Start(); + ApiResponse a = await Util.PostAsync("Search", await Util.GetTokenAsync("manager", "l3tm3in"), SearchParameters.ToString()); + watch.Stop(); + + var TimeToSearch = watch.ElapsedMilliseconds; + + Util.ValidateDataReturnResponseOk(a); + + //Now validate the return list + var ResultCount = ((JArray)a.ObjectResponse["data"]["searchResults"]).Count; + + + //Set this time based on testing. 52385 Slowest run plus 10% + TimeToSearch.Should().BeLessThan(57623, "Unconstrained big data search should not be too slow"); + + + }//eot + + + + [Fact] + public async void SearchForSerialFieldShouldWork() + { + //CREATE A WIDGET + dynamic D = new JObject(); + D.name = Util.Uniquify("Serial search test WIDGET"); + D.dollarAmount = 1.11m; + D.active = true; + D.roles = 0; + D.notes = "Test for serial number search"; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(a); + long MatchWidgetInSerialId = a.ObjectResponse["data"]["id"].Value(); + var MatchWidgetSerial = a.ObjectResponse["data"]["serial"].Value(); + + //TODO: get this from the return object + string SerialSearch = MatchWidgetSerial.ToString(); ; + + + //Now see if can find those objects with a phrase search + dynamic SearchParameters = new JObject(); + SearchParameters.phrase = SerialSearch; + SearchParameters.nameOnly = false; + SearchParameters.typeOnly = 0;//no type + SearchParameters.maxResults = 0; + a = await Util.PostAsync("Search", await Util.GetTokenAsync("manager", "l3tm3in"), SearchParameters.ToString()); + Util.ValidateDataReturnResponseOk(a); + + //Now validate the return list + ((JArray)a.ObjectResponse["data"]["searchResults"]).Count.Should().BeGreaterOrEqualTo(1); + + //Turn the list into an array of id's + var v = ((JArray)a.ObjectResponse["data"]["searchResults"]); + List MatchingIdList = new List(); + foreach (JObject j in v) + { + MatchingIdList.Add(j["id"].Value()); + } + + //Ensure the expected items are returned + MatchingIdList.Should().Contain(MatchWidgetInSerialId, "ShouldContainMatchWidgetInSerialId"); + + + }//eot + + + //================================================== + + }//eoc +}//eons diff --git a/ServerState/ServerStateTest.cs b/ServerState/ServerStateTest.cs new file mode 100644 index 0000000..6344d6c --- /dev/null +++ b/ServerState/ServerStateTest.cs @@ -0,0 +1,79 @@ +using Xunit; + +namespace raven_integration +{ + + public class ServerStateTest + { + + + // ApiFixture fixture; + + // public ServerStateTest(ApiFixture _fixture) + // { + // this.fixture = _fixture; + // } + + + + /// + /// Test get state + /// + [Fact] + public async void ServerStateShouldReturnOk() + { + ApiResponse a = await Util.GetAsync("ServerState"); + Util.ValidateDataReturnResponseOk(a); + } + + + + + //can't test this because it fucks up other tests and the fixture + + // /// + // /// Test set state + // /// + // [Fact] + // public async void ServerStateShouldSet() + // { + + // /*{ + // "serverState": "open" + // } */ + + + // //open + // dynamic dd = new JObject(); + // dd.serverState = "open"; + + // ApiResponse aa = await Util.PostAsync("ServerState", fixture.ManagerAuthToken, dd.ToString()); + // Util.ValidateHTTPStatusCode(aa, 204); + + // //close + // dynamic d = new JObject(); + // d.serverState = "closed"; + + // ApiResponse a = await Util.PostAsync("ServerState", fixture.ManagerAuthToken, d.ToString()); + // Util.ValidateHTTPStatusCode(a, 204); + + // //open + // dynamic ddd = new JObject(); + // dd.serverState = "open"; + + // ApiResponse aaa = await Util.PostAsync("ServerState", fixture.ManagerAuthToken, ddd.ToString()); + // Util.ValidateHTTPStatusCode(aaa, 204); + + + + // } + + + + + + + //================================================== + + }//eoc +}//eons diff --git a/User/UserCrud.cs b/User/UserCrud.cs new file mode 100644 index 0000000..4a30cde --- /dev/null +++ b/User/UserCrud.cs @@ -0,0 +1,592 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; + +namespace raven_integration +{ + + public class UserCrud + { + + /// + /// Test all CRUD routes for a User + /// + [Fact] + public async void CRUD() + { + + //CREATE + dynamic D1 = new JObject(); + D1.name = Util.Uniquify("First Test User"); + D1.ownerId = 1L; + D1.active = true; + D1.login = Util.Uniquify("LOGIN"); + D1.password = Util.Uniquify("PASSWORD"); + D1.roles = 0;//norole + D1.localeId = 1;//random locale + D1.userType = 3;//non scheduleable + + ApiResponse R1 = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), D1.ToString()); + Util.ValidateDataReturnResponseOk(R1); + long d1Id = R1.ObjectResponse["data"]["id"].Value(); + + + dynamic D2 = new JObject(); + D2.name = Util.Uniquify("Second Test User"); + D2.ownerId = 1L; + D2.active = true; + D2.login = Util.Uniquify("LOGIN"); + D2.password = Util.Uniquify("PASSWORD"); + D2.roles = 0;//norole + D2.localeId = 1;//random locale + D2.userType = 3;//non scheduleable + + ApiResponse R2 = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), D2.ToString()); + Util.ValidateDataReturnResponseOk(R2); + long d2Id = R2.ObjectResponse["data"]["id"].Value(); + + + //RETRIEVE + + //Get one + ApiResponse R3 = await Util.GetAsync("User/" + d2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(R3); + R3.ObjectResponse["data"]["name"].Value().Should().Be(D2.name.ToString()); + + + + //UPDATE + //PUT + + //update w2id + D2.name = Util.Uniquify("UPDATED VIA PUT SECOND TEST User"); + D2.OwnerId = 1; + D2.concurrencyToken = R2.ObjectResponse["data"]["concurrencyToken"].Value(); + ApiResponse PUTTestResponse = await Util.PutAsync("User/" + d2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), D2.ToString()); + Util.ValidateHTTPStatusCode(PUTTestResponse, 200); + + //check PUT worked + ApiResponse checkPUTWorked = await Util.GetAsync("User/" + d2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateNoErrorInResponse(checkPUTWorked); + checkPUTWorked.ObjectResponse["data"]["name"].Value().Should().Be(D2.name.ToString()); + uint concurrencyToken = PUTTestResponse.ObjectResponse["data"]["concurrencyToken"].Value(); + + //PATCH + var newName = Util.Uniquify("UPDATED VIA PATCH SECOND TEST User"); + string patchJson = "[{\"value\": \"" + newName + "\",\"path\": \"/name\",\"op\": \"replace\"}]"; + ApiResponse PATCHTestResponse = await Util.PatchAsync("User/" + d2Id.ToString() + "/" + concurrencyToken.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), patchJson); + Util.ValidateHTTPStatusCode(PATCHTestResponse, 200); + + //check PATCH worked + ApiResponse checkPATCHWorked = await Util.GetAsync("User/" + d2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateNoErrorInResponse(checkPATCHWorked); + checkPATCHWorked.ObjectResponse["data"]["name"].Value().Should().Be(newName); + + //DELETE + ApiResponse DELETETestResponse = await Util.DeleteAsync("User/" + d2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(DELETETestResponse, 204); + } + + + /// + /// + /// + [Fact] + public async void UserWithActivityShouldNotBeDeleteable() + { + ApiResponse a = await Util.DeleteAsync("User/1", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateErrorCodeResponse(a, 2200, 400); + a.ObjectResponse["error"]["details"][0]["message"].Value().Should().Contain("[E_ACTIVE_NOT_DELETABLE]"); + } + + + /// + /// Test not found + /// + [Fact] + public async void GetNonExistentItemShouldError() + { + //Get non existant + //Should return status code 404, api error code 2010 + ApiResponse R = await Util.GetAsync("User/999999", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateResponseNotFound(R); + } + + /// + /// Test bad modelstate + /// + [Fact] + public async void GetBadModelStateShouldError() + { + //Get non existant + //Should return status code 400, api error code 2200 and a first target in details of "id" + ApiResponse R = await Util.GetAsync("User/2q2", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateBadModelStateResponse(R, "id"); + } + + + /// + /// + /// + [Fact] + public async void PutConcurrencyViolationShouldFail() + { + //CREATE + dynamic D = new JObject(); + D.name = Util.Uniquify("PutConcurrencyViolationShouldFail"); + D.ownerId = 1L; + D.active = true; + D.login = Util.Uniquify("LOGIN"); + D.password = Util.Uniquify("PASSWORD"); + D.roles = 0;//norole + D.localeId = 1;//random locale + D.userType = 3;//non scheduleable + + ApiResponse R = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(R); + long D1Id = R.ObjectResponse["data"]["id"].Value(); + uint OriginalConcurrencyToken = R.ObjectResponse["data"]["concurrencyToken"].Value(); + + + //UPDATE + //PUT + + D.name = Util.Uniquify("PutConcurrencyViolationShouldFail UPDATE VIA PUT "); + D.concurrencyToken = OriginalConcurrencyToken - 1;//bad token + ApiResponse PUTTestResponse = await Util.PutAsync("User/" + D1Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateConcurrencyError(PUTTestResponse); + } + + + /// + /// + /// + [Fact] + public async void PatchConcurrencyViolationShouldFail() + { + //CREATE + dynamic D = new JObject(); + D.name = Util.Uniquify("PatchConcurrencyViolationShouldFail"); + D.ownerId = 1L; + D.active = true; + D.login = Util.Uniquify("LOGIN"); + D.password = Util.Uniquify("PASSWORD"); + D.roles = 0;//norole + D.localeId = 1;//random locale + D.userType = 3;//non scheduleable + + ApiResponse R = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(R); + long w2Id = R.ObjectResponse["data"]["id"].Value(); + uint OriginalConcurrencyToken = R.ObjectResponse["data"]["concurrencyToken"].Value(); + + + //PATCH + var newName = Util.Uniquify("PutConcurrencyViolationShouldFail UPDATED VIA PATCH"); + string patchJson = "[{\"value\": \"" + newName + "\",\"path\": \"/name\",\"op\": \"replace\"}]"; + ApiResponse PATCHTestResponse = await Util.PatchAsync("User/" + w2Id.ToString() + "/" + (OriginalConcurrencyToken - 1).ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), patchJson); + Util.ValidateConcurrencyError(PATCHTestResponse); + } + + + + /// + /// + /// + [Fact] + public async void DisallowedPatchAttemptsShouldFail() + { + //CREATE + dynamic D = new JObject(); + D.name = Util.Uniquify("DisallowedPatchAttemptsShouldFail"); + D.ownerId = 1L; + D.active = true; + D.login = Util.Uniquify("LOGIN"); + D.password = Util.Uniquify("PASSWORD"); + D.roles = 0;//norole + D.localeId = 1;//random locale + D.userType = 3;//non scheduleable + + ApiResponse R = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(R); + long w2Id = R.ObjectResponse["data"]["id"].Value(); + uint OriginalConcurrencyToken = R.ObjectResponse["data"]["concurrencyToken"].Value(); + + + //PATCH attempt on Id + string patchJson = "[{\"value\": \"0\",\"path\": \"/id\",\"op\": \"replace\"}]"; + ApiResponse PATCHTestResponse = await Util.PatchAsync("User/" + w2Id.ToString() + "/" + (OriginalConcurrencyToken - 1).ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), patchJson); + Util.ValidateErrorCodeResponse(PATCHTestResponse, 2200, 400); + + //PATCH attempt on OwnerId + patchJson = "[{\"value\": \"0\",\"path\": \"/ownerid\",\"op\": \"replace\"}]"; + PATCHTestResponse = await Util.PatchAsync("User/" + w2Id.ToString() + "/" + (OriginalConcurrencyToken - 1).ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), patchJson); + Util.ValidateErrorCodeResponse(PATCHTestResponse, 2200, 400); + + //PATCH attempt add field + patchJson = "[{\"value\": \"0\",\"path\": \"/bogus\",\"op\": \"add\"}]"; + PATCHTestResponse = await Util.PatchAsync("User/" + w2Id.ToString() + "/" + (OriginalConcurrencyToken - 1).ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), patchJson); + Util.ValidateErrorCodeResponse(PATCHTestResponse, 2200, 400); + + //PATCH attempt remove name field + patchJson = "[{\"path\": \"/name\",\"op\": \"remove\"}]"; + PATCHTestResponse = await Util.PatchAsync("User/" + w2Id.ToString() + "/" + (OriginalConcurrencyToken - 1).ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), patchJson); + Util.ValidateErrorCodeResponse(PATCHTestResponse, 2200, 400); + } + + + /// + /// + /// + [Fact] + public async void PatchPasswordShouldWork() + { + //CREATE + dynamic D = new JObject(); + D.name = Util.Uniquify("PatchPasswordShouldWork"); + D.ownerId = 1L; + D.active = true; + D.login = Util.Uniquify("LOGIN"); + D.password = Util.Uniquify("PASSWORD"); + D.roles = 0;//norole + D.localeId = 1;//random locale + D.userType = 3;//non scheduleable + + ApiResponse R = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(R); + long UserId = R.ObjectResponse["data"]["id"].Value(); + uint OriginalConcurrencyToken = R.ObjectResponse["data"]["concurrencyToken"].Value(); + + //Test can login + dynamic DCreds = new JObject(); + DCreds.password = D.password; + DCreds.login = D.login; + R = await Util.PostAsync("Auth", null, DCreds.ToString()); + Util.ValidateDataReturnResponseOk(R); + + //PUT + var NewPassword = "NEW_PASSWORD"; + D.password = NewPassword; + D.concurrencyToken = OriginalConcurrencyToken; + R = await Util.PutAsync("User/" + UserId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(R); + + //Test can login with new creds + //dynamic DCreds = new JObject(); + DCreds.password = NewPassword; + DCreds.login = D.login; + R = await Util.PostAsync("Auth", null, DCreds.ToString()); + Util.ValidateDataReturnResponseOk(R); + } + + + /// + /// + /// + [Fact] + public async void PutPasswordShouldWork() + { + //CREATE + dynamic D = new JObject(); + D.name = Util.Uniquify("PutPasswordShouldWork"); + D.ownerId = 1L; + D.active = true; + D.login = Util.Uniquify("LOGIN"); + D.password = Util.Uniquify("PASSWORD"); + D.roles = 0;//norole + D.localeId = 1;//random locale + D.userType = 3;//non scheduleable + + ApiResponse R = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); + Util.ValidateDataReturnResponseOk(R); + long UserId = R.ObjectResponse["data"]["id"].Value(); + uint OriginalConcurrencyToken = R.ObjectResponse["data"]["concurrencyToken"].Value(); + + //Test can login + dynamic DCreds = new JObject(); + DCreds.password = D.password; + DCreds.login = D.login; + R = await Util.PostAsync("Auth", null, DCreds.ToString()); + Util.ValidateDataReturnResponseOk(R); + + //PATCH + var newPassword = "NEW_PASSWORD"; + string patchJson = "[{\"value\": \"" + newPassword + "\",\"path\": \"/password\",\"op\": \"replace\"}]"; + R = await Util.PatchAsync("User/" + UserId.ToString() + "/" + OriginalConcurrencyToken.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), patchJson); + Util.ValidateDataReturnResponseOk(R); + + //Test can login with new creds + //dynamic DCreds = new JObject(); + DCreds.password = newPassword; + DCreds.login = D.login; + R = await Util.PostAsync("Auth", null, DCreds.ToString()); + Util.ValidateDataReturnResponseOk(R); + } + + + + + /// + /// + /// + [Fact] + public async void UserListFilterAndSortWorks() + { + + var ObjectNameStart = Util.Uniquify("UserListFilterAndSortWorks"); + + //CREATE 3 TEST OBJECTS TO TEST ORDER + long FirstInOrdertId = 0; + long SecondInOrderId = 0; + long ThirdInOrderId = 0; + + dynamic d = new JObject(); + d.name = Util.Uniquify(ObjectNameStart); + d.active = false; + d.login = Util.Uniquify("LOGIN"); + d.password = Util.Uniquify("PASSWORD"); + d.roles = 0;//norole + d.localeId = 1;//random locale + d.userType = 3;//non scheduleable + + ApiResponse a = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + FirstInOrdertId = a.ObjectResponse["data"]["id"].Value(); + + d = new JObject(); + d.name = Util.Uniquify(ObjectNameStart); + d.login = Util.Uniquify("LOGIN"); + d.password = Util.Uniquify("PASSWORD"); + d.roles = 0;//norole + d.localeId = 1;//random locale + d.userType = 3;//non scheduleable + d.active = true; + + a = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + ThirdInOrderId = a.ObjectResponse["data"]["id"].Value(); + + d = new JObject(); + d.name = Util.Uniquify(ObjectNameStart); + d.login = Util.Uniquify("LOGIN"); + d.password = Util.Uniquify("PASSWORD"); + d.roles = 0;//norole + d.localeId = 1;//random locale + d.userType = 3;//non scheduleable + d.active = false; + a = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + SecondInOrderId = a.ObjectResponse["data"]["id"].Value(); + + + //CREATE FILTER + d = new JObject(); + d.name = Util.Uniquify(ObjectNameStart); + d["public"] = true; + d.listKey = "user"; + + //FILTER IN BY NAME FOR TESTING THIS RUN ONLY + dynamic dfilter = new JArray(); + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = ObjectNameStart; + dfilter.Add(DataFilterNameStart); + d.filter = dfilter.ToString(); + + dynamic dsortarray = new JArray(); + + //SORT ORDER ################### + //sort by active then by ID + + dynamic dsort = new JObject(); + dsort.fld = "active"; + dsort.dir = "+"; + dsortarray.Add(dsort); + + dsort = new JObject(); + dsort.fld = "id"; + dsort.dir = "+"; + dsortarray.Add(dsort); + + d.sort = dsortarray.ToString(); + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("manager", "l3tm3in"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"User/listusers?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains exactly 3 records + ((JArray)a.ObjectResponse["data"]).Count.Should().Be(3); + + //assert the order returned + a.ObjectResponse["data"][0]["id"].Value().Should().Be(FirstInOrdertId); + a.ObjectResponse["data"][1]["id"].Value().Should().Be(SecondInOrderId); + a.ObjectResponse["data"][2]["id"].Value().Should().Be(ThirdInOrderId); + + + a = await Util.DeleteAsync("User/" + FirstInOrdertId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("User/" + SecondInOrderId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("User/" + ThirdInOrderId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + + /// + /// + /// + [Fact] + public async void UserPickListDefaultSortNoFilterWorks() + { + var RouteName = "User";//########## + + //NOW FETCH LIST WITH FILTER + ApiResponse a = await Util.GetAsync($"{RouteName}/picklist?Offset=0&Limit=999", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains exactly 3 records + var ItemCount = ((JArray)a.ObjectResponse["data"]).Count; + + for (int i = 0; i < ItemCount - 1; i++) + { + var firstName = a.ObjectResponse["data"][i]["name"].Value().Replace(" ", ""); + var secondName = a.ObjectResponse["data"][i + 1]["name"].Value().Replace(" ", ""); + int comparison = String.Compare(firstName, secondName, comparisonType: StringComparison.OrdinalIgnoreCase); + comparison.Should().BeNegative(); + } + } + + + + /// + /// + /// + [Fact] + public async void UserPickListSortByFieldAscendingWorks() + { + + var NameStart = Util.Uniquify("UserPickListSortByFieldAscendingWorks"); + + //CREATE 3 TEST objects TO TEST ORDER + long FirstInOrderId = 0; + long SecondInOrderId = 0; + long ThirdInOrderId = 0; + + dynamic d = new JObject(); + d.name = Util.Uniquify(NameStart); + d.active = false; + d.login = Util.Uniquify("LOGIN"); + d.password = Util.Uniquify("PASSWORD"); + d.roles = 0;//norole + d.localeId = 1;//random locale + d.userType = 3;//non scheduleable + + ApiResponse a = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + ThirdInOrderId = a.ObjectResponse["data"]["id"].Value(); + + d = new JObject(); + d.name = Util.Uniquify(NameStart); + d.active = true; + d.login = Util.Uniquify("LOGIN"); + d.password = Util.Uniquify("PASSWORD"); + d.roles = 0;//norole + d.localeId = 1;//random locale + d.userType = 2;//non scheduleable + a = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + SecondInOrderId = a.ObjectResponse["data"]["id"].Value(); + + d = new JObject(); + d.name = Util.Uniquify(NameStart); + d.active = false; + d.login = Util.Uniquify("LOGIN"); + d.password = Util.Uniquify("PASSWORD"); + d.roles = 0;//norole + d.localeId = 1;//random locale + d.userType = 1;//non scheduleable + a = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + FirstInOrderId = a.ObjectResponse["data"]["id"].Value(); + + + //CREATE FILTER + d = new JObject(); + d.name = Util.Uniquify(NameStart); + d["public"] = true; + d.listKey = "user"; + + //FILTER IN BY NAME FOR TESTING THIS RUN ONLY + dynamic dfilter = new JArray(); + //name starts with filter to constrict to widgets that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = NameStart; + dfilter.Add(DataFilterNameStart); + d.filter = dfilter.ToString(); + + //SORT ORDER ################### + dynamic dsortarray = new JArray(); + dynamic dsort = new JObject(); + dsort.fld = "usertype"; + dsort.dir = "+"; + dsortarray.Add(dsort); + d.sort = dsortarray.ToString(); + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("manager", "l3tm3in"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH WIDGET LIST WITH FILTER + a = await Util.GetAsync($"User/picklist?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains exactly 3 records + ((JArray)a.ObjectResponse["data"]).Count.Should().Be(3); + + //assert the order returned + a.ObjectResponse["data"][0]["id"].Value().Should().Be(FirstInOrderId); + a.ObjectResponse["data"][1]["id"].Value().Should().Be(SecondInOrderId); + a.ObjectResponse["data"][2]["id"].Value().Should().Be(ThirdInOrderId); + + + a = await Util.DeleteAsync("User/" + FirstInOrderId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("User/" + SecondInOrderId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync("User/" + ThirdInOrderId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + + //================================================== + + }//eoc +}//eons diff --git a/User/UserInactive.cs b/User/UserInactive.cs new file mode 100644 index 0000000..64b99fe --- /dev/null +++ b/User/UserInactive.cs @@ -0,0 +1,31 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; + +namespace raven_integration +{ + + public class UserInactive + { + + /// + /// Inactive user should not be able to login + /// + [Fact] + public async void InactiveUserCantLogin() + { + dynamic DCreds = new JObject(); + DCreds.password = DCreds.login = "TEST_INACTIVE"; + ApiResponse a = await Util.PostAsync("Auth", null, DCreds.ToString()); + Util.ValidateErrorCodeResponse(a,2004, 401); + } + + + + + + //================================================== + + }//eoc +}//eons diff --git a/User/UserOptionsRu.cs b/User/UserOptionsRu.cs new file mode 100644 index 0000000..841963e --- /dev/null +++ b/User/UserOptionsRu.cs @@ -0,0 +1,127 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; + +namespace raven_integration +{ + + public class UserOptionsRu + { + + /// + /// Test all CRUD routes for a UserOptions object + /// + [Fact] + public async void RU() + { + + //CREATE a user + dynamic D1 = new JObject(); + D1.name = Util.Uniquify("Test UserOptions User"); + D1.ownerId = 1L; + D1.active = true; + D1.login = Util.Uniquify("LOGIN"); + D1.password = Util.Uniquify("PASSWORD"); + D1.roles = 0;//norole + D1.localeId = 1;//random locale + D1.userType = 3;//non scheduleable + + ApiResponse R = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), D1.ToString()); + Util.ValidateDataReturnResponseOk(R); + long UserId = R.ObjectResponse["data"]["id"].Value(); + + //Now there should be a user options available for this user + + + //RETRIEVE companion USEROPTIONS object + + //Get it + R = await Util.GetAsync("UserOptions/" + UserId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(R); + //ensure the default value is set + R.ObjectResponse["data"]["uiColor"].Value().Should().Be(0); + uint concurrencyToken = R.ObjectResponse["data"]["concurrencyToken"].Value(); + + //UPDATE + //PUT + dynamic D2 = new JObject(); + D2.emailaddress = "testuseroptions@helloayanova.com"; + D2.TimeZoneOffset = -7.5M;//Decimal value + D2.UiColor = -2097216;//Int value (no suffix for int literals) + D2.concurrencyToken = concurrencyToken; + ApiResponse PUTTestResponse = await Util.PutAsync("UserOptions/" + UserId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), D2.ToString()); + Util.ValidateHTTPStatusCode(PUTTestResponse, 200); + + //VALIDATE + R = await Util.GetAsync("UserOptions/" + UserId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(R); + //ensure the default value is set + R.ObjectResponse["data"]["emailAddress"].Value().Should().Be(D2.emailaddress.ToString()); + R.ObjectResponse["data"]["timeZoneOffset"].Value().Should().Be((decimal)D2.TimeZoneOffset); + R.ObjectResponse["data"]["uiColor"].Value().Should().Be((int)D2.UiColor); + concurrencyToken = R.ObjectResponse["data"]["concurrencyToken"].Value(); + + + //PATCH + string newEmail = "patchtestuseroptions@helloayanova.com"; + string patchJson = "[{\"value\": \"" + newEmail + "\",\"path\": \"/emailAddress\",\"op\": \"replace\"}]"; + ApiResponse PATCHTestResponse = await Util.PatchAsync("UserOptions/" + UserId.ToString() + "/" + concurrencyToken.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), patchJson); + Util.ValidateHTTPStatusCode(PATCHTestResponse, 200); + + //check PATCH worked + R = await Util.GetAsync("UserOptions/" + UserId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(R); + //ensure the default value is set + R.ObjectResponse["data"]["emailAddress"].Value().Should().Be(newEmail); + R.ObjectResponse["data"]["timeZoneOffset"].Value().Should().Be((decimal)D2.TimeZoneOffset); + R.ObjectResponse["data"]["uiColor"].Value().Should().Be((int)D2.UiColor); + // concurrencyToken = R.ObjectResponse["data"]["concurrencyToken"].Value(); + + //DELETE USER + ApiResponse DELETETestResponse = await Util.DeleteAsync("User/" + UserId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(DELETETestResponse, 204); + + //CHECK DELETE USER REMOVED USEROPTIONS + R = await Util.GetAsync("UserOptions/" + UserId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateResponseNotFound(R); + } + + + /// + /// Test not found + /// + [Fact] + public async void GetNonExistentItemShouldError() + { + //Get non existant + //Should return status code 404, api error code 2010 + ApiResponse R = await Util.GetAsync("UserOptions/999999", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateResponseNotFound(R); + } + + /// + /// Test bad modelstate + /// + [Fact] + public async void GetBadModelStateShouldError() + { + //Get non existant + //Should return status code 400, api error code 2200 and a first target in details of "id" + ApiResponse R = await Util.GetAsync("UserOptions/2q2", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateBadModelStateResponse(R, "id"); + } + + + + + + + + + + + //================================================== + + }//eoc +}//eons diff --git a/Widget/WidgetCrud.cs b/Widget/WidgetCrud.cs new file mode 100644 index 0000000..44df52a --- /dev/null +++ b/Widget/WidgetCrud.cs @@ -0,0 +1,244 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; + +namespace raven_integration +{ + + public class WidgetCrud + { + + /// + /// Test all CRUD routes for a widget + /// + [Fact] + public async void CRUD() + { + /* + { + "id": 0, + "name": "string", + "dollarAmount": 0, + "active": true, + "roles": 0 + } + */ + //CREATE + dynamic w1 = new JObject(); + w1.name = Util.Uniquify("First Test WIDGET"); + w1.dollarAmount = 1.11m; + w1.active = true; + w1.roles = 0; + w1.notes = "The quick brown fox jumped over the six lazy dogs!"; + + //Tags + dynamic dTagsArray = new JArray(); + dTagsArray.Add("Red Tag"); + dTagsArray.Add("ORANGE IS THE NEW BLACK"); + dTagsArray.Add("yellow"); + dTagsArray.Add("green"); + dTagsArray.Add("blue"); + dTagsArray.Add("indigo"); + dTagsArray.Add("VIOLET Tag"); + w1.tags = dTagsArray; + + ApiResponse r1 = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w1.ToString()); + Util.ValidateDataReturnResponseOk(r1); + long w1Id = r1.ObjectResponse["data"]["id"].Value(); + + dynamic w2 = new JObject(); + w2.name = Util.Uniquify("Second Test WIDGET"); + w2.dollarAmount = 2.22m; + w2.active = true; + w2.roles = 0; + w2.notes = "What is the frequency Kenneth?"; + w2.tags = dTagsArray; + + ApiResponse r2 = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w2.ToString()); + Util.ValidateDataReturnResponseOk(r2); + long w2Id = r2.ObjectResponse["data"]["id"].Value(); + + //RETRIEVE + + //Get one + ApiResponse r3 = await Util.GetAsync("Widget/" + w2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(r3); + r3.ObjectResponse["data"]["name"].Value().Should().Be(w2.name.ToString()); + r3.ObjectResponse["data"]["notes"].Value().Should().Be(w2.notes.ToString()); + var returnedTags = ((JArray)r3.ObjectResponse["data"]["tags"]); + returnedTags.Count.Should().Be(7); + returnedTags[0].Value().Should().Be("red-tag"); + returnedTags[1].Value().Should().Be("orange-is-the-new-black"); + returnedTags[2].Value().Should().Be("yellow"); + returnedTags[3].Value().Should().Be("green"); + returnedTags[4].Value().Should().Be("blue"); + returnedTags[5].Value().Should().Be("indigo"); + returnedTags[6].Value().Should().Be("violet-tag"); + + + + //UPDATE + //PUT + + //update w2id + w2.name = Util.Uniquify("UPDATED VIA PUT SECOND TEST WIDGET"); + w2.OwnerId = 1; + w2.concurrencyToken = r2.ObjectResponse["data"]["concurrencyToken"].Value(); + ApiResponse PUTTestResponse = await Util.PutAsync("Widget/" + w2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), w2.ToString()); + Util.ValidateHTTPStatusCode(PUTTestResponse, 200); + + //check PUT worked + ApiResponse checkPUTWorked = await Util.GetAsync("Widget/" + w2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateNoErrorInResponse(checkPUTWorked); + checkPUTWorked.ObjectResponse["data"]["name"].Value().Should().Be(w2.name.ToString()); + uint concurrencyToken = PUTTestResponse.ObjectResponse["data"]["concurrencyToken"].Value(); + + //PATCH + var newName = Util.Uniquify("UPDATED VIA PATCH SECOND TEST WIDGET"); + string patchJson = "[{\"value\": \"" + newName + "\",\"path\": \"/name\",\"op\": \"replace\"}]"; + ApiResponse PATCHTestResponse = await Util.PatchAsync("Widget/" + w2Id.ToString() + "/" + concurrencyToken.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), patchJson); + Util.ValidateHTTPStatusCode(PATCHTestResponse, 200); + + //check PATCH worked + ApiResponse checkPATCHWorked = await Util.GetAsync("Widget/" + w2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateNoErrorInResponse(checkPATCHWorked); + checkPATCHWorked.ObjectResponse["data"]["name"].Value().Should().Be(newName); + + //DELETE + ApiResponse DELETETestResponse = await Util.DeleteAsync("Widget/" + w2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(DELETETestResponse, 204); + } + + + + + + + /// + /// Test not found + /// + [Fact] + public async void GetNonExistentItemShouldError() + { + //Get non existant + //Should return status code 404, api error code 2010 + ApiResponse a = await Util.GetAsync("Widget/999999", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateResponseNotFound(a); + } + + /// + /// Test bad modelstate + /// + [Fact] + public async void GetBadModelStateShouldError() + { + //Get non existant + //Should return status code 400, api error code 2200 and a first target in details of "id" + ApiResponse a = await Util.GetAsync("Widget/2q2", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateBadModelStateResponse(a, "id"); + } + + + /// + /// Test server exception + /// + [Fact] + public async void ServerExceptionShouldErrorPropertly() + { + //Get non existant + //Should return status code 400, api error code 2200 and a first target in details of "id" + ApiResponse a = await Util.GetAsync("Widget/exception", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateServerExceptionResponse(a); + } + + + + /// + /// Test server alt exception + /// + [Fact] + public async void ServerAltExceptionShouldErrorPropertly() + { + //Get non existant + //Should return status code 400, api error code 2200 and a first target in details of "id" + ApiResponse a = await Util.GetAsync("Widget/altexception", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateServerExceptionResponse(a); + } + + + + + /// + /// + /// + [Fact] + public async void PutConcurrencyViolationShouldFail() + { + + //CREATE + + dynamic w2 = new JObject(); + w2.name = Util.Uniquify("PutConcurrencyViolationShouldFail"); + w2.dollarAmount = 2.22m; + w2.active = true; + w2.roles = 0; + + ApiResponse r2 = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w2.ToString()); + Util.ValidateDataReturnResponseOk(r2); + long w2Id = r2.ObjectResponse["data"]["id"].Value(); + uint OriginalConcurrencyToken = r2.ObjectResponse["data"]["concurrencyToken"].Value(); + + + + //UPDATE + //PUT + + w2.name = Util.Uniquify("PutConcurrencyViolationShouldFail UPDATE VIA PUT "); + w2.OwnerId = 1; + w2.concurrencyToken = OriginalConcurrencyToken - 1;//bad token + ApiResponse PUTTestResponse = await Util.PutAsync("Widget/" + w2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), w2.ToString()); + Util.ValidateConcurrencyError(PUTTestResponse); + + + } + + + + + /// + /// + /// + [Fact] + public async void PatchConcurrencyViolationShouldFail() + { + + //CREATE + + dynamic w2 = new JObject(); + w2.name = Util.Uniquify("PatchConcurrencyViolationShouldFail"); + w2.dollarAmount = 2.22m; + w2.active = true; + w2.roles = 0; + + ApiResponse r2 = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w2.ToString()); + Util.ValidateDataReturnResponseOk(r2); + long w2Id = r2.ObjectResponse["data"]["id"].Value(); + uint OriginalConcurrencyToken = r2.ObjectResponse["data"]["concurrencyToken"].Value(); + + + //PATCH + var newName = Util.Uniquify("PutConcurrencyViolationShouldFail UPDATED VIA PATCH"); + string patchJson = "[{\"value\": \"" + newName + "\",\"path\": \"/name\",\"op\": \"replace\"}]"; + ApiResponse PATCHTestResponse = await Util.PatchAsync("Widget/" + w2Id.ToString() + "/" + (OriginalConcurrencyToken - 1).ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), patchJson); + Util.ValidateConcurrencyError(PATCHTestResponse); + } + + + + + + //================================================== + + }//eoc +}//eons diff --git a/Widget/WidgetLists.cs b/Widget/WidgetLists.cs new file mode 100644 index 0000000..1ae974d --- /dev/null +++ b/Widget/WidgetLists.cs @@ -0,0 +1,214 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; +using System.Collections.Generic; +using System.Threading.Tasks; +using System.Collections.Concurrent; + +namespace raven_integration +{ + + public class WidgetLists + { + + + + + /// + /// + /// + [Fact] + public async void WidgetPickListDefaultSortNoFilterWorks() + { + var RouteName = "Widget";//########## + + //NOW FETCH LIST WITH FILTER + ApiResponse a = await Util.GetAsync($"{RouteName}/picklist?Offset=0&Limit=999", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains exactly 3 records + var ItemCount = ((JArray)a.ObjectResponse["data"]).Count; + + for (int i = 0; i < ItemCount - 1; i++) + { + //Note it's necessary to replace the spaces because postgres thinks spaces go last and the string comparison thinks they go first + var firstName = a.ObjectResponse["data"][i]["name"].Value().Replace(" ",""); + var secondName = a.ObjectResponse["data"][i + 1]["name"].Value().Replace(" ",""); + int comparison = String.Compare(firstName, secondName, comparisonType: StringComparison.OrdinalIgnoreCase); + comparison.Should().BeNegative(); + } + } + + + /// + /// + /// + [Fact] + public async void WidgetPickListSortByFieldAscendingWorks() + { + + var NameStart = Util.Uniquify("WidgetPickListSortByFieldAscendingWorks"); + var RouteName = "Widget"; + + //CREATE 3 TEST OBJECTS TO TEST ORDER + long FirstInOrderId = 0; + long SecondInOrderId = 0; + long ThirdInOrderId = 0; + + dynamic d = new JObject(); + d.name = Util.Uniquify(NameStart); + d.startDate = DateTime.Now; + d.endDate = DateTime.Now.AddHours(1); + + ApiResponse a = await Util.PostAsync(RouteName, await Util.GetTokenAsync("manager", "l3tm3in"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + FirstInOrderId = a.ObjectResponse["data"]["id"].Value(); + + d = new JObject(); + d.name = Util.Uniquify(NameStart); + d.startDate = DateTime.Now.AddHours(1); + d.endDate = DateTime.Now.AddHours(2); + a = await Util.PostAsync(RouteName, await Util.GetTokenAsync("manager", "l3tm3in"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + SecondInOrderId = a.ObjectResponse["data"]["id"].Value(); + + d = new JObject(); + d.name = Util.Uniquify(NameStart); + d.startDate = DateTime.Now.AddHours(2); + d.endDate = DateTime.Now.AddHours(3); + a = await Util.PostAsync(RouteName, await Util.GetTokenAsync("manager", "l3tm3in"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + ThirdInOrderId = a.ObjectResponse["data"]["id"].Value(); + + + //CREATE FILTER + d = new JObject(); + d.name = Util.Uniquify(NameStart); + d["public"] = true; + d.listKey = "widget"; + + //FILTER IN BY NAME FOR TESTING THIS RUN ONLY + dynamic dfilter = new JArray(); + //name starts with filter to constrict to objects that this test block created only + dynamic DataFilterNameStart = new JObject(); + DataFilterNameStart.fld = "name"; + DataFilterNameStart.op = Util.OpStartsWith; + DataFilterNameStart.value = NameStart; + dfilter.Add(DataFilterNameStart); + d.filter = dfilter.ToString(); + + //SORT ORDER ################### + dynamic dsortarray = new JArray(); + dynamic dsort = new JObject(); + dsort.fld = "startdate"; + dsort.dir = "+"; + dsortarray.Add(dsort); + d.sort = dsortarray.ToString(); + + a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("manager", "l3tm3in"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + long DataFilterId = a.ObjectResponse["data"]["id"].Value(); + + //NOW FETCH LIST WITH FILTER + a = await Util.GetAsync($"{RouteName}/picklist?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert contains exactly 3 records + ((JArray)a.ObjectResponse["data"]).Count.Should().Be(3); + + //assert the order returned + a.ObjectResponse["data"][0]["id"].Value().Should().Be(FirstInOrderId); + a.ObjectResponse["data"][1]["id"].Value().Should().Be(SecondInOrderId); + a.ObjectResponse["data"][2]["id"].Value().Should().Be(ThirdInOrderId); + + + a = await Util.DeleteAsync($"{RouteName}/" + FirstInOrderId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync($"{RouteName}/" + SecondInOrderId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + a = await Util.DeleteAsync($"{RouteName}/" + ThirdInOrderId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + //DELETE DATAFILTER + a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateHTTPStatusCode(a, 204); + + } + + + /// + /// Paging test + /// + [Fact] + public async void PagingShouldWorkAsExpected() + { + //Get all + ApiResponse a = await Util.GetAsync("Widget/listwidgets?Offset=2&Limit=3", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + + //assert aAll contains at least two records + ((JArray)a.ObjectResponse["data"]).Count.Should().Be(3); + + JObject jp = (JObject)a.ObjectResponse["paging"]; + jp["count"].Value().Should().BeGreaterThan(5); + jp["offset"].Value().Should().Be(2); + jp["limit"].Value().Should().Be(3); + jp["first"].Value().Should().EndWith("&pageSize=3"); + jp["previous"].Value().Should().EndWith("&pageSize=3"); + jp["next"].Value().Should().EndWith("&pageSize=3"); + jp["last"].Value().Should().EndWith("&pageSize=3"); + } + + + + + /// + /// + /// + [Fact] + public async void FilterOptionsRouteShouldWorkAsExpected() + { + //Get options with manager (english user) + ApiResponse a = await Util.GetAsync("Widget/FilterOptions", await Util.GetTokenAsync("manager", "l3tm3in")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + a.ObjectResponse["data"]["key"].Value().Should().Be("widget"); + ((JArray)a.ObjectResponse["data"]["flds"]).Count.Should().Be(10); + + int DollarAmountFieldNumber = 4; + + a.ObjectResponse["data"]["flds"][DollarAmountFieldNumber]["lt"].Value().Should().Be("Price"); + + a = await Util.GetAsync("Widget/FilterOptions", await Util.GetTokenAsync("es", "es")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + a.ObjectResponse["data"]["flds"][DollarAmountFieldNumber]["lt"].Value().Should().Be("Importe"); + + a = await Util.GetAsync("Widget/FilterOptions", await Util.GetTokenAsync("fr", "fr")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + a.ObjectResponse["data"]["flds"][DollarAmountFieldNumber]["lt"].Value().Should().Be("Montant"); + + a = await Util.GetAsync("Widget/FilterOptions", await Util.GetTokenAsync("de", "de")); + Util.ValidateDataReturnResponseOk(a); + Util.ValidateHTTPStatusCode(a, 200); + a.ObjectResponse["data"]["flds"][DollarAmountFieldNumber]["lt"].Value().Should().Be("Betrag"); + + } + + + + + + + //================================================== + + }//eoc +}//eons diff --git a/Widget/WidgetRights.cs b/Widget/WidgetRights.cs new file mode 100644 index 0000000..52794c2 --- /dev/null +++ b/Widget/WidgetRights.cs @@ -0,0 +1,261 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace raven_integration +{ + // [Collection("APICOLLECTION")] + public class WidgetRights + { + + + /// + /// Test not authorized error return + /// + [Fact] + public async void ServerShouldNotAllowUnauthenticatedAccess() + { + ApiResponse a = await Util.GetAsync("Widget/list"); + Util.ValidateHTTPStatusCode(a, 401); + } + + /// + /// Test insufficient read rights error return + /// + [Fact] + public async void ServerShouldNotAllowReadUnauthorizedAccess() + { + ApiResponse a = await Util.GetAsync("Widget/listwidgets", await Util.GetTokenAsync( "OpsAdminFull")); + //2004 unauthorized + Util.ValidateErrorCodeResponse(a, 2004, 401); + } + + + + /// + /// Test insufficient create rights error return + /// + [Fact] + public async void ServerShouldNotAllowCreateUnauthorizedAccess() + { + //CREATE + dynamic d = new JObject(); + d.name = Util.Uniquify("ServerShouldNotAllowCreateUnauthorizedAccess TEST WIDGET"); + d.created = DateTime.Now.ToString(); + d.dollarAmount = 1.11m; + d.active = true; + d.roles = 0; + + //BizAdminLimited user should not be able to create a widget, only read them + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync( "BizAdminLimited"), d.ToString()); + + //2004 unauthorized + Util.ValidateErrorCodeResponse(a, 2004, 401); + } + + + + /// + /// Test owner rights to modify + /// + [Fact] + public async void ServerShouldAllowOwnerOnlyRightsUserToPatchOwn() + { + + // TECH FULL has owner only rights to widget + + //CREATE + dynamic d = new JObject(); + d.name = Util.Uniquify("ServerShouldAllowOwnerOnlyRightsUserToPatchOwn TEST WIDGET"); + d.created = DateTime.Now.ToString(); + d.dollarAmount = 1.11m; + d.active = true; + d.roles = 0; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync( "TechFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + long Id = a.ObjectResponse["data"]["id"].Value(); + uint OriginalConcurrencyToken = a.ObjectResponse["data"]["concurrencyToken"].Value(); + + //Now attempt to modify it via patch + var newName = Util.Uniquify("ServerShouldAllowOwnerOnlyRightsUserToPatchOwn - UPDATED TEST WIDGET"); + string patchJson = "[{\"value\": \"" + newName + "\",\"path\": \"/name\",\"op\": \"replace\"}]"; + a = await Util.PatchAsync("Widget/" + Id.ToString() + "/" + OriginalConcurrencyToken.ToString(), await Util.GetTokenAsync( "TechFull"), patchJson); + Util.ValidateHTTPStatusCode(a, 200); + } + + + /// + /// Test owner rights fails to modify other creator object + /// + [Fact] + public async void ServerShouldDisAllowOwnerOnlyRightsUserToPatchNonOwned() + { + // TECH FULL has owner only rights to widget + //INVENTORY FULL has full rights to widget + + //CREATE + dynamic d = new JObject(); + d.name = Util.Uniquify("ServerShouldDisAllowOwnerOnlyRightsUserToPatchNonOwned TEST WIDGET"); + d.created = DateTime.Now.ToString(); + d.dollarAmount = 1.11m; + d.active = true; + d.roles = 0; + + //create via inventory full test user + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync( "InventoryFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + long Id = a.ObjectResponse["data"]["id"].Value(); + uint OriginalConcurrencyToken = a.ObjectResponse["data"]["concurrencyToken"].Value(); + + //Now TechFullAuthToken attempt to modify it via patch + var newName = Util.Uniquify("ServerShouldDisAllowOwnerOnlyRightsUserToPatchNonOwned - UPDATED TEST WIDGETB"); + string patchJson = "[{\"value\": \"" + newName + "\",\"path\": \"/name\",\"op\": \"replace\"}]"; + a = await Util.PatchAsync("Widget/" + Id.ToString() + "/" + OriginalConcurrencyToken.ToString(), await Util.GetTokenAsync( "TechFull"), patchJson); + //2004 unauthorized expected + Util.ValidateErrorCodeResponse(a, 2004, 401); + + + } + + + + + + /// + /// Test owner rights to modify + /// + [Fact] + public async void ServerShouldAllowOwnerOnlyRightsUserToPutOwn() + { + + // TECH FULL has owner only rights to widget + + //CREATE + dynamic d = new JObject(); + d.name = Util.Uniquify("ServerShouldAllowOwnerOnlyRightsUserToPutOwn TEST WIDGET"); + d.created = DateTime.Now.ToString(); + d.dollarAmount = 1.11m; + d.active = true; + d.roles = 0; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync( "TechFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + long Id = a.ObjectResponse["data"]["id"].Value(); + uint OriginalConcurrencyToken = a.ObjectResponse["data"]["concurrencyToken"].Value(); + + //Now attempt to modify it via patch + var newName = Util.Uniquify("ServerShouldAllowOwnerOnlyRightsUserToPutOwn - UPDATED TEST WIDGET"); + d.OwnerId = 1; + d.name = newName; + d.concurrencyToken = OriginalConcurrencyToken; + + a = await Util.PutAsync("Widget/" + Id.ToString(), await Util.GetTokenAsync( "TechFull"), d.ToString()); + Util.ValidateHTTPStatusCode(a, 200); + } + + + /// + /// Test owner rights fails to modify other creator object + /// + [Fact] + public async void ServerShouldDisAllowOwnerOnlyRightsUserToPutNonOwned() + { + // TECH FULL has owner only rights to widget + //INVENTORY FULL has full rights to widget + + //CREATE + dynamic d = new JObject(); + d.name = Util.Uniquify("ServerShouldDisAllowOwnerOnlyRightsUserToPutNonOwned TEST WIDGET"); + d.created = DateTime.Now.ToString(); + d.dollarAmount = 1.11m; + d.active = true; + d.roles = 0; + + //create via inventory full test user + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync( "InventoryFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + long Id = a.ObjectResponse["data"]["id"].Value(); + + //Now TechFullAuthToken attempt to modify it via patch + var newName = Util.Uniquify("ServerShouldDisAllowOwnerOnlyRightsUserToPutNonOwned - UPDATED TEST WIDGET"); + d.name = newName; + a = await Util.PutAsync("Widget/" + Id.ToString(), await Util.GetTokenAsync( "TechFull"), d.ToString()); + //2004 unauthorized expected + Util.ValidateErrorCodeResponse(a, 2004, 401); + + + } + + + + /// + /// Test owner rights to delete + /// + [Fact] + public async void ServerShouldAllowOwnerOnlyRightsUserToDelete() + { + + // TECH FULL has owner only rights to widget + + //CREATE + dynamic d = new JObject(); + d.name = Util.Uniquify("ServerShouldAllowOwnerOnlyRightsUserToDelete TEST WIDGET"); + d.created = DateTime.Now.ToString(); + d.dollarAmount = 1.11m; + d.active = true; + d.roles = 0; + + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync( "TechFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + long Id = a.ObjectResponse["data"]["id"].Value(); + + //Now attempt to delete it + a = await Util.DeleteAsync("Widget/" + Id.ToString(), await Util.GetTokenAsync( "TechFull")); + Util.ValidateHTTPStatusCode(a, 204); + } + + + + + /// + /// Test owner rights fails to delete other creator object + /// + [Fact] + public async void ServerShouldDisAllowOwnerOnlyRightsUserToDeleteNonOwned() + { + // TECH FULL has owner only rights to widget + //INVENTORY FULL has full rights to widget + + //CREATE + dynamic d = new JObject(); + d.name = Util.Uniquify("ServerShouldDisAllowOwnerOnlyRightsUserToDeleteNonOwned TEST WIDGET"); + d.created = DateTime.Now.ToString(); + d.dollarAmount = 1.11m; + d.active = true; + d.roles = 0; + + //create via inventory full test user + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync( "InventoryFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + long Id = a.ObjectResponse["data"]["id"].Value(); + + //Now attempt delete + a = await Util.DeleteAsync("Widget/" + Id.ToString(), await Util.GetTokenAsync( "TechFull")); + //2004 unauthorized expected + Util.ValidateErrorCodeResponse(a, 2004, 401); + + + } + + + + + + //================================================== + + }//eoc +}//eons diff --git a/Widget/WidgetValidationTests.cs b/Widget/WidgetValidationTests.cs new file mode 100644 index 0000000..e3bd09b --- /dev/null +++ b/Widget/WidgetValidationTests.cs @@ -0,0 +1,232 @@ +using System; +using Xunit; +using Newtonsoft.Json.Linq; +using FluentAssertions; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace raven_integration +{ + public class WidgetValidationTest + { + + + // /// + // /// Test business rule should be active on new + // /// + // [Fact] + // public async void BusinessRuleNewShouldBeActiveShouldWork() + // { + // //CREATE attempt with broken rules + // dynamic d = new JObject(); + // d.name = Util.Uniquify("ServerShouldDisAllowOwnerOnlyRightsUserToDeleteNonOwned TEST WIDGET"); + // d.created = DateTime.Now.ToString(); + // d.dollarAmount = 1.11m; + // d.active = false;//<--- BROKEN RULE new widget must be active = true!! + // d.roles = 0; + + // //create via inventory full test user + // ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("InventoryFull"), d.ToString()); + + // Util.ValidateErrorCodeResponse(a, 2200, 400); + // Util.ShouldContainValidationError(a, "Active", "InvalidValue"); + + // } + + + + + /// + /// Test business rule name should be unique + /// + [Fact] + public async void BusinessRuleNameMustBeUnique() + { + //CREATE attempt with broken rules + dynamic d = new JObject(); + d.name = Util.Uniquify("BusinessRuleNameMustBeUnique TEST WIDGET"); + d.created = DateTime.Now.ToString(); + d.dollarAmount = 1.11m; + d.active = true; + d.roles = 0; + + //create via inventory full test user + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("InventoryFull"), d.ToString()); + Util.ValidateDataReturnResponseOk(a); + + //Now try to create again with same name + a = await Util.PostAsync("Widget", await Util.GetTokenAsync("InventoryFull"), d.ToString()); + + //2002 in-valid expected + Util.ValidateErrorCodeResponse(a, 2200, 400); + Util.ShouldContainValidationError(a, "Name", "NotUnique"); + + } + + + + /// + /// + /// + [Fact] + public async void BusinessRuleNameRequired() + { + + dynamic d = new JObject(); + d.name = ""; + d.created = DateTime.Now.ToString(); + d.dollarAmount = 1.11m; + d.active = true; + d.roles = 0; + + //create via inventory full test user + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("InventoryFull"), d.ToString()); + + + //2002 in-valid expected + Util.ValidateErrorCodeResponse(a, 2200, 400); + Util.ShouldContainValidationError(a, "Name", "RequiredPropertyEmpty"); + + } + + /// + /// + /// + [Fact] + public async void BusinessRuleNameLengthExceeded() + { + + dynamic d = new JObject(); + d.name = new string('A', 256); ; + d.created = DateTime.Now.ToString(); + d.dollarAmount = 1.11m; + d.active = true; + d.roles = 0; + + //create via inventory full test user + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("InventoryFull"), d.ToString()); + + + //2002 in-valid expected + Util.ValidateErrorCodeResponse(a, 2200, 400); + Util.ShouldContainValidationError(a, "Name", "LengthExceeded", "255 max"); + + } + + + + + /// + /// + /// + [Fact] + public async void BusinessRuleStartDateWithoutEndDateShouldError() + { + + dynamic d = new JObject(); + d.name = Util.Uniquify("BusinessRuleStartDateWithoutEndDateShouldError TEST"); + d.created = DateTime.Now.ToString(); + d.startDate = d.created; + //NO END DATE ERRROR + d.dollarAmount = 1.11m; + d.active = true; + d.roles = 0; + + //create via inventory full test user + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("InventoryFull"), d.ToString()); + + + //2002 in-valid expected + Util.ValidateErrorCodeResponse(a, 2200, 400); + Util.ShouldContainValidationError(a, "EndDate", "RequiredPropertyEmpty"); + + } + + + + /// + /// + /// + [Fact] + public async void BusinessRuleEndDateWithoutStartDateShouldError() + { + + dynamic d = new JObject(); + d.name = Util.Uniquify("BusinessRuleEndDateWithoutStartDateShouldError TEST"); + d.created = DateTime.Now.ToString(); + d.endDate = d.created; + //NO START DATE ERRROR + d.dollarAmount = 1.11m; + d.active = true; + d.roles = 0; + + //create via inventory full test user + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("InventoryFull"), d.ToString()); + + + //2002 in-valid expected + Util.ValidateErrorCodeResponse(a, 2200, 400); + Util.ShouldContainValidationError(a, "StartDate", "RequiredPropertyEmpty"); + + } + + + /// + /// + /// + [Fact] + public async void BusinessRuleEndDateBeforeStartDateShouldError() + { + + dynamic d = new JObject(); + d.name = Util.Uniquify("BusinessRuleEndDateBeforeStartDateShouldError TEST"); + d.created = DateTime.Now.ToString(); + d.startDate = DateTime.Now.ToString(); + d.endDate = DateTime.Now.AddHours(-1).ToString(); + //NO START DATE ERRROR + d.dollarAmount = 1.11m; + d.active = true; + d.roles = 0; + + //create via inventory full test user + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("InventoryFull"), d.ToString()); + + + //2002 in-valid expected + Util.ValidateErrorCodeResponse(a, 2200, 400); + Util.ShouldContainValidationError(a, "StartDate", "StartDateMustComeBeforeEndDate"); + + } + + + + /// + /// + /// + [Fact] + public async void BusinessRuleEnumInvalidShouldError() + { + + dynamic d = new JObject(); + d.name = Util.Uniquify("BusinessRuleEnumInvalidShouldError TEST"); + d.created = DateTime.Now.ToString(); + + //NO END DATE ERRROR + d.dollarAmount = 1.11m; + d.active = true; + d.roles = 99999;//<---BAD ROLE VALUE + + //create via inventory full test user + ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("InventoryFull"), d.ToString()); + + + //2002 in-valid expected + Util.ValidateErrorCodeResponse(a, 2200, 400); + Util.ShouldContainValidationError(a, "Roles", "InvalidValue"); + + } + + //================================================== + + }//eoc +}//eons diff --git a/burntest.bat b/burntest.bat new file mode 100644 index 0000000..be4b5ff --- /dev/null +++ b/burntest.bat @@ -0,0 +1,8 @@ +SET /a VAR=0 +:HOME +SET /a VAR=VAR+1 +rem 1000 runs in local debug mode server is about 6 hours at current test pace with huge data +IF %VAR%==500 goto :End +dotnet test +goto :HOME +:End \ No newline at end of file diff --git a/raven-integration.csproj b/raven-integration.csproj new file mode 100644 index 0000000..b9922dc --- /dev/null +++ b/raven-integration.csproj @@ -0,0 +1,17 @@ + + + + netcoreapp2.1 + false + true + + + + + + + + + + + diff --git a/testdata/ayanova.data.dump.xxx.zip b/testdata/ayanova.data.dump.xxx.zip new file mode 100644 index 0000000..cbf4168 Binary files /dev/null and b/testdata/ayanova.data.dump.xxx.zip differ diff --git a/testdata/test.png b/testdata/test.png new file mode 100644 index 0000000..c1cf6c3 Binary files /dev/null and b/testdata/test.png differ diff --git a/testdata/test.zip b/testdata/test.zip new file mode 100644 index 0000000..a1a3fc5 Binary files /dev/null and b/testdata/test.zip differ diff --git a/util.cs b/util.cs new file mode 100644 index 0000000..61ac682 --- /dev/null +++ b/util.cs @@ -0,0 +1,404 @@ +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 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) + { + 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); + } + + /// + /// 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); + } + + + + + }//eoc +}//eons